sdm: hwc2: Use mixer resolution
- Use SDM's mixer/FB interface to get the corresponding
resolution and use in HWC2
- Support API to change layer mixer resolution
Change-Id: I79b43e3d04d97fc7de1bc9df75dce2c955accafd
Crs-fixed: 1026007
diff --git a/sdm/libs/hwc2/hwc_color_manager.cpp b/sdm/libs/hwc2/hwc_color_manager.cpp
index 0be9724..89b4918 100644
--- a/sdm/libs/hwc2/hwc_color_manager.cpp
+++ b/sdm/libs/hwc2/hwc_color_manager.cpp
@@ -257,7 +257,7 @@
uint32_t primary_width = 0;
uint32_t primary_height = 0;
- hwc_display->GetPanelResolution(&primary_width, &primary_height);
+ hwc_display->GetMixerResolution(&primary_width, &primary_height);
uint8_t *buf = new uint8_t[size]();
// handle for solid fill layer with fd = -1.
private_handle_t *handle = new private_handle_t(-1, 0, private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index cabb18a..8237882 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -231,12 +231,6 @@
swap_interval_zero_ = true;
}
- framebuffer_config_ = new DisplayConfigVariableInfo();
- if (!framebuffer_config_) {
- DLOGV("Failed to allocate memory for custom framebuffer config.");
- core_intf_->DestroyDisplay(display_intf_);
- return -EINVAL;
- }
client_target_ = new HWCLayer(id_);
int blit_enabled = 0;
@@ -267,7 +261,6 @@
return -EINVAL;
}
- delete framebuffer_config_;
delete client_target_;
if (blit_engine_) {
@@ -368,7 +361,6 @@
// TODO(user): Move to a getter if this is needed at other places
hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top),
INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
- ScaleDisplayFrame(&scaled_display_frame);
ApplyScanAdjustment(&scaled_display_frame);
hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
ApplyDeInterlaceAdjustment(layer);
@@ -503,9 +495,11 @@
HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
int32_t dataspace) {
+ DisplayConfigVariableInfo variable_config;
+ display_intf_->GetFrameBufferConfig(&variable_config);
// TODO(user): Support scaled configurations, other formats and other dataspaces
if (format != HAL_PIXEL_FORMAT_RGBA_8888 || dataspace != HAL_DATASPACE_UNKNOWN ||
- width != framebuffer_config_->x_pixels || height != framebuffer_config_->y_pixels) {
+ width != variable_config.x_pixels || height != variable_config.y_pixels) {
return HWC2::Error::Unsupported;
} else {
return HWC2::Error::None;
@@ -535,7 +529,12 @@
HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
int32_t *out_value) {
- DisplayConfigVariableInfo variable_config = *framebuffer_config_;
+ DisplayConfigVariableInfo variable_config;
+ DisplayError error = display_intf_->GetFrameBufferConfig(&variable_config);
+ if (error != kErrorNone) {
+ DLOGV("Get variable config failed. Error = %d", error);
+ return HWC2::Error::BadDisplay;
+ }
switch (attribute) {
case HWC2::Attribute::VsyncPeriod:
@@ -630,6 +629,10 @@
return HWC2::Error::None;
}
+DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) {
+ return kErrorNotSupported;
+}
+
void HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
dump_frame_count_ = count;
dump_frame_index_ = 0;
@@ -1209,41 +1212,25 @@
return -EINVAL;
}
- if (framebuffer_config_->x_pixels == x_pixels && framebuffer_config_->y_pixels == y_pixels) {
- return 0;
- }
-
- DisplayConfigVariableInfo active_config;
- uint32_t active_config_index = 0;
- display_intf_->GetActiveConfig(&active_config_index);
- DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
+ DisplayConfigVariableInfo fb_config;
+ DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config);
if (error != kErrorNone) {
- DLOGV("GetConfig variable info failed. Error = %d", error);
+ DLOGV("Get frame buffer config failed. Error = %d", error);
return -EINVAL;
}
- if (active_config.x_pixels <= 0 || active_config.y_pixels <= 0) {
- DLOGV("Invalid panel resolution (%dx%d)", active_config.x_pixels, active_config.y_pixels);
+ fb_config.x_pixels = x_pixels;
+ fb_config.y_pixels = y_pixels;
+
+ error = display_intf_->SetFrameBufferConfig(fb_config);
+ if (error != kErrorNone) {
+ DLOGV("Set frame buffer config failed. Error = %d", error);
return -EINVAL;
}
// Create rects to represent the new source and destination crops
LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
- LayerRect dst = LayerRect(0, 0, FLOAT(active_config.x_pixels), FLOAT(active_config.y_pixels));
- // Set rotate90 to false since this is taken care of during regular composition.
- bool rotate90 = false;
- error = display_intf_->IsScalingValid(crop, dst, rotate90);
- if (error != kErrorNone) {
- DLOGV("Unsupported resolution: (%dx%d)", x_pixels, y_pixels);
- return -EINVAL;
- }
-
- framebuffer_config_->x_pixels = x_pixels;
- framebuffer_config_->y_pixels = y_pixels;
- framebuffer_config_->vsync_period_ns = active_config.vsync_period_ns;
- framebuffer_config_->x_dpi = active_config.x_dpi;
- framebuffer_config_->y_dpi = active_config.y_dpi;
-
+ LayerRect dst = LayerRect(0, 0, FLOAT(fb_config.x_pixels), FLOAT(fb_config.y_pixels));
auto client_target_layer = client_target_->GetSDMLayer();
client_target_layer->src_rect = crop;
client_target_layer->dst_rect = dst;
@@ -1269,68 +1256,32 @@
client_target_layer->input_buffer->height = UINT32(aligned_height);
client_target_layer->plane_alpha = 255;
- DLOGI("New framebuffer resolution (%dx%d)", framebuffer_config_->x_pixels,
- framebuffer_config_->y_pixels);
+ DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels);
return 0;
}
void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
- *x_pixels = framebuffer_config_->x_pixels;
- *y_pixels = framebuffer_config_->y_pixels;
+ DisplayConfigVariableInfo fb_config;
+ display_intf_->GetFrameBufferConfig(&fb_config);
+
+ *x_pixels = fb_config.x_pixels;
+ *y_pixels = fb_config.y_pixels;
}
-void HWCDisplay::ScaleDisplayFrame(hwc_rect_t *display_frame) {
- if (!IsFrameBufferScaled()) {
- return;
- }
-
- uint32_t active_config_index = 0;
- display_intf_->GetActiveConfig(&active_config_index);
- DisplayConfigVariableInfo active_config;
- DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
- if (error != kErrorNone) {
- DLOGE("GetConfig variable info failed. Error = %d", error);
- return;
- }
-
- float custom_x_pixels = FLOAT(framebuffer_config_->x_pixels);
- float custom_y_pixels = FLOAT(framebuffer_config_->y_pixels);
- float active_x_pixels = FLOAT(active_config.x_pixels);
- float active_y_pixels = FLOAT(active_config.y_pixels);
- float x_pixels_ratio = active_x_pixels / custom_x_pixels;
- float y_pixels_ratio = active_y_pixels / custom_y_pixels;
- float layer_width = FLOAT(display_frame->right - display_frame->left);
- float layer_height = FLOAT(display_frame->bottom - display_frame->top);
-
- display_frame->left = INT(x_pixels_ratio * FLOAT(display_frame->left));
- display_frame->top = INT(y_pixels_ratio * FLOAT(display_frame->top));
- display_frame->right = INT(FLOAT(display_frame->left) + layer_width * x_pixels_ratio);
- display_frame->bottom = INT(FLOAT(display_frame->top) + layer_height * y_pixels_ratio);
-}
-
-bool HWCDisplay::IsFrameBufferScaled() {
- if (framebuffer_config_->x_pixels == 0 || framebuffer_config_->y_pixels == 0) {
- return false;
- }
- uint32_t panel_x_pixels = 0;
- uint32_t panel_y_pixels = 0;
- GetPanelResolution(&panel_x_pixels, &panel_y_pixels);
- return (framebuffer_config_->x_pixels != panel_x_pixels) ||
- (framebuffer_config_->y_pixels != panel_y_pixels);
+DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
+ return display_intf_->GetMixerResolution(x_pixels, y_pixels);
}
void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
- DisplayConfigVariableInfo active_config;
- uint32_t active_config_index = 0;
- display_intf_->GetActiveConfig(&active_config_index);
- DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
- if (error != kErrorNone) {
- DLOGE("GetConfig variable info failed. Error = %d", error);
- return;
- }
- *x_pixels = active_config.x_pixels;
- *y_pixels = active_config.y_pixels;
+ DisplayConfigVariableInfo display_config;
+ uint32_t active_index = 0;
+
+ display_intf_->GetActiveConfig(&active_index);
+ display_intf_->GetConfig(active_index, &display_config);
+
+ *x_pixels = display_config.x_pixels;
+ *y_pixels = display_config.y_pixels;
}
int HWCDisplay::SetDisplayStatus(uint32_t display_status) {
@@ -1476,8 +1427,9 @@
return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1;
}
-int HWCDisplay::GetDisplayAttributesForConfig(int config, DisplayConfigVariableInfo *attributes) {
- return display_intf_->GetConfig(UINT32(config), attributes) == kErrorNone ? 0 : -1;
+int HWCDisplay::GetDisplayAttributesForConfig(int config,
+ DisplayConfigVariableInfo *display_attributes) {
+ return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1;
}
bool HWCDisplay::SingleLayerUpdating(void) {
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 9204024..a5ef7eb 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -98,11 +98,13 @@
virtual HWC2::PowerMode GetLastPowerMode();
virtual int SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels);
virtual void GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels);
- virtual void GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels);
virtual int SetDisplayStatus(uint32_t display_status);
virtual int OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
virtual int Perform(uint32_t operation, ...);
virtual void SetSecureDisplay(bool secure_display_active);
+ virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height);
+ virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
+ virtual void GetPanelResolution(uint32_t *width, uint32_t *height);
virtual std::string Dump(void);
// Captures frame output in the buffer specified by output_buffer_info. The API is
@@ -121,7 +123,8 @@
virtual int SetActiveDisplayConfig(int config);
virtual int GetActiveDisplayConfig(uint32_t *config);
virtual int GetDisplayConfigCount(uint32_t *count);
- virtual int GetDisplayAttributesForConfig(int config, DisplayConfigVariableInfo *attributes);
+ virtual int GetDisplayAttributesForConfig(int config,
+ DisplayConfigVariableInfo *display_attributes);
int SetPanelBrightness(int level);
int GetPanelBrightness(int *level);
@@ -201,7 +204,6 @@
LayerBufferFormat GetSDMFormat(const int32_t &source, const int flags);
const char *GetHALPixelFormatString(int format);
const char *GetDisplayString();
- void ScaleDisplayFrame(hwc_rect_t *display_frame);
void MarkLayersForGPUBypass(void);
void MarkLayersForClientComposition(void);
virtual void ApplyScanAdjustment(hwc_rect_t *display_frame);
@@ -235,7 +237,6 @@
bool dump_input_layers_ = false;
HWC2::PowerMode last_power_mode_;
bool swap_interval_zero_ = false;
- DisplayConfigVariableInfo *framebuffer_config_ = NULL;
bool display_paused_ = false;
uint32_t min_refresh_rate_ = 0;
uint32_t max_refresh_rate_ = 0;
@@ -256,7 +257,6 @@
HWCColorMode *color_mode_ = NULL;
private:
- bool IsFrameBufferScaled();
void DumpInputBuffers(void);
BlitEngine *blit_engine_ = NULL;
qService::QService *qservice_ = NULL;
diff --git a/sdm/libs/hwc2/hwc_display_external.cpp b/sdm/libs/hwc2/hwc_display_external.cpp
index 73ed0e8..caacb11 100644
--- a/sdm/libs/hwc2/hwc_display_external.cpp
+++ b/sdm/libs/hwc2/hwc_display_external.cpp
@@ -49,6 +49,7 @@
HWCDisplay **hwc_display) {
uint32_t external_width = 0;
uint32_t external_height = 0;
+ DisplayError error = kErrorNone;
HWCDisplay *hwc_display_external = new HWCDisplayExternal(core_intf, callbacks, qservice);
int status = hwc_display_external->Init();
@@ -57,7 +58,10 @@
return status;
}
- hwc_display_external->GetPanelResolution(&external_width, &external_height);
+ error = hwc_display_external->GetMixerResolution(&external_width, &external_height);
+ if (error != kErrorNone) {
+ return -EINVAL;
+ }
if (primary_width && primary_height) {
// use_primary_res means HWCDisplayExternal should directly set framebuffer resolution to the
@@ -144,29 +148,29 @@
return;
}
- uint32_t panel_width = 0;
- uint32_t panel_height = 0;
- GetPanelResolution(&panel_width, &panel_height);
+ uint32_t mixer_width = 0;
+ uint32_t mixer_height = 0;
+ GetMixerResolution(&mixer_width, &mixer_height);
- if (panel_width == 0 || panel_height == 0) {
- DLOGV("Invalid panel dimensions (%d, %d)", panel_width, panel_height);
+ if (mixer_width == 0 || mixer_height == 0) {
+ DLOGV("Invalid mixer dimensions (%d, %d)", mixer_width, mixer_height);
return;
}
- uint32_t new_panel_width = UINT32(panel_width * FLOAT(1.0f - width_ratio));
- uint32_t new_panel_height = UINT32(panel_height * FLOAT(1.0f - height_ratio));
+ uint32_t new_mixer_width = UINT32(mixer_width * FLOAT(1.0f - width_ratio));
+ uint32_t new_mixer_height = UINT32(mixer_height * FLOAT(1.0f - height_ratio));
- int x_offset = INT((FLOAT(panel_width) * width_ratio) / 2.0f);
- int y_offset = INT((FLOAT(panel_height) * height_ratio) / 2.0f);
+ int x_offset = INT((FLOAT(mixer_width) * width_ratio) / 2.0f);
+ int y_offset = INT((FLOAT(mixer_height) * height_ratio) / 2.0f);
- display_frame->left =
- (display_frame->left * INT32(new_panel_width) / INT32(panel_width)) + x_offset;
- display_frame->top =
- (display_frame->top * INT32(new_panel_height) / INT32(panel_height)) + y_offset;
- display_frame->right =
- ((display_frame->right * INT32(new_panel_width)) / INT32(panel_width)) + x_offset;
- display_frame->bottom =
- ((display_frame->bottom * INT32(new_panel_height)) / INT32(panel_height)) + y_offset;
+ display_frame->left = (display_frame->left * INT32(new_mixer_width) / INT32(mixer_width))
+ + x_offset;
+ display_frame->top = (display_frame->top * INT32(new_mixer_height) / INT32(mixer_height)) +
+ y_offset;
+ display_frame->right = ((display_frame->right * INT32(new_mixer_width)) / INT32(mixer_width)) +
+ x_offset;
+ display_frame->bottom = ((display_frame->bottom * INT32(new_mixer_height)) / INT32(mixer_height))
+ + y_offset;
}
void HWCDisplayExternal::SetSecureDisplay(bool secure_display_active) {
diff --git a/sdm/libs/hwc2/hwc_display_primary.cpp b/sdm/libs/hwc2/hwc_display_primary.cpp
index ea2e862..9e2fcce 100644
--- a/sdm/libs/hwc2/hwc_display_primary.cpp
+++ b/sdm/libs/hwc2/hwc_display_primary.cpp
@@ -60,7 +60,7 @@
return status;
}
- hwc_display_primary->GetPanelResolution(&primary_width, &primary_height);
+ hwc_display_primary->GetMixerResolution(&primary_width, &primary_height);
int width = 0, height = 0;
HWCDebugHandler::Get()->GetProperty("sdm.fb_size_width", &width);
HWCDebugHandler::Get()->GetProperty("sdm.fb_size_height", &height);
@@ -537,4 +537,12 @@
}
+DisplayError HWCDisplayPrimary::SetMixerResolution(uint32_t width, uint32_t height) {
+ return display_intf_->SetMixerResolution(width, height);
+}
+
+DisplayError HWCDisplayPrimary::GetMixerResolution(uint32_t *width, uint32_t *height) {
+ return display_intf_->GetMixerResolution(width, height);
+}
+
} // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display_primary.h b/sdm/libs/hwc2/hwc_display_primary.h
index e653d9c..41b0c9f 100644
--- a/sdm/libs/hwc2/hwc_display_primary.h
+++ b/sdm/libs/hwc2/hwc_display_primary.h
@@ -80,6 +80,8 @@
void HandleFrameOutput();
void HandleFrameCapture();
void HandleFrameDump();
+ DisplayError SetMixerResolution(uint32_t width, uint32_t height);
+ DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
BufferAllocator *buffer_allocator_ = nullptr;
CPUHint *cpu_hint_ = nullptr;
diff --git a/sdm/libs/hwc2/hwc_display_virtual.cpp b/sdm/libs/hwc2/hwc_display_virtual.cpp
index 3afe52b..e81781f 100644
--- a/sdm/libs/hwc2/hwc_display_virtual.cpp
+++ b/sdm/libs/hwc2/hwc_display_virtual.cpp
@@ -60,7 +60,7 @@
return status;
}
- hwc_display_virtual->GetPanelResolution(&virtual_width, &virtual_height);
+ hwc_display_virtual->GetMixerResolution(&virtual_width, &virtual_height);
status = hwc_display_virtual->SetFrameBufferResolution(width, height);
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index db4240d..7e87b10 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -832,6 +832,10 @@
status = GetBWTransactionStatus(input_parcel, output_parcel);
break;
+ case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
+ status = SetMixerResolution(input_parcel);
+ break;
+
default:
DLOGW("QService command = %d is not supported", command);
return -EINVAL;
@@ -998,25 +1002,26 @@
return error;
}
-android::status_t HWCSession::HandleGetDisplayAttributesForConfig(
- const android::Parcel *input_parcel, android::Parcel *output_parcel) {
+android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
+ *input_parcel,
+ android::Parcel *output_parcel) {
int config = input_parcel->readInt32();
int dpy = input_parcel->readInt32();
int error = android::BAD_VALUE;
- DisplayConfigVariableInfo attributes;
+ DisplayConfigVariableInfo display_attributes;
if (dpy > HWC_DISPLAY_VIRTUAL) {
return android::BAD_VALUE;
}
if (hwc_display_[dpy]) {
- error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &attributes);
+ error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
if (error == 0) {
- output_parcel->writeInt32(INT(attributes.vsync_period_ns));
- output_parcel->writeInt32(INT(attributes.x_pixels));
- output_parcel->writeInt32(INT(attributes.y_pixels));
- output_parcel->writeFloat(attributes.x_dpi);
- output_parcel->writeFloat(attributes.y_dpi);
+ output_parcel->writeInt32(INT(display_attributes.vsync_period_ns));
+ output_parcel->writeInt32(INT(display_attributes.x_pixels));
+ output_parcel->writeInt32(INT(display_attributes.y_pixels));
+ output_parcel->writeFloat(display_attributes.x_dpi);
+ output_parcel->writeFloat(display_attributes.y_dpi);
output_parcel->writeInt32(0); // Panel type, unsupported.
}
}
@@ -1169,6 +1174,31 @@
}
}
+android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
+ DisplayError error = kErrorNone;
+ uint32_t dpy = UINT32(input_parcel->readInt32());
+
+ if (dpy != HWC_DISPLAY_PRIMARY) {
+ DLOGI("Resoulution change not supported for this display %d", dpy);
+ return -EINVAL;
+ }
+
+ if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ DLOGI("Primary display is not initialized");
+ return -EINVAL;
+ }
+
+ uint32_t width = UINT32(input_parcel->readInt32());
+ uint32_t height = UINT32(input_parcel->readInt32());
+
+ error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMixerResolution(width, height);
+ if (error != kErrorNone) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
int type = input_parcel->readInt32();
bool enable = (input_parcel->readInt32() > 0);
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 23298bf..63cce84 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -164,6 +164,8 @@
android::Parcel *output_parcel);
android::status_t GetBWTransactionStatus(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
+ android::status_t SetMixerResolution(const android::Parcel *input_parcel);
+
static Locker locker_;
CoreInterface *core_intf_ = NULL;
HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {NULL};