blob: 3d09df2a592fe88b967d148d67a3d4a020c28246 [file] [log] [blame]
// Copyright 2023 The Fuchsia 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 "src/graphics/display/lib/edid/timings.h"
#include <lib/stdcompat/span.h>
#include <gtest/gtest.h>
#include "src/graphics/display/lib/api-types-cpp/display-timing.h"
namespace edid {
namespace {
TEST(EdidTimingParams, Progressive) {
constexpr display::DisplayTiming kExpected = {
.horizontal_active_px = 0x0f'0f,
.horizontal_front_porch_px = 0x0a'0a,
.horizontal_sync_width_px = 0x01'01,
.horizontal_back_porch_px = 0x02'02,
.vertical_active_lines = 0x0b'0b,
.vertical_front_porch_lines = 0x03'03,
.vertical_sync_width_lines = 0x04'04,
.vertical_back_porch_lines = 0x05'05,
.pixel_clock_frequency_khz = 0x1f'1f'1f,
.fields_per_frame = display::FieldsPerFrame::kProgressive,
.hsync_polarity = display::SyncPolarity::kPositive,
.vsync_polarity = display::SyncPolarity::kPositive,
.vblank_alternates = false,
.pixel_repetition = 0,
};
constexpr timing_params_t kEdidTimingParams = {
.pixel_freq_khz = 0x1f'1f'1f,
.horizontal_addressable = 0x0f'0f,
.horizontal_front_porch = 0x0a'0a,
.horizontal_sync_pulse = 0x01'01,
.horizontal_blanking = 0x0d'0d,
.vertical_addressable = 0x0b'0b,
.vertical_front_porch = 0x03'03,
.vertical_sync_pulse = 0x04'04,
.vertical_blanking = 0x0c'0c,
.flags = timing_params_t::kPositiveHsync | timing_params_t::kPositiveVsync,
// Calculated from the values above:
// Htotal = Hactive + Hblank = 0x1c'1c,
// Vtotal = Vactive + Vblank = 0x17'17,
// Field refresh rate = Pixel Freq (Hz) / (Htotal * Vtotal) = 47.9501 Hz
.vertical_refresh_e2 = 4795,
};
const display::DisplayTiming display_timing = ToDisplayTiming(kEdidTimingParams);
EXPECT_EQ(kExpected, display_timing);
const int vertical_refresh_rate_centihertz =
(display_timing.vertical_field_refresh_rate_millihertz() + 5) / 10;
EXPECT_EQ(vertical_refresh_rate_centihertz,
static_cast<int>(kEdidTimingParams.vertical_refresh_e2));
}
TEST(EdidTimingParams, Interlaced) {
constexpr display::DisplayTiming kExpected = {
.horizontal_active_px = 0x0f'0f,
.horizontal_front_porch_px = 0x0a'0a,
.horizontal_sync_width_px = 0x01'01,
.horizontal_back_porch_px = 0x02'02,
.vertical_active_lines = 0x0b'0b,
.vertical_front_porch_lines = 0x03'03,
.vertical_sync_width_lines = 0x04'04,
.vertical_back_porch_lines = 0x05'05,
.pixel_clock_frequency_khz = 0x1f'1f'1f,
.fields_per_frame = display::FieldsPerFrame::kInterlaced,
.hsync_polarity = display::SyncPolarity::kPositive,
.vsync_polarity = display::SyncPolarity::kPositive,
.vblank_alternates = true,
.pixel_repetition = 0,
};
constexpr timing_params_t kEdidTimingParams = {
.pixel_freq_khz = 0x1f'1f'1f,
.horizontal_addressable = 0x0f'0f,
.horizontal_front_porch = 0x0a'0a,
.horizontal_sync_pulse = 0x01'01,
.horizontal_blanking = 0x0d'0d,
.vertical_addressable = 0x0b'0b,
.vertical_front_porch = 0x03'03,
.vertical_sync_pulse = 0x04'04,
.vertical_blanking = 0x0c'0c,
.flags = timing_params_t::kInterlaced | timing_params_t::kPositiveHsync |
timing_params_t::kPositiveVsync | timing_params_t::kAlternatingVblank,
// Calculated from the values above:
// Htotal = Hactive + Hblank = 0x1c'1c,
// Vtotal = Vactive + Vblank * 2 + 1 = 0x23'24
// Field refresh rate = Pixel Freq (Hz) / (Htotal * Vtotal) = 63.0131 Hz
.vertical_refresh_e2 = 63'01,
};
const display::DisplayTiming display_timing = ToDisplayTiming(kEdidTimingParams);
EXPECT_EQ(kExpected, display_timing);
const int vertical_refresh_rate_centihertz =
(display_timing.vertical_field_refresh_rate_millihertz() + 5) / 10;
EXPECT_EQ(vertical_refresh_rate_centihertz,
static_cast<int>(kEdidTimingParams.vertical_refresh_e2));
}
TEST(EdidTimingParams, PolarityMapping) {
// Verify Hsync / Vsync polarities are correctly mapped.
{
constexpr display::DisplayTiming kExpected = {
.horizontal_active_px = 0x0f'0f,
.horizontal_front_porch_px = 0x0a'0a,
.horizontal_sync_width_px = 0x01'01,
.horizontal_back_porch_px = 0x02'02,
.vertical_active_lines = 0x0b'0b,
.vertical_front_porch_lines = 0x03'03,
.vertical_sync_width_lines = 0x04'04,
.vertical_back_porch_lines = 0x05'05,
.pixel_clock_frequency_khz = 0x1f'1f'1f,
.fields_per_frame = display::FieldsPerFrame::kInterlaced,
.hsync_polarity = display::SyncPolarity::kPositive,
.vsync_polarity = display::SyncPolarity::kNegative,
.vblank_alternates = true,
.pixel_repetition = 0,
};
constexpr timing_params_t kEdidTimingParams = {
.pixel_freq_khz = 0x1f'1f'1f,
.horizontal_addressable = 0x0f'0f,
.horizontal_front_porch = 0x0a'0a,
.horizontal_sync_pulse = 0x01'01,
.horizontal_blanking = 0x0d'0d,
.vertical_addressable = 0x0b'0b,
.vertical_front_porch = 0x03'03,
.vertical_sync_pulse = 0x04'04,
.vertical_blanking = 0x0c'0c,
.flags = timing_params_t::kInterlaced | timing_params_t::kPositiveHsync |
timing_params_t::kAlternatingVblank,
// Calculated from the values above:
// Htotal = Hactive + Hblank = 0x1c'1c,
// Vtotal = Vactive + Vblank * 2 + 1 = 0x23'24
// Field refresh rate = Pixel Freq (Hz) / (Htotal * Vtotal) = 63.0131 Hz
.vertical_refresh_e2 = 63'01,
};
const display::DisplayTiming display_timing = ToDisplayTiming(kEdidTimingParams);
EXPECT_EQ(kExpected, display_timing);
const int vertical_refresh_rate_centihertz =
(display_timing.vertical_field_refresh_rate_millihertz() + 5) / 10;
EXPECT_EQ(vertical_refresh_rate_centihertz,
static_cast<int>(kEdidTimingParams.vertical_refresh_e2));
}
{
constexpr display::DisplayTiming kExpected = {
.horizontal_active_px = 0x0f'0f,
.horizontal_front_porch_px = 0x0a'0a,
.horizontal_sync_width_px = 0x01'01,
.horizontal_back_porch_px = 0x02'02,
.vertical_active_lines = 0x0b'0b,
.vertical_front_porch_lines = 0x03'03,
.vertical_sync_width_lines = 0x04'04,
.vertical_back_porch_lines = 0x05'05,
.pixel_clock_frequency_khz = 0x1f'1f'1f,
.fields_per_frame = display::FieldsPerFrame::kInterlaced,
.hsync_polarity = display::SyncPolarity::kNegative,
.vsync_polarity = display::SyncPolarity::kPositive,
.vblank_alternates = true,
.pixel_repetition = 0,
};
constexpr edid::timing_params_t kEdidTimingParams = {
.pixel_freq_khz = 0x1f'1f'1f,
.horizontal_addressable = 0x0f'0f,
.horizontal_front_porch = 0x0a'0a,
.horizontal_sync_pulse = 0x01'01,
.horizontal_blanking = 0x0d'0d,
.vertical_addressable = 0x0b'0b,
.vertical_front_porch = 0x03'03,
.vertical_sync_pulse = 0x04'04,
.vertical_blanking = 0x0c'0c,
.flags = timing_params_t::kInterlaced | timing_params_t::kPositiveVsync |
timing_params_t::kAlternatingVblank,
// Calculated from the values above:
// Htotal = Hactive + Hblank = 0x1c'1c,
// Vtotal = Vactive + Vblank * 2 + 1 = 0x23'24
// Field refresh rate = Pixel Freq (Hz) / (Htotal * Vtotal) = 63.0131 Hz
.vertical_refresh_e2 = 63'01,
};
const display::DisplayTiming display_timing = ToDisplayTiming(kEdidTimingParams);
EXPECT_EQ(kExpected, display_timing);
const int vertical_refresh_rate_centihertz =
(display_timing.vertical_field_refresh_rate_millihertz() + 5) / 10;
EXPECT_EQ(vertical_refresh_rate_centihertz,
static_cast<int>(kEdidTimingParams.vertical_refresh_e2));
}
}
} // namespace
} // namespace edid