"Merge Tagged PR 2542"

This commit is contained in:
yuzubot
2019-10-28 12:01:15 +00:00
parent 0a2ad100cb
commit 9077da0378
10 changed files with 403 additions and 19 deletions

View File

@@ -10,6 +10,8 @@
#include "core/hle/service/lbl/lbl.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
#include "core/settings.h"
#include "video_core/renderer_base.h"
namespace Service::LBL {
@@ -18,21 +20,21 @@ public:
explicit LBL() : ServiceFramework{"lbl"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "SaveCurrentSetting"},
{1, nullptr, "LoadCurrentSetting"},
{2, nullptr, "SetCurrentBrightnessSetting"},
{3, nullptr, "GetCurrentBrightnessSetting"},
{4, nullptr, "ApplyCurrentBrightnessSettingToBacklight"},
{5, nullptr, "GetBrightnessSettingAppliedToBacklight"},
{6, nullptr, "SwitchBacklightOn"},
{7, nullptr, "SwitchBacklightOff"},
{8, nullptr, "GetBacklightSwitchStatus"},
{9, nullptr, "EnableDimming"},
{10, nullptr, "DisableDimming"},
{11, nullptr, "IsDimmingEnabled"},
{12, nullptr, "EnableAutoBrightnessControl"},
{13, nullptr, "DisableAutoBrightnessControl"},
{14, nullptr, "IsAutoBrightnessControlEnabled"},
{0, &LBL::SaveCurrentSetting, "SaveCurrentSetting"},
{1, &LBL::LoadCurrentSetting, "LoadCurrentSetting"},
{2, &LBL::SetCurrentBrightnessSetting, "SetCurrentBrightnessSetting"},
{3, &LBL::GetCurrentBrightnessSetting, "GetCurrentBrightnessSetting"},
{4, &LBL::ApplyCurrentBrightnessSettingToBacklight, "ApplyCurrentBrightnessSettingToBacklight"},
{5, &LBL::GetBrightnessSettingAppliedToBacklight, "GetBrightnessSettingAppliedToBacklight"},
{6, &LBL::SwitchBacklightOn, "SwitchBacklightOn"},
{7, &LBL::SwitchBacklightOff, "SwitchBacklightOff"},
{8, &LBL::GetBacklightSwitchStatus, "GetBacklightSwitchStatus"},
{9, &LBL::EnableDimming, "EnableDimming"},
{10, &LBL::DisableDimming, "DisableDimming"},
{11, &LBL::IsDimmingEnabled, "IsDimmingEnabled"},
{12, &LBL::EnableAutoBrightnessControl, "EnableAutoBrightnessControl"},
{13, &LBL::DisableAutoBrightnessControl, "DisableAutoBrightnessControl"},
{14, &LBL::IsAutoBrightnessControlEnabled, "IsAutoBrightnessControlEnabled"},
{15, nullptr, "SetAmbientLightSensorValue"},
{16, nullptr, "GetAmbientLightSensorValue"},
{17, nullptr, "SetBrightnessReflectionDelayLevel"},
@@ -42,8 +44,8 @@ public:
{21, nullptr, "SetCurrentAmbientLightSensorMapping"},
{22, nullptr, "GetCurrentAmbientLightSensorMapping"},
{23, nullptr, "IsAmbientLightSensorAvailable"},
{24, nullptr, "SetCurrentBrightnessSettingForVrMode"},
{25, nullptr, "GetCurrentBrightnessSettingForVrMode"},
{24, &LBL::SetCurrentBrightnessSettingForVrMode, "SetCurrentBrightnessSettingForVrMode"},
{25, &LBL::GetCurrentBrightnessSettingForVrMode, "GetCurrentBrightnessSettingForVrMode"},
{26, &LBL::EnableVrMode, "EnableVrMode"},
{27, &LBL::DisableVrMode, "DisableVrMode"},
{28, &LBL::IsVrModeEnabled, "IsVrModeEnabled"},
@@ -53,13 +55,209 @@ public:
RegisterHandlers(functions);
}
void LoadFromSettings() {
current_brightness = Settings::values.backlight_brightness;
current_vr_mode_brightness = Settings::values.backlight_brightness;
if (auto_brightness_enabled) {
return;
}
if (vr_mode_enabled) {
Renderer().SetCurrentBrightness(current_vr_mode_brightness);
} else {
Renderer().SetCurrentBrightness(current_brightness);
}
}
private:
f32 GetAutoBrightnessValue() const {
return 0.5f;
}
VideoCore::RendererBase& Renderer() {
return Core::System::GetInstance().Renderer();
}
void SaveCurrentSetting(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
Settings::values.backlight_brightness = current_brightness;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void LoadCurrentSetting(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
LoadFromSettings();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void SetCurrentBrightnessSetting(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto value = rp.PopRaw<f32>();
LOG_DEBUG(Service_LBL, "called, value={:.3f}", value);
current_brightness = std::clamp(value, 0.0f, 1.0f);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetCurrentBrightnessSetting(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(current_brightness);
}
void ApplyCurrentBrightnessSettingToBacklight(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
if (!auto_brightness_enabled) {
Renderer().SetCurrentBrightness(vr_mode_enabled ? current_vr_mode_brightness
: current_brightness);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetBrightnessSettingAppliedToBacklight(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(Renderer().GetCurrentResultantBrightness());
}
void SwitchBacklightOn(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto fade_time = rp.PopRaw<u64>();
LOG_DEBUG(Service_LBL, "called, fade_time={:016X}", fade_time);
Renderer().SetBacklightStatus(true, fade_time);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void SwitchBacklightOff(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto fade_time = rp.PopRaw<u64>();
LOG_DEBUG(Service_LBL, "called, fade_time={:016X}", fade_time);
Renderer().SetBacklightStatus(false, fade_time);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetBacklightSwitchStatus(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u8>(Renderer().GetBacklightStatus());
}
void EnableDimming(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
dimming_enabled = true;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void DisableDimming(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "callled");
dimming_enabled = false;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void IsDimmingEnabled(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u8>(dimming_enabled);
}
void EnableAutoBrightnessControl(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
auto_brightness_enabled = true;
Renderer().SetCurrentBrightness(GetAutoBrightnessValue());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void DisableAutoBrightnessControl(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
auto_brightness_enabled = false;
Renderer().SetCurrentBrightness(current_brightness);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void IsAutoBrightnessControlEnabled(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u8>(auto_brightness_enabled);
}
void SetCurrentBrightnessSettingForVrMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto value = rp.PopRaw<f32>();
LOG_DEBUG(Service_LBL, "called, value={:.3f}", value);
current_vr_mode_brightness = std::clamp(value, 0.0f, 1.0f);
if (vr_mode_enabled && !auto_brightness_enabled) {
Renderer().SetCurrentBrightness(value);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetCurrentBrightnessSettingForVrMode(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(current_vr_mode_brightness);
}
void EnableVrMode(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LBL, "called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
if (!vr_mode_enabled && !auto_brightness_enabled &&
current_brightness != current_vr_mode_brightness) {
Renderer().SetCurrentBrightness(current_vr_mode_brightness);
}
vr_mode_enabled = true;
}
@@ -69,6 +267,11 @@ private:
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
if (vr_mode_enabled && !auto_brightness_enabled &&
current_brightness != current_vr_mode_brightness) {
Renderer().SetCurrentBrightness(current_brightness);
}
vr_mode_enabled = false;
}
@@ -80,9 +283,27 @@ private:
rb.Push(vr_mode_enabled);
}
bool auto_brightness_enabled = false;
bool dimming_enabled = true;
f32 current_brightness = GetAutoBrightnessValue();
f32 current_vr_mode_brightness = GetAutoBrightnessValue();
bool vr_mode_enabled = false;
};
void RequestLoadCurrentSetting(SM::ServiceManager& sm) {
if (&sm == nullptr) {
return;
}
const auto lbl = sm.GetService<LBL>("lbl");
if (lbl) {
lbl->LoadFromSettings();
}
}
void InstallInterfaces(SM::ServiceManager& sm) {
std::make_shared<LBL>()->InstallAsService(sm);
}

View File

@@ -10,6 +10,9 @@ class ServiceManager;
namespace Service::LBL {
// Requests the LBL service passed to load brightness values from Settings
void RequestLoadCurrentSetting(SM::ServiceManager& sm);
void InstallInterfaces(SM::ServiceManager& sm);
} // namespace Service::LBL

View File

@@ -6,6 +6,8 @@
#include "core/core.h"
#include "core/gdbstub/gdbstub.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/lbl/lbl.h"
#include "core/hle/service/sm/sm.h"
#include "core/settings.h"
#include "video_core/renderer_base.h"
@@ -70,6 +72,7 @@ void Apply() {
auto& system_instance = Core::System::GetInstance();
if (system_instance.IsPoweredOn()) {
system_instance.Renderer().RefreshBaseSettings();
Service::LBL::RequestLoadCurrentSetting(system_instance.ServiceManager());
}
Service::HID::ReloadInputDevices();

View File

@@ -428,6 +428,8 @@ struct Values {
float bg_green;
float bg_blue;
float backlight_brightness = 0.5f;
std::string log_filter;
bool use_dev_keys;

View File

@@ -40,4 +40,35 @@ void RendererBase::RequestScreenshot(void* data, std::function<void()> callback,
renderer_settings.screenshot_requested = true;
}
f32 RendererBase::GetCurrentResultantBrightness() const {
return renderer_settings.current_brightness / 2.0f;
}
void RendererBase::SetBacklightStatus(bool enabled, u64 fade_transition_time) {
if (fade_transition_time == 0) {
// Needed to ensure the renderer recognizes that a change must occur.
fade_transition_time = 1;
}
if (enabled && renderer_settings.current_brightness == 0) {
renderer_settings.current_brightness = current_brightness_backup;
renderer_settings.backlight_fade_time = fade_transition_time;
} else if (!enabled && renderer_settings.current_brightness != 0) {
current_brightness_backup = renderer_settings.current_brightness;
renderer_settings.current_brightness = 0;
renderer_settings.backlight_fade_time = fade_transition_time;
}
}
bool RendererBase::GetBacklightStatus() const {
return renderer_settings.current_brightness != 0;
}
void RendererBase::SetCurrentBrightness(f32 value) {
if (value != renderer_settings.current_brightness) {
renderer_settings.current_brightness = value * 2.0f;
renderer_settings.backlight_fade_time = 1;
}
}
} // namespace VideoCore

View File

@@ -28,6 +28,10 @@ struct RendererSettings {
void* screenshot_bits;
std::function<void()> screenshot_complete_callback;
Layout::FramebufferLayout screenshot_framebuffer_layout;
// Backlight & Brightness
std::atomic<f32> current_brightness{1.f};
std::atomic<u64> backlight_fade_time{0};
};
class RendererBase : NonCopyable {
@@ -86,6 +90,17 @@ public:
void RequestScreenshot(void* data, std::function<void()> callback,
const Layout::FramebufferLayout& layout);
// Gets the current brightness, even if it has been changed from the set value. Most of the time
// for yuzu this will simply match what was returned, but implementations are free to change the
// value in settings.
f32 GetCurrentResultantBrightness() const;
void SetBacklightStatus(bool enabled, u64 fade_transition_time);
bool GetBacklightStatus() const;
void SetCurrentBrightness(f32 value);
protected:
Core::Frontend::EmuWindow& render_window; ///< Reference to the render window handle.
std::unique_ptr<RasterizerInterface> rasterizer;
@@ -97,6 +112,9 @@ protected:
private:
/// Updates the framebuffer layout of the contained render window handle.
void UpdateCurrentFramebufferLayout();
// Value of brightness before backlight switch used to preserve value.
f32 current_brightness_backup;
};
} // namespace VideoCore

View File

@@ -54,11 +54,13 @@ in vec2 frag_tex_coord;
out vec4 color;
uniform sampler2D color_texture;
uniform vec4 backlight;
void main() {
// Swap RGBA -> ABGR so we don't have to do this on the CPU. This needs to change if we have to
// support more framebuffer pixel formats.
color = texture(color_texture, frag_tex_coord);
// Also multiply the color by the backlight multiplier supplied.
color = texture(color_texture, frag_tex_coord) * backlight;
}
)";
@@ -121,8 +123,13 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
// Load the framebuffer from memory, draw it to the screen, and swap buffers
LoadFBToScreenInfo(*framebuffer);
if (renderer_settings.screenshot_requested)
if (renderer_settings.screenshot_requested) {
CaptureScreenshot();
}
if (renderer_settings.backlight_fade_time > 0) {
UpdateBacklight();
}
DrawScreen(render_window.GetFramebufferLayout());
@@ -205,9 +212,13 @@ void RendererOpenGL::InitOpenGLObjects() {
state.Apply();
uniform_modelview_matrix = glGetUniformLocation(shader.handle, "modelview_matrix");
uniform_color_texture = glGetUniformLocation(shader.handle, "color_texture");
uniform_backlight = glGetUniformLocation(shader.handle, "backlight");
attrib_position = glGetAttribLocation(shader.handle, "vert_position");
attrib_tex_coord = glGetAttribLocation(shader.handle, "vert_tex_coord");
// Initialize backlight
glUniform4f(uniform_backlight, 1.f, 1.f, 1.f, 1.f);
// Generate VBO handle for drawing
vertex_buffer.Create();
@@ -416,6 +427,29 @@ void RendererOpenGL::CaptureScreenshot() {
renderer_settings.screenshot_requested = false;
}
void RendererOpenGL::UpdateBacklight() {
constexpr u64 PER_FRAME_FADE_TIME = 1000000000.0f / 60;
const auto fade_time = renderer_settings.backlight_fade_time.load(std::memory_order_relaxed);
auto value = renderer_settings.current_brightness.load(std::memory_order_relaxed);
if (fade_time <= PER_FRAME_FADE_TIME) {
glUniform4f(uniform_backlight, value, value, value, value);
renderer_settings.backlight_fade_time = 0;
fade_time_max = 0;
} else {
if (fade_time_max == 0) {
fade_time_max = fade_time;
value_max = value;
}
value += (value_max - value) * PER_FRAME_FADE_TIME / fade_time_max;
glUniform4f(uniform_backlight, value, value, value, value);
renderer_settings.backlight_fade_time -= PER_FRAME_FADE_TIME;
renderer_settings.current_brightness = value;
}
}
static const char* GetSource(GLenum source) {
#define RET(s) \
case GL_DEBUG_SOURCE_##s: \

View File

@@ -70,6 +70,7 @@ private:
void UpdateFramerate();
void CaptureScreenshot();
void UpdateBacklight();
// Loads framebuffer from emulated memory into the display information structure
void LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuffer);
@@ -97,6 +98,7 @@ private:
// Shader uniform location indices
GLuint uniform_modelview_matrix;
GLuint uniform_color_texture;
GLuint uniform_backlight;
// Shader attribute input indices
GLuint attrib_position;
@@ -105,6 +107,10 @@ private:
/// Used for transforming the framebuffer orientation
Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags;
Common::Rectangle<int> framebuffer_crop_rect;
// Used for backlight transitions
u64 fade_time_max = 0;
f32 value_max = 0;
};
} // namespace OpenGL

View File

@@ -62,6 +62,8 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
}
UpdateBackgroundColorButton(new_bg_color);
});
connect(ui->brightness_reset, &QPushButton::pressed, this,
[this] { ui->brightness_slider->setValue(100); });
}
ConfigureGraphics::~ConfigureGraphics() = default;
@@ -80,6 +82,7 @@ void ConfigureGraphics::SetConfiguration() {
ui->force_30fps_mode->setChecked(Settings::values.force_30fps_mode);
UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red, Settings::values.bg_green,
Settings::values.bg_blue));
ui->brightness_slider->setValue(Settings::values.backlight_brightness * 100 + 50);
}
void ConfigureGraphics::ApplyConfiguration() {
@@ -93,6 +96,7 @@ void ConfigureGraphics::ApplyConfiguration() {
Settings::values.bg_red = static_cast<float>(bg_color.redF());
Settings::values.bg_green = static_cast<float>(bg_color.greenF());
Settings::values.bg_blue = static_cast<float>(bg_color.blueF());
Settings::values.backlight_brightness = (ui->brightness_slider->value() - 50.0f) / 100.0f;
}
void ConfigureGraphics::changeEvent(QEvent* event) {

View File

@@ -111,6 +111,68 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Brightness</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSlider" name="brightness_slider">
<property name="minimum">
<number>50</number>
</property>
<property name="maximum">
<number>150</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="pageStep">
<number>20</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::NoTicks</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="brightness_reset">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>