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<int> 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(),
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
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.
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.
struct FrameStateTracker& tracker_;
};
+ void HandleExit();
void GetCachedLayers(const std::vector<OverlayLayer>& layers,
DisplayPlaneStateList* composition, bool* render_layers,
bool* can_ignore_commit);
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
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
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_) {
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
std::unique_ptr<DisplayPlane> &cursor_plane,
std::vector<std::unique_ptr<DisplayPlane>> &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.
*/