diff --git a/common/core/overlaylayer.cpp b/common/core/overlaylayer.cpp index 0946b73d..d5061b97 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) && !force_content_changed_) { + !(state_ & kNeedsReValidation)) { state_ &= ~kLayerContentChanged; } } diff --git a/common/core/overlaylayer.h b/common/core/overlaylayer.h index 22d4930b..6847ea68 100644 --- a/common/core/overlaylayer.h +++ b/common/core/overlaylayer.h @@ -123,17 +123,11 @@ struct OverlayLayer { } const HwcRect& GetSurfaceDamage() const { - if (force_content_changed_) - return display_frame_; - else - return surface_damage_; + return surface_damage_; } HwcRect& GetSurfaceDamage() { - if (force_content_changed_) - return display_frame_; - else - return surface_damage_; + return surface_damage_; } uint32_t GetSourceCropWidth() const { @@ -258,10 +252,6 @@ 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: @@ -316,7 +306,6 @@ 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/displayplanemanager.cpp b/common/display/displayplanemanager.cpp index 2d678e10..099bc5be 100644 --- a/common/display/displayplanemanager.cpp +++ b/common/display/displayplanemanager.cpp @@ -112,12 +112,28 @@ bool DisplayPlaneManager::ValidateLayers( OverlayPlane(temp.GetDisplayPlane(), temp.GetOverlayLayer())); } + size_t video_layers = 0; + for (size_t lindex = add_index; lindex < layers.size(); lindex++) { + if (layers[lindex].IsVideoLayer()) + video_layers++; + } + // In case we are forcing GPU composition for all layers and using a single // plane. if (disable_overlay) { - ISURFACETRACE("Forcing GPU For all layers %d %d %d %d \n", disable_overlay, - composition.empty(), add_index <= 0, layers.size()); - ForceGpuForAllLayers(commit_planes, composition, layers, mark_later, false); + if (!video_layers) { + ISURFACETRACE("Forcing GPU For all layers %d %d %d %d \n", + disable_overlay, composition.empty(), add_index <= 0, + layers.size()); + ForceGpuForAllLayers(commit_planes, composition, layers, mark_later, + false); + } else { + ISURFACETRACE("Forcing VPP For all layers %d %d %d %d \n", + disable_overlay, composition.empty(), add_index <= 0, + layers.size()); + ForceVppForAllLayers(commit_planes, composition, layers, add_index, + mark_later, false); + } *re_validation_needed = false; *commit_checked = true; @@ -134,11 +150,6 @@ bool DisplayPlaneManager::ValidateLayers( j->get()->SetInUse(false); } - size_t video_layers = 0; - for (size_t lindex = add_index; lindex < layers.size(); lindex++) { - if (layers[lindex].IsVideoLayer()) - video_layers++; - } size_t avail_planes = overlay_planes_.size() - composition.size(); if (!(overlay_planes_[overlay_planes_.size() - 1]->IsUniversal())) avail_planes--; @@ -393,7 +404,8 @@ bool DisplayPlaneManager::ValidateLayers( } if (validate_final_layers) { - ValidateFinalLayers(commit_planes, composition, layers, mark_later, false); + ValidateFinalLayers(commit_planes, composition, layers, mark_later, false, + add_index); test_commit_done = true; } @@ -734,11 +746,14 @@ void DisplayPlaneManager::SetDisplayTransform(uint32_t transform) { void DisplayPlaneManager::EnsureOffScreenTarget(DisplayPlaneState &plane) { NativeSurface *surface = NULL; // We only use media formats when video compostion for 1 layer + int dest_x = plane.GetDisplayFrame().left; + int dest_w = plane.GetDisplayFrame().right - dest_x; + bool video_separate = plane.IsVideoPlane() && (plane.GetSourceLayers().size() == 1); uint32_t preferred_format = 0; uint32_t usage = hwcomposer::kLayerNormal; - if (video_separate) { + if (video_separate && !(dest_w % 2 || dest_x % 2)) { preferred_format = plane.GetDisplayPlane()->GetPreferredVideoFormat(); } else { preferred_format = plane.GetDisplayPlane()->GetPreferredFormat(); @@ -773,6 +788,8 @@ void DisplayPlaneManager::EnsureOffScreenTarget(DisplayPlaneState &plane) { bool modifer_succeeded = false; new_surface->Init(resource_manager_, preferred_format, usage, modifier, &modifer_succeeded); + if (video_separate) + new_surface->GetLayer()->SetVideoLayer(true); if (modifer_succeeded) { plane.GetDisplayPlane()->PreferredFormatModifierValidated(); @@ -791,17 +808,25 @@ void DisplayPlaneManager::EnsureOffScreenTarget(DisplayPlaneState &plane) { void DisplayPlaneManager::ValidateFinalLayers( std::vector &commit_planes, DisplayPlaneStateList &composition, std::vector &layers, - std::vector &mark_later, bool recycle_resources) { + std::vector &mark_later, bool recycle_resources, + size_t add_index) { + bool has_video = false; for (DisplayPlaneState &plane : composition) { if (plane.NeedsOffScreenComposition() && !plane.GetOffScreenTarget()) { EnsureOffScreenTarget(plane); } + if (!has_video && plane.IsVideoPlane()) + has_video = true; } // If this combination fails just fall back to 3D for all layers. if (!plane_handler_->TestCommit(commit_planes)) { - ForceGpuForAllLayers(commit_planes, composition, layers, mark_later, - recycle_resources); + if (!has_video) + ForceGpuForAllLayers(commit_planes, composition, layers, mark_later, + recycle_resources); + else + ForceVppForAllLayers(commit_planes, composition, layers, add_index, + mark_later, false); } } diff --git a/common/display/displayplanemanager.h b/common/display/displayplanemanager.h index a20144b5..9878285e 100644 --- a/common/display/displayplanemanager.h +++ b/common/display/displayplanemanager.h @@ -133,7 +133,7 @@ class DisplayPlaneManager { DisplayPlaneStateList &list, std::vector &layers, std::vector &mark_later, - bool recycle_resources); + bool recycle_resources, size_t add_index); void ResetPlaneTarget(DisplayPlaneState &plane, OverlayPlane &overlay_plane); diff --git a/common/display/displayqueue.cpp b/common/display/displayqueue.cpp index 322763a4..9bcf475b 100644 --- a/common/display/displayqueue.cpp +++ b/common/display/displayqueue.cpp @@ -545,8 +545,6 @@ 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)); diff --git a/os/android/gralloc1bufferhandler.cpp b/os/android/gralloc1bufferhandler.cpp index 61eac39f..fd5ac3e7 100644 --- a/os/android/gralloc1bufferhandler.cpp +++ b/os/android/gralloc1bufferhandler.cpp @@ -149,16 +149,21 @@ bool Gralloc1BufferHandler::CreateBuffer(uint32_t w, uint32_t h, int format, set_format_(gralloc1_dvc, temp->gralloc1_buffer_descriptor_t_, pixel_format); #ifdef ENABLE_RBC - uint64_t modifier = 0; - if (set_modifier_) { - if (preferred_modifier != -1) { - modifier = preferred_modifier; + if (preferred_modifier != 0) { + uint64_t modifier = 0; + if (set_modifier_) { + if (preferred_modifier != -1) { + modifier = preferred_modifier; + } + set_modifier_(gralloc1_dvc, temp->gralloc1_buffer_descriptor_t_, + modifier); } - set_modifier_(gralloc1_dvc, temp->gralloc1_buffer_descriptor_t_, modifier); - } - if (modifier_used && modifier != DRM_FORMAT_MOD_NONE) { - *modifier_used = true; + if (modifier_used && modifier != DRM_FORMAT_MOD_NONE) { + *modifier_used = true; + } + } else { + *modifier_used = false; } #else if (modifier_used) { diff --git a/wsi/drm/drmdisplay.cpp b/wsi/drm/drmdisplay.cpp index 0ca10a80..c542d630 100644 --- a/wsi/drm/drmdisplay.cpp +++ b/wsi/drm/drmdisplay.cpp @@ -155,68 +155,6 @@ 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) { - drmModeFreePropertyBlob(blob); - 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); - } - } - - drmModeFreePropertyBlob(blob); - 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) { @@ -294,8 +232,6 @@ bool DrmDisplay::ConnectDisplay(const drmModeModeInfo &mode_info, ITRACE("DCIP3 support not available"); } - GetEDIDDisplayData(connector_props); - PhysicalDisplay::Connect(); SetHDCPState(desired_protection_support_, content_type_); @@ -409,6 +345,64 @@ bool DrmDisplay::GetDisplayAttribute(uint32_t config /*config*/, return status; } +uint32_t DrmDisplay::FindPreferedDisplayMode(size_t modes_size) { + uint32_t prefer_display_mode = 0; + if (modes_size > 1) { + SPIN_LOCK(display_lock_); + for (size_t i = 0; i < modes_size; i++) { + // There is only one preferred mode per connector. + if (modes_[i].type & DRM_MODE_TYPE_PREFERRED) { + prefer_display_mode = i; + IHOTPLUGEVENTTRACE("Preferred display config is found. index: %d", i); + break; + } + } + SPIN_UNLOCK(display_lock_); + } + if (prefer_display_mode_ != prefer_display_mode) + prefer_display_mode_ = prefer_display_mode; + return prefer_display_mode; +} + +uint32_t DrmDisplay::FindPerformaceDisplayMode(size_t modes_size) { + uint32_t perf_display_mode; + perf_display_mode = prefer_display_mode_; + if (modes_size >= prefer_display_mode_) { + int32_t prefer_width = 0, prefer_height = 0, prefer_interval = 0; + int32_t perf_width = 0, perf_height = 0, perf_interval = 0, + previous_perf_interval = 0; + GetDisplayAttribute(prefer_display_mode_, HWCDisplayAttribute::kWidth, + &prefer_width); + GetDisplayAttribute(prefer_display_mode_, HWCDisplayAttribute::kHeight, + &prefer_height); + GetDisplayAttribute(prefer_display_mode_, HWCDisplayAttribute::kRefreshRate, + &prefer_interval); + previous_perf_interval = prefer_interval; + IHOTPLUGEVENTTRACE("Preferred width:%d, height:%d, interval:%d", + prefer_width, prefer_height, prefer_interval); + for (size_t i = 0; i < modes_size; i++) { + if (i != prefer_display_mode_) { + GetDisplayAttribute(i, HWCDisplayAttribute::kWidth, &perf_width); + GetDisplayAttribute(i, HWCDisplayAttribute::kHeight, &perf_height); + GetDisplayAttribute(i, HWCDisplayAttribute::kRefreshRate, + &perf_interval); + IHOTPLUGEVENTTRACE("EDIP item width:%d, height:%d, rate:%d", perf_width, + perf_height, perf_interval); + if (prefer_width == perf_width && prefer_height == perf_height && + prefer_interval > perf_interval && + previous_perf_interval > perf_interval) { + perf_display_mode = i; + previous_perf_interval = perf_interval; + } + } + } + } + if (perf_display_mode_ != perf_display_mode) + perf_display_mode_ = perf_display_mode; + IHOTPLUGEVENTTRACE("PerformaceDisplayMode: %d", perf_display_mode_); + return perf_display_mode; +} + bool DrmDisplay::GetDisplayConfigs(uint32_t *num_configs, uint32_t *configs) { if (!num_configs) return false; @@ -421,8 +415,16 @@ bool DrmDisplay::GetDisplayConfigs(uint32_t *num_configs, uint32_t *configs) { return PhysicalDisplay::GetDisplayConfigs(num_configs, configs); } + uint32_t prefer_display_mode = prefer_display_mode_; + uint32_t perf_display_mode = perf_display_mode_; + if (!configs) { - *num_configs = modes_size; + prefer_display_mode = FindPreferedDisplayMode(modes_size); + perf_display_mode = FindPerformaceDisplayMode(modes_size); + if (prefer_display_mode == perf_display_mode) + *num_configs = 1; + else + *num_configs = 2; IHOTPLUGEVENTTRACE( "GetDisplayConfigs: Total Configs: %d pipe: %d display: %p", *num_configs, pipe_, this); @@ -433,9 +435,9 @@ bool DrmDisplay::GetDisplayConfigs(uint32_t *num_configs, uint32_t *configs) { "GetDisplayConfigs: Populating Configs: %d pipe: %d display: %p", *num_configs, pipe_, this); - uint32_t size = *num_configs > modes_size ? modes_size : *num_configs; - for (uint32_t i = 0; i < size; i++) - configs[i] = i; + configs[0] = prefer_display_mode; + if (prefer_display_mode != perf_display_mode) + configs[1] = perf_display_mode; return true; } @@ -707,6 +709,7 @@ 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 eec53043..9e6061ab 100644 --- a/wsi/drm/drmdisplay.h +++ b/wsi/drm/drmdisplay.h @@ -133,8 +133,6 @@ class DrmDisplay : public PhysicalDisplay { first_commit_ = true; } - bool CheckLimitedMonitor(); - private: void ShutDownPipe(); void GetDrmObjectPropertyValue(const char *name, @@ -167,10 +165,12 @@ 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(); + uint32_t FindPreferedDisplayMode(size_t modes_size); + uint32_t FindPerformaceDisplayMode(size_t modes_size); + uint32_t crtc_id_ = 0; uint32_t mmWidth_ = 0; uint32_t mmHeight_ = 0; @@ -198,6 +198,8 @@ class DrmDisplay : public PhysicalDisplay { uint32_t flags_ = DRM_MODE_ATOMIC_ALLOW_MODESET; bool planes_updated_ = false; bool first_commit_ = false; + uint32_t prefer_display_mode_ = 0; + uint32_t perf_display_mode_ = 0; std::string display_name_ = ""; HWCContentProtection current_protection_support_ = HWCContentProtection::kUnSupported; diff --git a/wsi/drm/drmdisplaymanager.cpp b/wsi/drm/drmdisplaymanager.cpp index adef66ef..da6fe4c7 100644 --- a/wsi/drm/drmdisplaymanager.cpp +++ b/wsi/drm/drmdisplaymanager.cpp @@ -306,14 +306,7 @@ bool DrmDisplayManager::UpdateDisplayState() { encoder->crtc_id, display->CrtcId(), display->GetDisplayPipe()); // Set the modes supported for each display - 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); - } + display->SetDrmModeInfo(mode); break; } } @@ -361,14 +354,7 @@ bool DrmDisplayManager::UpdateDisplayState() { IHOTPLUGEVENTTRACE("Connected with crtc: %d pipe:%d \n", display->CrtcId(), display->GetDisplayPipe()); // Set the modes supported for each display - 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); - } + display->SetDrmModeInfo(mode); break; } } diff --git a/wsi/physicaldisplay.cpp b/wsi/physicaldisplay.cpp index 7fad3e80..679d7caa 100644 --- a/wsi/physicaldisplay.cpp +++ b/wsi/physicaldisplay.cpp @@ -152,6 +152,10 @@ void PhysicalDisplay::Connect() { SPIN_LOCK(modeset_lock_); if (connection_state_ & kConnected) { + IHOTPLUGEVENTTRACE( + "PhysicalDisplay::Connect connected already, return with power mode " + "update."); + UpdatePowerMode(); SPIN_UNLOCK(modeset_lock_); return; } diff --git a/wsi/physicaldisplay.h b/wsi/physicaldisplay.h index 4fd91f7e..471f13ca 100644 --- a/wsi/physicaldisplay.h +++ b/wsi/physicaldisplay.h @@ -306,15 +306,5 @@ 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_