diff options
34 files changed, 411 insertions, 0 deletions
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index f41e4b4..b710cf5 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn @@ -98,6 +98,7 @@ component("ash") { "//ui/display/util", "//chromeos", "//chromeos:power_manager_proto", + "//third_party/qcms", "//ui/chromeos/resources", "//ui/chromeos/strings", "//ui/chromeos:ui_chromeos", diff --git a/ash/ash.gyp b/ash/ash.gyp index 972152c..1044e24 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -43,6 +43,8 @@ 'autoclick/autoclick_controller.h', 'cancel_mode.cc', 'cancel_mode.h', + 'content/display/display_color_manager_chromeos.cc', + 'content/display/display_color_manager_chromeos.h', 'content/display/screen_orientation_controller_chromeos.cc', 'content/display/screen_orientation_controller_chromeos.h', 'debug.cc', @@ -967,6 +969,7 @@ # Ash #includes power_supply_properties.pb.h directly. '../chromeos/chromeos.gyp:power_manager_proto', '../device/bluetooth/bluetooth.gyp:device_bluetooth', + '../third_party/qcms/qcms.gyp:qcms', '../ui/chromeos/ui_chromeos.gyp:ui_chromeos_resources', '../ui/chromeos/ui_chromeos.gyp:ui_chromeos_strings', '../ui/chromeos/ui_chromeos.gyp:ui_chromeos', diff --git a/ash/content/display/DEPS b/ash/content/display/DEPS index 42cea3c..07d93bc 100644 --- a/ash/content/display/DEPS +++ b/ash/content/display/DEPS @@ -2,7 +2,9 @@ include_rules = [ "+content/public/browser/screen_orientation_delegate.h", "+content/public/browser/screen_orientation_provider.h", "+content/public/browser/browser_context.h", + "+content/public/browser/browser_thread.h", "+content/public/browser/web_contents.h", + "+third_party/qcms/src/qcms.h", "+third_party/WebKit/public/platform/WebScreenOrientationLockType.h", ] diff --git a/ash/content/display/display_color_manager_chromeos.cc b/ash/content/display/display_color_manager_chromeos.cc new file mode 100644 index 0000000..0d7252f --- /dev/null +++ b/ash/content/display/display_color_manager_chromeos.cc @@ -0,0 +1,139 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/content/display/display_color_manager_chromeos.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/logging.h" +#include "chromeos/chromeos_switches.h" +#include "content/public/browser/browser_thread.h" +#include "third_party/qcms/src/qcms.h" +#include "ui/display/types/display_snapshot.h" +#include "ui/display/types/gamma_ramp_rgb_entry.h" +#include "ui/display/types/native_display_delegate.h" +#include "ui/gfx/display.h" +#include "ui/gfx/screen.h" + +using content::BrowserThread; + +namespace ash { + +namespace { + +bool ParseFile(const base::FilePath& path, + DisplayColorManager::ColorCalibrationData* data) { + qcms_profile* display_profile = qcms_profile_from_path(path.value().c_str()); + + if (!display_profile) { + LOG(WARNING) << "Unable to load ICC file: " << path.value(); + return false; + } + + size_t vcgt_channel_length = + qcms_profile_get_vcgt_channel_length(display_profile); + if (!vcgt_channel_length) { + LOG(WARNING) << "No vcgt table in ICC file: " << path.value(); + return false; + } + + std::vector<uint16_t> vcgt_data; + vcgt_data.resize(vcgt_channel_length * 3); + if (!qcms_profile_get_vcgt_rgb_channels(display_profile, &vcgt_data[0])) { + LOG(WARNING) << "Unable to get vcgt data"; + qcms_profile_release(display_profile); + return false; + } + + data->lut.resize(vcgt_channel_length); + for (size_t i = 0; i < vcgt_channel_length; ++i) { + data->lut[i].r = vcgt_data[i]; + data->lut[i].g = vcgt_data[vcgt_channel_length + i]; + data->lut[i].b = vcgt_data[(vcgt_channel_length * 2) + i]; + } + qcms_profile_release(display_profile); + return true; +} + +} // namespace + +DisplayColorManager::DisplayColorManager(ui::DisplayConfigurator* configurator) + : configurator_(configurator) { + configurator_->AddObserver(this); + LoadInternalFromCommandLine(); +} + +DisplayColorManager::~DisplayColorManager() { + configurator_->RemoveObserver(this); + + for (auto it : calibration_map_) { + delete it.second; + calibration_map_.erase(it.first); + } +} + +void DisplayColorManager::OnDisplayModeChanged( + const ui::DisplayConfigurator::DisplayStateList& display_states) { + for (const ui::DisplaySnapshot* state : display_states) + ApplyDisplayColorCalibration(state->display_id()); +} + +void DisplayColorManager::ApplyDisplayColorCalibration(uint64_t display_id) { + if (calibration_map_.find(display_id) != calibration_map_.end()) { + ColorCalibrationData* ramp = calibration_map_[display_id]; + if (!configurator_->SetGammaRamp(display_id, ramp->lut)) + LOG(WARNING) << "Error applying gamma ramp"; + } +} + +void DisplayColorManager::LoadInternalFromCommandLine() { + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch( + chromeos::switches::kInternalDisplayColorProfileFile)) { + const base::FilePath& path = command_line->GetSwitchValuePath( + chromeos::switches::kInternalDisplayColorProfileFile); + VLOG(1) << "Loading ICC file : " << path.value() + << "for internal display id: " << gfx::Display::InternalDisplayId(); + LoadCalibrationForDisplay(gfx::Display::InternalDisplayId(), path); + } +} + +void DisplayColorManager::LoadCalibrationForDisplay( + int64_t display_id, + const base::FilePath& path) { + if (display_id == gfx::Display::kInvalidDisplayID) { + LOG(WARNING) << "Trying to load calibration data for invalid display id"; + return; + } + + scoped_ptr<ColorCalibrationData> data(new ColorCalibrationData()); + base::Callback<bool(void)> request( + base::Bind(&ParseFile, path, base::Unretained(data.get()))); + base::PostTaskAndReplyWithResult( + BrowserThread::GetBlockingPool(), FROM_HERE, request, + base::Bind(&DisplayColorManager::UpdateCalibrationData, AsWeakPtr(), + display_id, base::Passed(data.Pass()))); +} + +void DisplayColorManager::UpdateCalibrationData( + uint64_t display_id, + scoped_ptr<ColorCalibrationData> data, + bool success) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (success) { + // The map takes over ownership of the underlying memory. + calibration_map_[display_id] = data.release(); + } +} + +DisplayColorManager::ColorCalibrationData::ColorCalibrationData() { +} + +DisplayColorManager::ColorCalibrationData::~ColorCalibrationData() { +} + +} // namespace ash diff --git a/ash/content/display/display_color_manager_chromeos.h b/ash/content/display/display_color_manager_chromeos.h new file mode 100644 index 0000000..7f21c32 --- /dev/null +++ b/ash/content/display/display_color_manager_chromeos.h @@ -0,0 +1,66 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_DISPLAY_DISPLAY_COLOR_MANAGER_CHROMEOS_H_ +#define ASH_DISPLAY_DISPLAY_COLOR_MANAGER_CHROMEOS_H_ + +#include <map> +#include <vector> + +#include "ash/ash_export.h" +#include "base/basictypes.h" +#include "base/files/file_path.h" +#include "base/memory/weak_ptr.h" +#include "ui/display/chromeos/display_configurator.h" +#include "ui/gfx/display.h" +#include "ui/gfx/display_observer.h" + +namespace ui { +struct GammaRampRGBEntry; +} // namespace ui + +namespace ash { + +// An object that observes changes in display configuration applies any color +// calibration where needed. +class ASH_EXPORT DisplayColorManager + : public ui::DisplayConfigurator::Observer, + public base::SupportsWeakPtr<DisplayColorManager> { + public: + explicit DisplayColorManager(ui::DisplayConfigurator* configurator); + ~DisplayColorManager() override; + + // ui::DisplayConfigurator::Observer + void OnDisplayModeChanged( + const ui::DisplayConfigurator::DisplayStateList& outputs) override; + void OnDisplayModeChangeFailed( + const ui::DisplayConfigurator::DisplayStateList& displays, + ui::MultipleDisplayState failed_new_state) override {} + + struct ColorCalibrationData { + ColorCalibrationData(); + ~ColorCalibrationData(); + + std::vector<ui::GammaRampRGBEntry> lut; + }; + + private: + void ApplyDisplayColorCalibration(uint64_t display_id); + void LoadInternalFromCommandLine(); + void LoadCalibrationForDisplay(int64_t display_id, + const base::FilePath& path); + void UpdateCalibrationData( + uint64_t display_id, + scoped_ptr<DisplayColorManager::ColorCalibrationData> data, + bool success); + + ui::DisplayConfigurator* configurator_; + std::map<uint64_t, ColorCalibrationData*> calibration_map_; + + DISALLOW_COPY_AND_ASSIGN(DisplayColorManager); +}; + +} // namespace ash + +#endif // ASH_DISPLAY_DISPLAY_COLOR_MANAGER_CHROMEOS_H_ diff --git a/ash/shell.cc b/ash/shell.cc index e572d8d..a6f455b 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -121,6 +121,7 @@ #include "ash/accelerators/magnifier_key_scroller.h" #include "ash/accelerators/spoken_feedback_toggler.h" #include "ash/ash_constants.h" +#include "ash/content/display/display_color_manager_chromeos.h" #include "ash/content/display/screen_orientation_controller_chromeos.h" #include "ash/display/display_change_observer_chromeos.h" #include "ash/display/display_configurator_animation.h" @@ -811,6 +812,7 @@ Shell::~Shell() { keyboard::KeyboardController::ResetInstance(NULL); #if defined(OS_CHROMEOS) + display_color_manager_.reset(); if (display_change_observer_) display_configurator_->RemoveObserver(display_change_observer_.get()); if (display_configurator_animation_) @@ -863,6 +865,8 @@ void Shell::Init(const ShellInitParams& init_params) { delegate_->IsFirstRunAfterBoot() ? kChromeOsBootColor : 0); display_initialized = true; } + display_color_manager_.reset( + new DisplayColorManager(display_configurator_.get())); #endif // defined(OS_CHROMEOS) if (!display_initialized) display_manager_->InitDefaultDisplay(); diff --git a/ash/shell.h b/ash/shell.h index 14b7fd4..cb46540 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -83,6 +83,7 @@ class BluetoothNotificationController; class CaptureController; class DesktopBackgroundController; class DisplayChangeObserver; +class DisplayColorManager; class DisplayConfiguratorAnimation; class DisplayController; class DisplayErrorObserver; @@ -725,6 +726,7 @@ class ASH_EXPORT Shell : public SystemModalContainerEventFilterDelegate, scoped_ptr<VirtualKeyboardController> virtual_keyboard_controller_; // Controls video output device state. scoped_ptr<ui::DisplayConfigurator> display_configurator_; + scoped_ptr<DisplayColorManager> display_color_manager_; scoped_ptr<DisplayConfiguratorAnimation> display_configurator_animation_; scoped_ptr<DisplayErrorObserver> display_error_observer_; scoped_ptr<ProjectingObserver> projecting_observer_; diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index b3c074e9..586f7d9 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc @@ -210,6 +210,10 @@ const char kHostPairingOobe[] = "host-pairing-oobe"; const char kIgnoreUserProfileMappingForTests[] = "ignore-user-profile-mapping-for-tests"; +// File to load internal display ICC file from. +const char kInternalDisplayColorProfileFile[] = + "internal-display-color-profile-file"; + // Enables Chrome-as-a-login-manager behavior. const char kLoginManager[] = "login-manager"; diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index eeafc2b..cf0f66e 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h @@ -84,6 +84,7 @@ CHROMEOS_EXPORT extern const char kHasChromeOSKeyboard[]; CHROMEOS_EXPORT extern const char kHomedir[]; CHROMEOS_EXPORT extern const char kHostPairingOobe[]; CHROMEOS_EXPORT extern const char kIgnoreUserProfileMappingForTests[]; +CHROMEOS_EXPORT extern const char kInternalDisplayColorProfileFile[]; CHROMEOS_EXPORT extern const char kLoginManager[]; CHROMEOS_EXPORT extern const char kLoginProfile[]; CHROMEOS_EXPORT extern const char kLoginUser[]; diff --git a/ui/display/chromeos/display_configurator.cc b/ui/display/chromeos/display_configurator.cc index c577fd0..0c72954 100644 --- a/ui/display/chromeos/display_configurator.cc +++ b/ui/display/chromeos/display_configurator.cc @@ -754,6 +754,17 @@ bool DisplayConfigurator::SetColorCalibrationProfile( return false; } +bool DisplayConfigurator::SetGammaRamp( + int64_t display_id, + const std::vector<GammaRampRGBEntry>& lut) { + for (const DisplaySnapshot* display : cached_displays_) { + if (display->display_id() == display_id) + return native_display_delegate_->SetGammaRamp(*display, lut); + } + + return false; +} + void DisplayConfigurator::PrepareForExit() { configure_display_ = false; } diff --git a/ui/display/chromeos/display_configurator.h b/ui/display/chromeos/display_configurator.h index 3dc87f4..96f93ec 100644 --- a/ui/display/chromeos/display_configurator.h +++ b/ui/display/chromeos/display_configurator.h @@ -30,6 +30,8 @@ class Size; } namespace ui { +struct DisplayConfigureRequest; +struct GammaRampRGBEntry; class DisplayLayoutManager; class DisplayMode; class DisplaySnapshot; @@ -260,6 +262,10 @@ class DISPLAY_EXPORT DisplayConfigurator : public NativeDisplayObserver { bool SetColorCalibrationProfile(int64_t display_id, ui::ColorCalibrationProfile new_profile); + // Sets the gamma ramp for |display_id| to the values in |lut|. + bool SetGammaRamp(int64_t display_id, + const std::vector<GammaRampRGBEntry>& lut); + private: class DisplayLayoutManagerImpl; diff --git a/ui/display/chromeos/test/action_logger_util.cc b/ui/display/chromeos/test/action_logger_util.cc index c798b48..bbdad78 100644 --- a/ui/display/chromeos/test/action_logger_util.cc +++ b/ui/display/chromeos/test/action_logger_util.cc @@ -5,9 +5,12 @@ #include "ui/display/chromeos/test/action_logger_util.h" #include "base/format_macros.h" +#include "base/logging.h" #include "base/strings/stringprintf.h" #include "ui/display/types/display_mode.h" #include "ui/display/types/display_snapshot.h" +#include "ui/display/types/gamma_ramp_rgb_entry.h" +#include "ui/display/types/native_display_delegate.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/size.h" @@ -52,6 +55,18 @@ std::string GetSetHDCPStateAction(const DisplaySnapshot& output, output.display_id(), state); } +std::string SetGammaRampAction(const ui::DisplaySnapshot& output, + const std::vector<GammaRampRGBEntry>& lut) { + std::string table; + for (size_t i = 0; i < lut.size(); ++i) { + table += base::StringPrintf(",rgb[%" PRIuS "]=%04x%04x%04x", i, lut[i].r, + lut[i].g, lut[i].b); + } + + return base::StringPrintf("set_gamma_ramp(id=%" PRId64 "%s)", + output.display_id(), table.c_str()); +} + std::string JoinActions(const char* action, ...) { std::string actions; diff --git a/ui/display/chromeos/test/action_logger_util.h b/ui/display/chromeos/test/action_logger_util.h index 4b66cd1..35609de 100644 --- a/ui/display/chromeos/test/action_logger_util.h +++ b/ui/display/chromeos/test/action_logger_util.h @@ -6,6 +6,7 @@ #define UI_DISPLAY_CHROMEOS_TEST_ACTION_LOGGER_UTIL_H_ #include <string> +#include <vector> #include "ui/display/types/display_constants.h" @@ -16,6 +17,7 @@ class Size; namespace ui { +struct GammaRampRGBEntry; class DisplayMode; class DisplaySnapshot; @@ -62,6 +64,9 @@ std::string GetFramebufferAction(const gfx::Size& size, std::string GetSetHDCPStateAction(const DisplaySnapshot& output, HDCPState state); +// Returns a string describing a TestNativeDisplayDelegate::SetGammaRamp() call; +std::string SetGammaRampAction(const ui::DisplaySnapshot& output, + const std::vector<GammaRampRGBEntry>& lut); // Joins a sequence of strings describing actions (e.g. kScreenDim) such // that they can be compared against a string returned by // ActionLogger::GetActionsAndClear(). The list of actions must be diff --git a/ui/display/chromeos/test/test_native_display_delegate.cc b/ui/display/chromeos/test/test_native_display_delegate.cc index f1b0101..dfffe3c 100644 --- a/ui/display/chromeos/test/test_native_display_delegate.cc +++ b/ui/display/chromeos/test/test_native_display_delegate.cc @@ -132,6 +132,13 @@ bool TestNativeDisplayDelegate::SetColorCalibrationProfile( return false; } +bool TestNativeDisplayDelegate::SetGammaRamp( + const ui::DisplaySnapshot& output, + const std::vector<GammaRampRGBEntry>& lut) { + log_->AppendAction(SetGammaRampAction(output, lut)); + return true; +} + void TestNativeDisplayDelegate::AddObserver(NativeDisplayObserver* observer) { } diff --git a/ui/display/chromeos/test/test_native_display_delegate.h b/ui/display/chromeos/test/test_native_display_delegate.h index f9e1767..f64d3c7 100644 --- a/ui/display/chromeos/test/test_native_display_delegate.h +++ b/ui/display/chromeos/test/test_native_display_delegate.h @@ -73,6 +73,8 @@ class TestNativeDisplayDelegate : public NativeDisplayDelegate { bool SetColorCalibrationProfile( const DisplaySnapshot& output, ui::ColorCalibrationProfile new_profile) override; + bool SetGammaRamp(const ui::DisplaySnapshot& output, + const std::vector<GammaRampRGBEntry>& lut) override; void AddObserver(NativeDisplayObserver* observer) override; void RemoveObserver(NativeDisplayObserver* observer) override; diff --git a/ui/display/chromeos/x11/native_display_delegate_x11.cc b/ui/display/chromeos/x11/native_display_delegate_x11.cc index 5c23e3f..15a2cfa 100644 --- a/ui/display/chromeos/x11/native_display_delegate_x11.cc +++ b/ui/display/chromeos/x11/native_display_delegate_x11.cc @@ -623,6 +623,13 @@ XRRCrtcGamma* NativeDisplayDelegateX11::CreateGammaRampForProfile( return NULL; } +bool NativeDisplayDelegateX11::SetGammaRamp( + const ui::DisplaySnapshot& output, + const std::vector<GammaRampRGBEntry>& lut) { + NOTIMPLEMENTED(); + return false; +} + void NativeDisplayDelegateX11::DrawBackground() { if (!background_color_argb_) return; diff --git a/ui/display/chromeos/x11/native_display_delegate_x11.h b/ui/display/chromeos/x11/native_display_delegate_x11.h index 5d49435..4a0f1e3 100644 --- a/ui/display/chromeos/x11/native_display_delegate_x11.h +++ b/ui/display/chromeos/x11/native_display_delegate_x11.h @@ -95,6 +95,8 @@ class DISPLAY_EXPORT NativeDisplayDelegateX11 : public NativeDisplayDelegate { const DisplaySnapshot& output) override; bool SetColorCalibrationProfile(const DisplaySnapshot& output, ColorCalibrationProfile new_profile) override; + bool SetGammaRamp(const ui::DisplaySnapshot& output, + const std::vector<GammaRampRGBEntry>& lut) override; void AddObserver(NativeDisplayObserver* observer) override; void RemoveObserver(NativeDisplayObserver* observer) override; diff --git a/ui/display/display.gyp b/ui/display/display.gyp index e8f45f7..cf1f9ba 100644 --- a/ui/display/display.gyp +++ b/ui/display/display.gyp @@ -26,6 +26,7 @@ 'types/display_snapshot.cc', 'types/display_snapshot.h', 'types/display_types_export.h', + 'types/gamma_ramp_rgb_entry.h', 'types/native_display_delegate.h', 'types/native_display_observer.h', ], diff --git a/ui/display/types/BUILD.gn b/ui/display/types/BUILD.gn index 4613119..6b5d1e3 100644 --- a/ui/display/types/BUILD.gn +++ b/ui/display/types/BUILD.gn @@ -11,6 +11,7 @@ component("types") { "display_snapshot.cc", "display_snapshot.h", "display_types_export.h", + "gamma_ramp_rgb_entry.h", "native_display_delegate.h", "native_display_observer.h", ] diff --git a/ui/display/types/gamma_ramp_rgb_entry.h b/ui/display/types/gamma_ramp_rgb_entry.h new file mode 100644 index 0000000..70405e1 --- /dev/null +++ b/ui/display/types/gamma_ramp_rgb_entry.h @@ -0,0 +1,23 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_DISPLAY_TYPES_GAMMA_RAMP_RGB_ENTRY_H_ +#define UI_DISPLAY_TYPES_GAMMA_RAMP_RGB_ENTRY_H_ + +#include <stdint.h> + +#include "ui/display/types/display_types_export.h" + +namespace ui { + +// Provides a single entry for a gamma correction table in a GPU. +struct DISPLAY_TYPES_EXPORT GammaRampRGBEntry { + uint16_t r; + uint16_t g; + uint16_t b; +}; + +} // namespace ui + +#endif // UI_DISPLAY_TYPES_GAMMA_RAMP_RGB_ENTRY_H_ diff --git a/ui/display/types/native_display_delegate.h b/ui/display/types/native_display_delegate.h index 98aef26..d37083d 100644 --- a/ui/display/types/native_display_delegate.h +++ b/ui/display/types/native_display_delegate.h @@ -24,6 +24,8 @@ class DisplaySnapshot; class NativeDisplayObserver; +struct GammaRampRGBEntry; + typedef base::Callback<void(const std::vector<ui::DisplaySnapshot*>&)> GetDisplaysCallback; typedef base::Callback<void(bool)> ConfigureCallback; @@ -103,6 +105,10 @@ class DISPLAY_TYPES_EXPORT NativeDisplayDelegate { const ui::DisplaySnapshot& output, ui::ColorCalibrationProfile new_profile) = 0; + // Set the gamma ramp for the display. + virtual bool SetGammaRamp(const ui::DisplaySnapshot& output, + const std::vector<GammaRampRGBEntry>& lut) = 0; + virtual void AddObserver(NativeDisplayObserver* observer) = 0; virtual void RemoveObserver(NativeDisplayObserver* observer) = 0; diff --git a/ui/ozone/common/gpu/ozone_gpu_messages.h b/ui/ozone/common/gpu/ozone_gpu_messages.h index bc9a465..5600963 100644 --- a/ui/ozone/common/gpu/ozone_gpu_messages.h +++ b/ui/ozone/common/gpu/ozone_gpu_messages.h @@ -11,6 +11,7 @@ #include "ipc/ipc_message_macros.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/display/types/display_constants.h" +#include "ui/display/types/gamma_ramp_rgb_entry.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/ipc/gfx_param_traits.h" @@ -50,6 +51,12 @@ IPC_STRUCT_TRAITS_BEGIN(ui::DisplaySnapshot_Params) IPC_STRUCT_TRAITS_MEMBER(string_representation) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(ui::GammaRampRGBEntry) + IPC_STRUCT_TRAITS_MEMBER(r) + IPC_STRUCT_TRAITS_MEMBER(g) + IPC_STRUCT_TRAITS_MEMBER(b) +IPC_STRUCT_TRAITS_END() + //------------------------------------------------------------------------------ // GPU Messages // These are messages from the browser to the GPU process. @@ -111,6 +118,11 @@ IPC_MESSAGE_CONTROL2(OzoneGpuMsg_SetHDCPState, int64_t /* display_id */, ui::HDCPState /* state */) +// Provides the gamma ramp for display adjustment. +IPC_MESSAGE_CONTROL2(OzoneGpuMsg_SetGammaRamp, + int64_t, // display ID, + std::vector<ui::GammaRampRGBEntry>) // lut + //------------------------------------------------------------------------------ // Browser Messages // These messages are from the GPU to the browser process. diff --git a/ui/ozone/common/native_display_delegate_ozone.cc b/ui/ozone/common/native_display_delegate_ozone.cc index d85b641..c0310c8 100644 --- a/ui/ozone/common/native_display_delegate_ozone.cc +++ b/ui/ozone/common/native_display_delegate_ozone.cc @@ -105,6 +105,13 @@ bool NativeDisplayDelegateOzone::SetColorCalibrationProfile( return false; } +bool NativeDisplayDelegateOzone::SetGammaRamp( + const ui::DisplaySnapshot& output, + const std::vector<GammaRampRGBEntry>& lut) { + NOTIMPLEMENTED(); + return false; +} + void NativeDisplayDelegateOzone::AddObserver(NativeDisplayObserver* observer) { NOTIMPLEMENTED(); } diff --git a/ui/ozone/common/native_display_delegate_ozone.h b/ui/ozone/common/native_display_delegate_ozone.h index 74c8785..5f142b2 100644 --- a/ui/ozone/common/native_display_delegate_ozone.h +++ b/ui/ozone/common/native_display_delegate_ozone.h @@ -43,6 +43,9 @@ class NativeDisplayDelegateOzone : public NativeDisplayDelegate { bool SetColorCalibrationProfile( const ui::DisplaySnapshot& output, ui::ColorCalibrationProfile new_profile) override; + bool SetGammaRamp(const ui::DisplaySnapshot& output, + const std::vector<GammaRampRGBEntry>& lut) override; + void AddObserver(NativeDisplayObserver* observer) override; void RemoveObserver(NativeDisplayObserver* observer) override; diff --git a/ui/ozone/platform/drm/gpu/drm_device.cc b/ui/ozone/platform/drm/gpu/drm_device.cc index 49b6f5e..b14d229 100644 --- a/ui/ozone/platform/drm/gpu/drm_device.cc +++ b/ui/ozone/platform/drm/gpu/drm_device.cc @@ -18,6 +18,7 @@ #include "base/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "third_party/skia/include/core/SkImageInfo.h" +#include "ui/display/types/gamma_ramp_rgb_entry.h" #include "ui/ozone/platform/drm/gpu/drm_util.h" #include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h" @@ -584,4 +585,32 @@ bool DrmDevice::DropMaster() { return (drmDropMaster(file_.GetPlatformFile()) == 0); } +bool DrmDevice::SetGammaRamp(uint32_t crtc_id, + const std::vector<GammaRampRGBEntry>& lut) { + ScopedDrmCrtcPtr crtc = GetCrtc(crtc_id); + + // TODO(robert.bradford) resample the incoming ramp to match what the kernel + // expects. + if (static_cast<size_t>(crtc->gamma_size) != lut.size()) { + LOG(ERROR) << "Gamma table size mismatch: supplied " << lut.size() + << " expected " << crtc->gamma_size; + } + + std::vector<uint16_t> r, g, b; + r.reserve(lut.size()); + g.reserve(lut.size()); + b.reserve(lut.size()); + + for (size_t i = 0; i < lut.size(); ++i) { + r.push_back(lut[i].r); + g.push_back(lut[i].g); + b.push_back(lut[i].b); + } + + DCHECK(file_.IsValid()); + TRACE_EVENT0("drm", "DrmDevice::SetGamma"); + return (drmModeCrtcSetGamma(file_.GetPlatformFile(), crtc_id, r.size(), &r[0], + &g[0], &b[0]) == 0); +} + } // namespace ui diff --git a/ui/ozone/platform/drm/gpu/drm_device.h b/ui/ozone/platform/drm/gpu/drm_device.h index 1e3d12e..02d88ed 100644 --- a/ui/ozone/platform/drm/gpu/drm_device.h +++ b/ui/ozone/platform/drm/gpu/drm_device.h @@ -34,6 +34,7 @@ class SingleThreadTaskRunner; namespace ui { class HardwareDisplayPlaneManager; +struct GammaRampRGBEntry; // Wraps DRM calls into a nice interface. Used to provide different // implementations of the DRM calls. For the actual implementation the DRM API @@ -160,6 +161,10 @@ class OZONE_EXPORT DrmDevice : public base::RefCountedThreadSafe<DrmDevice> { uint32_t flags, const PageFlipCallback& callback); + // Set the gamma ramp for |crtc_id| to reflect the ramps in |lut|. + virtual bool SetGammaRamp(uint32_t crtc_id, + const std::vector<GammaRampRGBEntry>& lut); + // Drm master related virtual bool SetMaster(); virtual bool DropMaster(); diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc index 1214d7d..8a25418 100644 --- a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc +++ b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc @@ -9,6 +9,7 @@ #include "base/file_descriptor_posix.h" #include "base/files/file.h" #include "base/single_thread_task_runner.h" +#include "ui/display/types/gamma_ramp_rgb_entry.h" #include "ui/display/types/native_display_observer.h" #include "ui/events/ozone/device/device_event.h" #include "ui/ozone/common/display_util.h" @@ -192,6 +193,21 @@ bool DrmGpuDisplayManager::RelinquishDisplayControl() { return true; } +void DrmGpuDisplayManager::SetGammaRamp( + int64_t id, + const std::vector<GammaRampRGBEntry>& lut) { + DrmDisplaySnapshot* display = FindDisplaySnapshot(id); + if (!display) { + LOG(ERROR) << "There is no display with ID " << id; + return; + } + + if (!display->drm()->SetGammaRamp(display->crtc(), lut)) { + LOG(ERROR) << "Failed to set gamma ramp for display: crtc_id = " + << display->crtc() << " size = " << lut.size(); + } +} + DrmDisplaySnapshot* DrmGpuDisplayManager::FindDisplaySnapshot(int64_t id) { for (size_t i = 0; i < cached_displays_.size(); ++i) if (cached_displays_[i]->display_id() == id) diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h index e23885b..21c314e 100644 --- a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h +++ b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h @@ -26,6 +26,8 @@ class DrmDisplaySnapshot; class DrmDisplayMode; class ScreenManager; +struct GammaRampRGBEntry; + class DrmGpuDisplayManager { public: DrmGpuDisplayManager(ScreenManager* screen_manager, @@ -56,6 +58,9 @@ class DrmGpuDisplayManager { bool GetHDCPState(int64_t display_id, HDCPState* state); bool SetHDCPState(int64_t display_id, HDCPState state); + // Set the gamma ramp for a particular display id. + void SetGammaRamp(int64_t id, const std::vector<GammaRampRGBEntry>& lut); + private: DrmDisplaySnapshot* FindDisplaySnapshot(int64_t id); const DrmDisplayMode* FindDisplayMode(const gfx::Size& size, diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.cc b/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.cc index 0a9108e..9a730bc 100644 --- a/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.cc +++ b/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.cc @@ -216,6 +216,7 @@ bool DrmGpuPlatformSupport::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(OzoneGpuMsg_RemoveGraphicsDevice, OnRemoveGraphicsDevice) IPC_MESSAGE_HANDLER(OzoneGpuMsg_GetHDCPState, OnGetHDCPState) IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetHDCPState, OnSetHDCPState) + IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetGammaRamp, OnSetGammaRamp); IPC_MESSAGE_UNHANDLED(handled = false); IPC_END_MESSAGE_MAP() @@ -294,6 +295,12 @@ void DrmGpuPlatformSupport::OnRemoveGraphicsDevice(const base::FilePath& path) { drm_device_manager_->RemoveDrmDevice(path); } +void DrmGpuPlatformSupport::OnSetGammaRamp( + int64_t id, + const std::vector<GammaRampRGBEntry>& lut) { + ndd_->SetGammaRamp(id, lut); +} + void DrmGpuPlatformSupport::RelinquishGpuResources( const base::Closure& callback) { callback.Run(); diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.h b/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.h index abd6978..1662ea3 100644 --- a/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.h +++ b/ui/ozone/platform/drm/gpu/drm_gpu_platform_support.h @@ -36,6 +36,7 @@ class ScreenManager; struct DisplayMode_Params; struct DisplaySnapshot_Params; +struct GammaRampRGBEntry; class DrmGpuPlatformSupport : public GpuPlatformSupport { public: @@ -78,6 +79,7 @@ class DrmGpuPlatformSupport : public GpuPlatformSupport { void OnRemoveGraphicsDevice(const base::FilePath& path); void OnGetHDCPState(int64_t display_id); void OnSetHDCPState(int64_t display_id, HDCPState state); + void OnSetGammaRamp(int64_t id, const std::vector<GammaRampRGBEntry>& lut); void SetIOTaskRunner( const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner); diff --git a/ui/ozone/platform/drm/host/drm_native_display_delegate.cc b/ui/ozone/platform/drm/host/drm_native_display_delegate.cc index b200165..fffa9ca 100644 --- a/ui/ozone/platform/drm/host/drm_native_display_delegate.cc +++ b/ui/ozone/platform/drm/host/drm_native_display_delegate.cc @@ -243,6 +243,13 @@ bool DrmNativeDisplayDelegate::SetColorCalibrationProfile( return false; } +bool DrmNativeDisplayDelegate::SetGammaRamp( + const ui::DisplaySnapshot& output, + const std::vector<GammaRampRGBEntry>& lut) { + proxy_->Send(new OzoneGpuMsg_SetGammaRamp(output.display_id(), lut)); + return true; +} + void DrmNativeDisplayDelegate::AddObserver(NativeDisplayObserver* observer) { observers_.AddObserver(observer); } diff --git a/ui/ozone/platform/drm/host/drm_native_display_delegate.h b/ui/ozone/platform/drm/host/drm_native_display_delegate.h index 81193af..09d01a4 100644 --- a/ui/ozone/platform/drm/host/drm_native_display_delegate.h +++ b/ui/ozone/platform/drm/host/drm_native_display_delegate.h @@ -63,6 +63,8 @@ class DrmNativeDisplayDelegate : public NativeDisplayDelegate, const DisplaySnapshot& output) override; bool SetColorCalibrationProfile(const DisplaySnapshot& output, ColorCalibrationProfile new_profile) override; + bool SetGammaRamp(const ui::DisplaySnapshot& output, + const std::vector<GammaRampRGBEntry>& lut) override; void AddObserver(NativeDisplayObserver* observer) override; void RemoveObserver(NativeDisplayObserver* observer) override; diff --git a/ui/ozone/platform/drm/test/mock_drm_device.cc b/ui/ozone/platform/drm/test/mock_drm_device.cc index 3a822dc..0b1e348 100644 --- a/ui/ozone/platform/drm/test/mock_drm_device.cc +++ b/ui/ozone/platform/drm/test/mock_drm_device.cc @@ -240,6 +240,11 @@ bool MockDrmDevice::CommitProperties(drmModePropertySet* properties, return false; } +bool MockDrmDevice::SetGammaRamp(uint32_t crtc_id, + const std::vector<GammaRampRGBEntry>& lut) { + return true; +} + void MockDrmDevice::RunCallbacks() { while (!callbacks_.empty()) { PageFlipCallback callback = callbacks_.front(); diff --git a/ui/ozone/platform/drm/test/mock_drm_device.h b/ui/ozone/platform/drm/test/mock_drm_device.h index 5632b6e..cd9a2f2 100644 --- a/ui/ozone/platform/drm/test/mock_drm_device.h +++ b/ui/ozone/platform/drm/test/mock_drm_device.h @@ -16,6 +16,7 @@ namespace ui { class CrtcController; +struct GammaRampRGBEntry; // The real DrmDevice makes actual DRM calls which we can't use in unit tests. class MockDrmDevice : public ui::DrmDevice { @@ -108,6 +109,8 @@ class MockDrmDevice : public ui::DrmDevice { bool CommitProperties(drmModePropertySet* properties, uint32_t flags, const PageFlipCallback& callback) override; + bool SetGammaRamp(uint32_t crtc_id, + const std::vector<GammaRampRGBEntry>& lut) override; private: ~MockDrmDevice() override; |