blob: 427eb22348a7fce6ac7e815e473c2c73656abfa1 [file] [log] [blame]
// Copyright 2020 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 "chromecast/ui/display_settings/gamma_configurator.h"
#include <limits>
#include "chromecast/browser/cast_display_configurator.h"
#include "chromecast/graphics/cast_window_manager.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/compositor/compositor.h"
namespace chromecast {
namespace {
constexpr size_t kGammaTableSize = 256;
constexpr uint16_t kMaxGammaValue = std::numeric_limits<uint16_t>::max();
std::vector<display::GammaRampRGBEntry> CreateDefaultGammaLut() {
std::vector<display::GammaRampRGBEntry> gamma_lut;
for (size_t i = 0; i < kGammaTableSize; ++i) {
float value =
static_cast<float>(kGammaTableSize - i - 1) / (kGammaTableSize - 1);
value *= kMaxGammaValue;
gamma_lut.push_back({value, value, value});
}
return gamma_lut;
}
std::vector<display::GammaRampRGBEntry> InvertGammaLut(
const std::vector<display::GammaRampRGBEntry>& gamma_lut) {
// Use default reversed linear gamma LUT for inversion
if (gamma_lut.empty())
return CreateDefaultGammaLut();
// Use calibrated gamma LUT in reverse for inversion
std::vector<display::GammaRampRGBEntry> gamma_lut_inverted(gamma_lut.rbegin(),
gamma_lut.rend());
return gamma_lut_inverted;
}
} // namespace
GammaConfigurator::GammaConfigurator(
CastWindowManager* window_manager,
shell::CastDisplayConfigurator* display_configurator)
: window_manager_(window_manager),
display_configurator_(display_configurator) {
DCHECK(window_manager_);
DCHECK(display_configurator_);
}
GammaConfigurator::~GammaConfigurator() = default;
void GammaConfigurator::OnCalibratedGammaLoaded(
const std::vector<display::GammaRampRGBEntry>& gamma) {
is_initialized_ = true;
gamma_lut_ = gamma;
if (is_inverted_)
ApplyGammaLut();
}
void GammaConfigurator::ApplyGammaLut() {
if (is_inverted_)
display_configurator_->SetGammaCorrection({}, InvertGammaLut(gamma_lut_));
else
display_configurator_->SetGammaCorrection({}, gamma_lut_);
// The LUT is applied on the next swap buffers, so we need to make sure the
// root window triggers a swap buffer otherwise the content will not update.
window_manager_->GetRootWindow()
->GetHost()
->compositor()
->ScheduleFullRedraw();
}
void GammaConfigurator::SetColorInversion(bool invert) {
is_inverted_ = invert;
if (is_initialized_)
ApplyGammaLut();
}
} // namespace chromecast