Merge "hwc2: Teardown CWB in Create Virtual Display"
diff --git a/gralloc/gr_priv_handle.h b/gralloc/gr_priv_handle.h
index ace762e..0968c5c 100644
--- a/gralloc/gr_priv_handle.h
+++ b/gralloc/gr_priv_handle.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
* Not a Contribution
*
* Copyright (C) 2008 The Android Open Source Project
@@ -23,7 +23,9 @@
#include <log/log.h>
#include <hardware/gralloc.h>
#include <hardware/gralloc1.h>
+#ifdef __cplusplus
#include <cinttypes>
+#endif
#define GRALLOC1_FUNCTION_PERFORM 0x00001000
@@ -34,7 +36,12 @@
#define PRIV_HANDLE_CONST(exp) static_cast<const private_handle_t *>(exp)
#pragma pack(push, 4)
+#ifdef __cplusplus
struct private_handle_t : public native_handle_t {
+#else
+struct private_handle_t {
+ native_handle_t nativeHandle;
+#endif
enum {
PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
PRIV_FLAGS_USES_ION = 0x00000008,
@@ -85,7 +92,7 @@
uint64_t base;
uint64_t base_metadata;
uint64_t gpuaddr;
-
+#ifdef __cplusplus
static const int kNumFds = 2;
static const int kMagic = 'gmsm';
@@ -175,6 +182,7 @@
uint64_t GetUsage() const { return usage; }
uint64_t GetBackingstore() const { return id; }
+#endif
};
#pragma pack(pop)
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 569c4ea..e19eccc 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2014, 2016-2019 The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are
* retained for attribution purposes only.
@@ -84,6 +84,7 @@
SET_DSI_CLK = 42, // Set DSI Clk.
GET_DSI_CLK = 43, // Get DSI Clk.
GET_SUPPORTED_DSI_CLK = 44, // Get supported DSI Clk.
+ SET_COLOR_MODE_FROM_CLIENT = 45, // Overrides the QDCM mode using the given mode ID
COMMAND_LIST_END = 400,
};
diff --git a/sdm/include/private/resource_interface.h b/sdm/include/private/resource_interface.h
index 14f156b..fa4efb6 100644
--- a/sdm/include/private/resource_interface.h
+++ b/sdm/include/private/resource_interface.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015 - 2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
@@ -36,6 +36,7 @@
kCmdResetLUT,
kCmdGetDefaultClk,
kCmdDisableRotatorOneFrame,
+ kCmdSetDisplayState,
kCmdMax,
};
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index e07aae1..0f92d62 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
@@ -545,6 +545,9 @@
DisplayCompositionContext *display_comp_ctx =
reinterpret_cast<DisplayCompositionContext *>(display_ctx);
+ resource_intf_->Perform(ResourceInterface::kCmdSetDisplayState,
+ display_comp_ctx->display_resource_ctx, state);
+
switch (state) {
case kStateOff:
Purge(display_ctx);
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index f219726..97eb72b 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -1410,7 +1410,8 @@
uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size());
for (uint32_t i = 0; i < hw_layers_count; i++) {
- Layer *sdm_layer = layer_stack->layers.at(hw_layers_.info.index.at(i));
+ uint32_t sdm_layer_index = hw_layers_.info.index.at(i);
+ Layer *sdm_layer = layer_stack->layers.at(sdm_layer_index);
Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
hw_layer.input_buffer.planes[0].fd = sdm_layer->input_buffer.planes[0].fd;
@@ -1419,6 +1420,12 @@
hw_layer.input_buffer.size = sdm_layer->input_buffer.size;
hw_layer.input_buffer.acquire_fence_fd = sdm_layer->input_buffer.acquire_fence_fd;
hw_layer.input_buffer.handle_id = sdm_layer->input_buffer.handle_id;
+ // TODO(user): Other FBT layer attributes like surface damage, dataspace, secure camera and
+ // secure display flags are also updated during SetClientTarget() called between validate and
+ // commit. Need to revist this and update it accordingly for FBT layer.
+ if (hw_layers_.info.gpu_target_index == sdm_layer_index) {
+ hw_layer.input_buffer.flags.secure = sdm_layer->input_buffer.flags.secure;
+ }
}
return;
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index 21a7890..bf53c66 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
@@ -131,16 +131,16 @@
fb_config = display_attributes;
}
- // if display is already connected, unregister display from composition manager and register
- // the display with new configuration.
- if (display_comp_ctx_) {
- comp_manager_->UnregisterDisplay(display_comp_ctx_);
+ // if display is already connected, reconfigure the display with new configuration.
+ if (!display_comp_ctx_) {
+ error = comp_manager_->RegisterDisplay(display_id_, display_type_, display_attributes,
+ hw_panel_info, mixer_attributes, fb_config,
+ &display_comp_ctx_, &(default_qos_data_.clock_hz));
+ } else {
+ error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info,
+ mixer_attributes, fb_config,
+ &(default_qos_data_.clock_hz));
}
-
- error =
- comp_manager_->RegisterDisplay(display_id_, display_type_, display_attributes, hw_panel_info,
- mixer_attributes, fb_config, &display_comp_ctx_,
- &(default_qos_data_.clock_hz));
if (error != kErrorNone) {
return error;
}
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 7988405..51a47c8 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -1940,6 +1940,11 @@
AddSolidfillStage(sf, 0xFF);
SetSolidfillStages();
}
+
+ if (!secure_display_active_) {
+ DRMSecurityLevel crtc_security_level = DRMSecurityLevel::SECURE_NON_SECURE;
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SECURITY_LEVEL, token_.crtc_id, crtc_security_level);
+ }
}
DisplayError HWDeviceDRM::NullCommit(bool synchronous, bool retain_planes) {
diff --git a/sdm/libs/hwc2/hwc_debugger.cpp b/sdm/libs/hwc2/hwc_debugger.cpp
index 82f0e47..7f116d5 100644
--- a/sdm/libs/hwc2/hwc_debugger.cpp
+++ b/sdm/libs/hwc2/hwc_debugger.cpp
@@ -165,6 +165,20 @@
DebugHandler::SetLogMask(debug_handler_.log_mask_);
}
+void HWCDebugHandler::DebugQos(bool enable, int verbose_level) {
+ if (enable) {
+ debug_handler_.log_mask_[kTagQOSClient] = 1;
+ // TODO(user): add qos impl log mask when logging available
+ debug_handler_.verbose_level_ = verbose_level;
+ } else {
+ debug_handler_.log_mask_[kTagQOSClient] = 0;
+ // TODO(user): add qos impl log mask when logging available
+ debug_handler_.verbose_level_ = 0;
+ }
+
+ DebugHandler::SetLogMask(debug_handler_.log_mask_);
+}
+
void HWCDebugHandler::Error(const char *format, ...) {
va_list list;
va_start(list, format);
diff --git a/sdm/libs/hwc2/hwc_debugger.h b/sdm/libs/hwc2/hwc_debugger.h
index 7ebca8a..db8c2a6 100644
--- a/sdm/libs/hwc2/hwc_debugger.h
+++ b/sdm/libs/hwc2/hwc_debugger.h
@@ -57,6 +57,7 @@
static void DebugScalar(bool enable, int verbose_level);
static void DebugQdcm(bool enable, int verbose_level);
static void DebugClient(bool enable, int verbose_level);
+ static void DebugQos(bool enable, int verbose_level);
static void DebugDisplay(bool enable, int verbose_level);
static int GetIdleTimeoutMs();
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index f6051bd..cee0b8b 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -50,6 +50,8 @@
namespace sdm {
+uint32_t HWCDisplay::throttling_refresh_rate_ = 60;
+
bool NeedsToneMap(const LayerStack &layer_stack) {
for (Layer *layer : layer_stack.layers) {
if (layer->request.flags.tone_map) {
@@ -795,6 +797,9 @@
// Append client target to the layer stack
Layer *sdm_client_target = client_target_->GetSDMLayer();
sdm_client_target->flags.updating = IsLayerUpdating(client_target_);
+ // Derive client target dataspace based on the color mode - bug/115482728
+ int32_t client_target_dataspace = GetDataspaceFromColorMode(GetCurrentColorMode());
+ SetClientTargetDataSpace(client_target_dataspace);
layer_stack_.layers.push_back(sdm_client_target);
// fall back frame composition to GPU when client target is 10bit
@@ -819,7 +824,7 @@
HWC2::Error HWCDisplay::SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z) {
const auto map_layer = layer_map_.find(layer_id);
if (map_layer == layer_map_.end()) {
- DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
+ DLOGW("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
return HWC2::Error::BadLayer;
}
@@ -1145,14 +1150,13 @@
}
Layer *sdm_layer = client_target_->GetSDMLayer();
- sdm_layer->frame_rate = current_refresh_rate_;
+ sdm_layer->frame_rate = std::min(current_refresh_rate_, HWCDisplay::GetThrottlingRefreshRate());
client_target_->SetLayerSurfaceDamage(damage);
- if (client_target_->GetLayerDataspace() != dataspace) {
- client_target_->SetLayerDataspace(dataspace);
- Layer *sdm_layer = client_target_->GetSDMLayer();
- // Data space would be validated at GetClientTargetSupport, so just use here.
- sdm::GetSDMColorSpace(client_target_->GetLayerDataspace(),
- &sdm_layer->input_buffer.color_metadata);
+ int translated_dataspace = TranslateFromLegacyDataspace(dataspace);
+ if (client_target_->GetLayerDataspace() != translated_dataspace) {
+ DLOGW("New Dataspace = %d not matching Dataspace from color mode = %d",
+ translated_dataspace, client_target_->GetLayerDataspace());
+ return HWC2::Error::BadParameter;
}
client_target_->SetLayerBuffer(target, acquire_fence);
@@ -2294,8 +2298,20 @@
continue;
}
auto layer = hwc_layer->GetSDMLayer();
- layer->frame_rate = current_refresh_rate_;
+ layer->frame_rate = std::min(current_refresh_rate_, HWCDisplay::GetThrottlingRefreshRate());
}
}
+int32_t HWCDisplay::SetClientTargetDataSpace(int32_t dataspace) {
+ if (client_target_->GetLayerDataspace() != dataspace) {
+ client_target_->SetLayerDataspace(dataspace);
+ Layer *sdm_layer = client_target_->GetSDMLayer();
+ // Data space would be validated at GetClientTargetSupport, so just use here.
+ sdm::GetSDMColorSpace(client_target_->GetLayerDataspace(),
+ &sdm_layer->input_buffer.color_metadata);
+ }
+
+ return 0;
+}
+
} // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 3ee1551..ed0696a 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -34,7 +34,7 @@
#include <utility>
#include <vector>
#include <bitset>
-
+#include <algorithm>
#include "hwc_buffer_allocator.h"
#include "hwc_callbacks.h"
#include "hwc_layers.h"
@@ -191,6 +191,9 @@
}
// Display Configurations
+ static uint32_t GetThrottlingRefreshRate() { return HWCDisplay::throttling_refresh_rate_; }
+ static void SetThrottlingRefreshRate(uint32_t newRefreshRate)
+ { HWCDisplay::throttling_refresh_rate_ = newRefreshRate; }
virtual int SetActiveDisplayConfig(uint32_t config);
virtual int GetActiveDisplayConfig(uint32_t *config);
virtual int GetDisplayConfigCount(uint32_t *count);
@@ -203,6 +206,7 @@
return kErrorNotSupported;
}
+ uint32_t GetMaxRefreshRate() { return max_refresh_rate_; }
int SetPanelBrightness(int level);
int GetPanelBrightness(int *level);
int ToggleScreenUpdates(bool enable);
@@ -309,9 +313,9 @@
}
protected:
+ static uint32_t throttling_refresh_rate_;
// Maximum number of layers supported by display manager.
static const uint32_t kMaxLayerCount = 32;
-
HWCDisplay(CoreInterface *core_intf, BufferAllocator *buffer_allocator, HWCCallbacks *callbacks,
HWCDisplayEventHandler *event_handler, qService::QService *qservice, DisplayType type,
hwc2_display_t id, int32_t sdm_id, bool needs_blit, DisplayClass display_class);
@@ -337,6 +341,7 @@
bool IsLayerUpdating(HWCLayer *layer);
uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
virtual void GetUnderScanConfig() { }
+ int32_t SetClientTargetDataSpace(int32_t dataspace);
enum {
INPUT_LAYER_DUMP,
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 45cfb16..4caad2a 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -182,6 +182,10 @@
}
}
+ if (dataspace == HAL_DATASPACE_UNKNOWN) {
+ dataspace = HAL_DATASPACE_V0_SRGB;
+ }
+
return dataspace;
}
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 9eba741..9c33e7b 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -34,6 +34,7 @@
#include <QService.h>
#include <utils/utils.h>
#include <algorithm>
+#include <utility>
#include <bitset>
#include <iterator>
#include <memory>
@@ -76,7 +77,7 @@
int HWCSession::null_display_mode_ = 0;
// Map the known color modes to dataspace.
-static int32_t GetDataspace(ColorMode mode) {
+int32_t GetDataspaceFromColorMode(ColorMode mode) {
switch (mode) {
case ColorMode::SRGB:
case ColorMode::NATIVE:
@@ -182,7 +183,6 @@
}
StartServices();
-
HWCDebugHandler::Get()->GetProperty(ENABLE_NULL_DISPLAY_PROP, &null_display_mode_);
DisplayError error = kErrorNone;
@@ -945,7 +945,7 @@
}
hwc_session->UpdateVsyncSource();
-
+ hwc_session->UpdateThrottlingRate();
return HWC2_ERROR_NONE;
}
@@ -1551,6 +1551,14 @@
status = GetSupportedDsiClk(input_parcel, output_parcel);
break;
+ case qService::IQService::SET_COLOR_MODE_FROM_CLIENT:
+ if (!input_parcel) {
+ DLOGE("QService command = %d: input_parcel needed.", command);
+ break;
+ }
+ status = SetColorModeFromClient(input_parcel);
+ break;
+
default:
DLOGW("QService command = %d is not supported.", command);
break;
@@ -1823,6 +1831,27 @@
return 0;
}
+android::status_t HWCSession::SetColorModeFromClient(const android::Parcel *input_parcel) {
+ int display = input_parcel->readInt32();
+ auto mode = input_parcel->readInt32();
+ auto device = static_cast<hwc2_device_t *>(this);
+
+ int disp_idx = GetDisplayIndex(display);
+ if (disp_idx == -1) {
+ DLOGE("Invalid display = %d", display);
+ return -EINVAL;
+ }
+
+ auto err = CallDisplayFunction(device, static_cast<hwc2_display_t>(disp_idx),
+ &HWCDisplay::SetColorModeFromClientApi, mode);
+ if (err != HWC2_ERROR_NONE)
+ return -EINVAL;
+
+ Refresh(static_cast<hwc2_display_t>(disp_idx));
+
+ return 0;
+}
+
android::status_t HWCSession::RefreshScreen(const android::Parcel *input_parcel) {
int display = input_parcel->readInt32();
@@ -1855,6 +1884,7 @@
case qService::IQService::DEBUG_PIPE_LIFECYCLE:
HWCDebugHandler::DebugResources(enable, verbose_level);
+ HWCDebugHandler::DebugQos(enable, verbose_level);
break;
case qService::IQService::DEBUG_DRIVER_CONFIG:
@@ -1865,6 +1895,7 @@
HWCDebugHandler::DebugResources(enable, verbose_level);
HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
HWCDebugHandler::DebugRotator(enable, verbose_level);
+ HWCDebugHandler::DebugQos(enable, verbose_level);
break;
case qService::IQService::DEBUG_QDCM:
@@ -2840,7 +2871,7 @@
if (hwc_display) {
*format = HAL_PIXEL_FORMAT_RGB_888;
- *dataspace = GetDataspace(hwc_display->GetCurrentColorMode());
+ *dataspace = GetDataspaceFromColorMode(hwc_display->GetCurrentColorMode());
return HWC2_ERROR_NONE;
}
@@ -2947,6 +2978,28 @@
return HWC_DISPLAY_PRIMARY;
}
+void HWCSession::UpdateThrottlingRate() {
+ uint32_t new_min = 0;
+
+ for (int i=0; i < kNumDisplays; i++) {
+ auto &display = hwc_display_[i];
+ if (!display)
+ continue;
+ if (display->GetCurrentPowerMode() != HWC2::PowerMode::Off)
+ new_min = (new_min == 0) ? display->GetMaxRefreshRate() :
+ std::min(new_min, display->GetMaxRefreshRate());
+ }
+
+ SetNewThrottlingRate(new_min);
+}
+
+void HWCSession::SetNewThrottlingRate(const uint32_t new_rate) {
+ if (new_rate !=0 && throttling_refresh_rate_ != new_rate) {
+ HWCDisplay::SetThrottlingRefreshRate(new_rate);
+ throttling_refresh_rate_ = new_rate;
+ }
+}
+
android::status_t HWCSession::SetIdlePC(const android::Parcel *input_parcel) {
auto enable = input_parcel->readInt32();
auto synchronous = input_parcel->readInt32();
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 5dd803d..48aa5eb 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -43,6 +43,7 @@
#include <qd_utils.h>
#include <display_config.h>
#include <vector>
+#include <utility>
#include "hwc_callbacks.h"
#include "hwc_layers.h"
@@ -78,6 +79,8 @@
using ::android::hardware::Return;
using ::android::hardware::hidl_string;
+int32_t GetDataspaceFromColorMode(ColorMode mode);
+
// Create a singleton uevent listener thread valid for life of hardware composer process.
// This thread blocks on uevents poll inside uevent library implementation. This poll exits
// only when there is a valid uevent, it can not be interrupted otherwise. Tieing life cycle
@@ -241,7 +244,9 @@
static const int kExternalConnectionTimeoutMs = 500;
static const int kCommitDoneTimeoutMs = 100;
-
+ uint32_t throttling_refresh_rate_ = 60;
+ void UpdateThrottlingRate();
+ void SetNewThrottlingRate(uint32_t new_rate);
// hwc methods
static int Open(const hw_module_t *module, const char *name, hw_device_t **device);
static int Close(hw_device_t *device);
@@ -359,6 +364,7 @@
android::status_t SetColorModeWithRenderIntentOverride(const android::Parcel *input_parcel);
android::status_t SetColorModeById(const android::Parcel *input_parcel);
+ android::status_t SetColorModeFromClient(const android::Parcel *input_parcel);
android::status_t getComposerStatus();
android::status_t SetQSyncMode(const android::Parcel *input_parcel);
android::status_t SetIdlePC(const android::Parcel *input_parcel);