From: Kalyan Kondapally Date: Sun, 16 Jul 2017 18:15:30 +0000 (-0400) Subject: Add support for scaling layers. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=539ce319bba388d55569c02fa71c8baf6acfcae1;p=android-x86%2Fexternal-IA-Hardware-Composer.git Add support for scaling layers. External display might have a difference resolution compared to primary and when in clone mode we would need to scale layers to match the resolution. For now this results in gpu composition of all layers but in future we could use pipe scalar to scale the layers. Jira: IAHWC-80 Test: Linux test apps scale layers automatically when external display and primary display resolutions don't match. Signed-off-by: Kalyan Kondapally --- diff --git a/common/display/displayqueue.cpp b/common/display/displayqueue.cpp index b2944dd..c1900c5 100644 --- a/common/display/displayqueue.cpp +++ b/common/display/displayqueue.cpp @@ -237,7 +237,25 @@ bool DisplayQueue::QueueUpdate(std::vector& source_layers, overlay_layer.SetAlpha(layer->GetAlpha()); overlay_layer.SetBlending(layer->GetBlending()); overlay_layer.SetSourceCrop(layer->GetSourceCrop()); - overlay_layer.SetDisplayFrame(layer->GetDisplayFrame()); + if (scaling_tracker_.scaling_state_ == ScalingTracker::kNeedsScaling) { + HwcRect display_frame = layer->GetDisplayFrame(); + display_frame.left = + display_frame.left + + (display_frame.left * scaling_tracker_.scaling_width); + display_frame.top = display_frame.top + + (display_frame.top * scaling_tracker_.scaling_height); + display_frame.right = + display_frame.right + + (display_frame.right * scaling_tracker_.scaling_width); + display_frame.bottom = + display_frame.bottom + + (display_frame.bottom * scaling_tracker_.scaling_height); + + overlay_layer.SetDisplayFrame(display_frame); + } else { + overlay_layer.SetDisplayFrame(layer->GetDisplayFrame()); + } + overlay_layer.SetLayerIndex(layer_index); overlay_layer.SetZorder(index); overlay_layer.SetBuffer(buffer_handler_, layer->GetNativeHandle(), @@ -600,4 +618,22 @@ void DisplayQueue::DisplayConfigurationChanged() { state_ |= kConfigurationChanged; } +void DisplayQueue::UpdateScalingRatio(uint32_t primary_width, + uint32_t primary_height, + uint32_t display_width, + uint32_t display_height) { + scaling_tracker_.scaling_state_ = ScalingTracker::kNeeedsNoSclaing; + uint32_t primary_area = primary_width * primary_height; + uint32_t display_area = display_width * display_height; + if (primary_area != display_area) { + scaling_tracker_.scaling_state_ = ScalingTracker::kNeedsScaling; + scaling_tracker_.scaling_width = + float(display_width - primary_width) / float(primary_width); + scaling_tracker_.scaling_height = + float(display_height - primary_height) / float(primary_height); + } + + state_ |= kConfigurationChanged; +} + } // namespace hwcomposer diff --git a/common/display/displayqueue.h b/common/display/displayqueue.h index 0996512..03fdf3b 100644 --- a/common/display/displayqueue.h +++ b/common/display/displayqueue.h @@ -77,6 +77,9 @@ class DisplayQueue { void ForceRefresh(); + void UpdateScalingRatio(uint32_t primary_width, uint32_t primary_height, + uint32_t display_width, uint32_t display_height); + private: enum QueueState { kNeedsColorCorrection = 1 << 0, // Needs Color correction. @@ -86,7 +89,16 @@ class DisplayQueue { kIgnoreIdleRefresh = 1 << 6 // Ignore refresh request during idle callback. }; - void HandleExit(); + struct ScalingTracker { + enum ScalingState { + kNeeedsNoSclaing = 0, // Needs no scaling. + kNeedsScaling = 1, // Needs scaling. + }; + float scaling_height = 1.0; + float scaling_width = 1.0; + uint32_t scaling_state_ = ScalingTracker::kNeeedsNoSclaing; + }; + struct FrameStateTracker { enum FrameState { kPrepareComposition = 1 << 0, // Preparing for current frame composition. @@ -163,6 +175,7 @@ class DisplayQueue { struct FrameStateTracker& tracker_; }; + void HandleExit(); void GetCachedLayers(const std::vector& layers, DisplayPlaneStateList* composition, bool* render_layers, bool* can_ignore_commit); @@ -194,6 +207,7 @@ class DisplayQueue { DisplayPlaneStateList previous_plane_state_; NativeBufferHandler* buffer_handler_; FrameStateTracker idle_tracker_; + ScalingTracker scaling_tracker_; // shared_ptr since we need to use this outside of the thread lock (to // actually call the hook) and we don't want the memory freed until we're // done diff --git a/public/nativedisplay.h b/public/nativedisplay.h index bba85e4..dc44de9 100644 --- a/public/nativedisplay.h +++ b/public/nativedisplay.h @@ -211,8 +211,18 @@ class NativeDisplay { virtual bool IsConnected() const { return false; } -}; + /** + * Scales layers of display to match it's resolutions in case + * this display is in cloned mode and resolution doesn't match + * with Source Display. + */ + virtual void UpdateScalingRatio(uint32_t /*primary_width*/, + uint32_t /*primary_height*/, + uint32_t /*display_width*/, + uint32_t /*display_height*/) { + } +}; /** * This is provided for Convenience in case diff --git a/wsi/drm/drmdisplaymanager.cpp b/wsi/drm/drmdisplaymanager.cpp index 2d33066..1825803 100644 --- a/wsi/drm/drmdisplaymanager.cpp +++ b/wsi/drm/drmdisplaymanager.cpp @@ -285,6 +285,13 @@ bool DrmDisplayManager::UpdateDisplayState() { headless_.reset(new Headless(fd_, 0, 0)); } else if (headless_) { headless_.reset(nullptr); + } else { + uint32_t primary_width = connected_displays_.at(0)->Width(); + uint32_t primary_height = connected_displays_.at(0)->Height(); + for (auto display : connected_displays_) { + display->UpdateScalingRatio(primary_width, primary_height, + display->Width(), display->Height()); + } } if (callback_) { diff --git a/wsi/physicaldisplay.cpp b/wsi/physicaldisplay.cpp index 8c70852..cbbdeac 100644 --- a/wsi/physicaldisplay.cpp +++ b/wsi/physicaldisplay.cpp @@ -238,4 +238,16 @@ bool PhysicalDisplay::TestCommit( return false; } +void PhysicalDisplay::UpdateScalingRatio(uint32_t primary_width, + uint32_t primary_height, + uint32_t display_width, + uint32_t display_height) { + if ((primary_width == display_width) && (primary_height == display_height)) + return; + modeset_lock_.lock(); + display_queue_->UpdateScalingRatio(primary_width, primary_height, + display_width, display_height); + modeset_lock_.unlock(); +} + } // namespace hwcomposer diff --git a/wsi/physicaldisplay.h b/wsi/physicaldisplay.h index 5e5fb48..f009488 100644 --- a/wsi/physicaldisplay.h +++ b/wsi/physicaldisplay.h @@ -108,6 +108,10 @@ class PhysicalDisplay : public NativeDisplay, public DisplayPlaneHandler { std::unique_ptr &cursor_plane, std::vector> &overlay_planes) override; + void UpdateScalingRatio(uint32_t primary_width, uint32_t primary_height, + uint32_t display_width, + uint32_t display_height) override; + /** * API for setting color correction for display. */