intel_extreme: Improve accelerant tracing and debug output

* Several messages to syslog weren't tagged with
  intel_extreme making troubleshooting difficult
* Fix a few typesize printf issues with B_PRI macro
This commit is contained in:
Alexander von Gluck IV
2012-12-28 19:01:05 +00:00
parent 783039344d
commit 881a823e8a
6 changed files with 111 additions and 92 deletions
@@ -12,6 +12,7 @@
#include "utility.h"
#include <Debug.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -21,14 +22,17 @@
#include <AGP.h>
#undef TRACE
#define TRACE_ACCELERANT
#ifdef TRACE_ACCELERANT
extern "C" void _sPrintf(const char* format, ...);
# define TRACE(x) _sPrintf x
# define TRACE(x...) _sPrintf("intel_extreme accelerant:" x)
#else
# define TRACE(x) ;
# define TRACE(x...)
#endif
#define ERROR(x...) _sPrintf("intel_extreme accelerant: " x)
#define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
struct accelerant_info* gInfo;
@@ -180,7 +184,7 @@ uninit_common(void)
status_t
intel_init_accelerant(int device)
{
TRACE(("intel_init_accelerant()\n"));
CALLED();
status_t status = init_common(device, false);
if (status != B_OK)
@@ -216,11 +220,12 @@ intel_init_accelerant(int device)
gInfo->head_mode |= HEAD_MODE_LVDS_PANEL;
}
TRACE(("head detected: %#x\n", gInfo->head_mode));
TRACE(("adpa: %08lx, dova: %08lx, dovb: %08lx, lvds: %08lx\n",
TRACE("head detected: %#x\n", gInfo->head_mode);
TRACE("adpa: %08lx, dova: %08lx, dovb: %08lx, lvds: %08lx\n",
read32(INTEL_DISPLAY_A_ANALOG_PORT),
read32(INTEL_DISPLAY_A_DIGITAL_PORT),
read32(INTEL_DISPLAY_B_DIGITAL_PORT), read32(INTEL_DISPLAY_LVDS_PORT)));
read32(INTEL_DISPLAY_B_DIGITAL_PORT),
read32(INTEL_DISPLAY_LVDS_PORT));
status = create_mode_list();
if (status != B_OK) {
@@ -235,7 +240,7 @@ intel_init_accelerant(int device)
ssize_t
intel_accelerant_clone_info_size(void)
{
TRACE(("intel_accelerant_clone_info_size()\n"));
CALLED();
// clone info is device name, so return its maximum size
return B_PATH_NAME_LENGTH;
}
@@ -244,7 +249,7 @@ intel_accelerant_clone_info_size(void)
void
intel_get_accelerant_clone_info(void* info)
{
TRACE(("intel_get_accelerant_clone_info()\n"));
CALLED();
ioctl(gInfo->device, INTEL_GET_DEVICE_NAME, info, B_PATH_NAME_LENGTH);
}
@@ -252,7 +257,7 @@ intel_get_accelerant_clone_info(void* info)
status_t
intel_clone_accelerant(void* info)
{
TRACE(("intel_clone_accelerant()\n"));
CALLED();
// create full device name
char path[B_PATH_NAME_LENGTH];
@@ -294,7 +299,7 @@ err1:
void
intel_uninit_accelerant(void)
{
TRACE(("intel_uninit_accelerant()\n"));
CALLED();
// delete accelerant instance data
delete_area(gInfo->mode_list_area);
@@ -314,7 +319,7 @@ intel_uninit_accelerant(void)
status_t
intel_get_accelerant_device_info(accelerant_device_info* info)
{
TRACE(("intel_get_accelerant_device_info()\n"));
CALLED();
info->version = B_ACCELERANT_VERSION;
strcpy(info->name, gInfo->shared_info->device_type.InFamily(INTEL_TYPE_7xx)
@@ -332,7 +337,7 @@ intel_get_accelerant_device_info(accelerant_device_info* info)
sem_id
intel_accelerant_retrace_semaphore()
{
TRACE(("intel_accelerant_retrace_semaphore()\n"));
CALLED();
return gInfo->shared_info->vblank_sem;
}
@@ -11,14 +11,17 @@
#include "accelerant.h"
#undef TRACE
//#define TRACE_DPMS
#ifdef TRACE_DPMS
extern "C" void _sPrintf(const char* format, ...);
# define TRACE(x) _sPrintf x
# define TRACE(x...) _sPrintf("intel_extreme accelerant:" x)
#else
# define TRACE(x) ;
# define TRACE(x...)
#endif
#define ERROR(x...) _sPrintf("intel_extreme accelerant: " x)
#define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
void
enable_display_plane(bool enable)
@@ -231,7 +234,7 @@ set_display_power_mode(uint32 mode)
uint32
intel_dpms_capabilities(void)
{
TRACE(("intel_dpms_capabilities()\n"));
CALLED();
return B_DPMS_ON | B_DPMS_SUSPEND | B_DPMS_STAND_BY | B_DPMS_OFF;
}
@@ -239,7 +242,7 @@ intel_dpms_capabilities(void)
uint32
intel_dpms_mode(void)
{
TRACE(("intel_dpms_mode()\n"));
CALLED();
return gInfo->shared_info->dpms_mode;
}
@@ -247,7 +250,7 @@ intel_dpms_mode(void)
status_t
intel_set_dpms_mode(uint32 mode)
{
TRACE(("intel_set_dpms_mode()\n"));
CALLED();
gInfo->shared_info->dpms_mode = mode;
set_display_power_mode(mode);
@@ -15,14 +15,16 @@
#undef TRACE
//#define TRACE_ENGINE
#ifdef TRACE_ENGINE
# define TRACE(x) _sPrintf x
# define TRACE(x...) _sPrintf("intel_extreme accelerant:" x)
#else
# define TRACE(x) ;
# define TRACE(x...)
#endif
#define ERROR(x...) _sPrintf("intel_extreme accelerant: " x)
#define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
static engine_token sEngineToken = {1, 0 /*B_2D_ACCELERATION*/, NULL};
@@ -127,7 +129,7 @@ QueueCommands::MakeSpace(uint32 size)
if (fRingBuffer.space_left < size) {
if (system_time() > start + 1000000LL) {
TRACE(("intel_extreme: engine stalled, head %lx\n", head));
ERROR("engine stalled, head %lx\n", head);
break;
}
spin(10);
@@ -163,8 +165,8 @@ uninit_ring_buffer(ring_buffer &ringBuffer)
void
setup_ring_buffer(ring_buffer &ringBuffer, const char* name)
{
TRACE(("Setup ring buffer %s, offset %lx, size %lx\n", name,
ringBuffer.offset, ringBuffer.size));
TRACE("Setup ring buffer %s, offset %lx, size %lx\n", name,
ringBuffer.offset, ringBuffer.size);
if (init_lock(&ringBuffer.lock, name) < B_OK) {
// disable ring buffer
@@ -191,7 +193,7 @@ setup_ring_buffer(ring_buffer &ringBuffer, const char* name)
uint32
intel_accelerant_engine_count(void)
{
TRACE(("intel_accelerant_engine_count()\n"));
CALLED();
return 1;
}
@@ -200,7 +202,7 @@ status_t
intel_acquire_engine(uint32 capabilities, uint32 maxWait, sync_token* syncToken,
engine_token** _engineToken)
{
TRACE(("intel_acquire_engine()\n"));
CALLED();
*_engineToken = &sEngineToken;
if (acquire_lock(&gInfo->shared_info->engine_lock) != B_OK)
@@ -216,7 +218,7 @@ intel_acquire_engine(uint32 capabilities, uint32 maxWait, sync_token* syncToken,
status_t
intel_release_engine(engine_token* engineToken, sync_token* syncToken)
{
TRACE(("intel_release_engine()\n"));
CALLED();
if (syncToken != NULL)
syncToken->engine_id = engineToken->engine_id;
@@ -228,7 +230,7 @@ intel_release_engine(engine_token* engineToken, sync_token* syncToken)
void
intel_wait_engine_idle(void)
{
TRACE(("intel_wait_engine_idle()\n"));
CALLED();
{
QueueCommands queue(gInfo->shared_info->primary_ring_buffer);
@@ -254,7 +256,7 @@ intel_wait_engine_idle(void)
if (system_time() > start + 1000000LL) {
// the engine seems to be locked up!
TRACE(("intel_extreme: engine locked up, head %lx!\n", head));
ERROR("engine locked up, head %lx!\n", head);
break;
}
@@ -266,7 +268,7 @@ intel_wait_engine_idle(void)
status_t
intel_get_sync_token(engine_token* engineToken, sync_token* syncToken)
{
TRACE(("intel_get_sync_token()\n"));
CALLED();
return B_OK;
}
@@ -274,7 +276,7 @@ intel_get_sync_token(engine_token* engineToken, sync_token* syncToken)
status_t
intel_sync_to_token(sync_token* syncToken)
{
TRACE(("intel_sync_to_token()\n"));
CALLED();
intel_wait_engine_idle();
return B_OK;
}
@@ -14,14 +14,17 @@
#include <unistd.h>
#undef TRACE
//#define TRACE_MEMORY
#ifdef TRACE_MEMORY
extern "C" void _sPrintf(const char* format, ...);
# define TRACE(x) _sPrintf x
# define TRACE(x...) _sPrintf("intel_extreme accelerant:" x)
#else
# define TRACE(x) ;
# define TRACE(x...)
#endif
#define ERROR(x...) _sPrintf("intel_extreme accelerant: " x)
#define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
void
intel_free_memory(uint32 base)
+35 -32
View File
@@ -14,6 +14,7 @@
#include "accelerant.h"
#include "utility.h"
#include <Debug.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
@@ -24,14 +25,17 @@
#include <validate_display_mode.h>
#undef TRACE
#define TRACE_MODE
#ifdef TRACE_MODE
extern "C" void _sPrintf(const char* format, ...);
# define TRACE(x) _sPrintf x
# define TRACE(x...) _sPrintf("intel_extreme accelerant:" x)
#else
# define TRACE(x) ;
# define TRACE(x...)
#endif
#define ERROR(x...) _sPrintf("intel_extreme accelerant: " x)
#define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
struct display_registers {
uint32 pll;
@@ -171,16 +175,16 @@ create_mode_list(void)
edid_dump(&gInfo->edid_info);
gInfo->has_edid = true;
} else {
TRACE(("intel_extreme: getting EDID on port A (analog) failed : %s. "
"Trying on port C (lvds)\n", strerror(error)));
TRACE("getting EDID on port A (analog) failed : %s. "
"Trying on port C (lvds)\n", strerror(error));
bus.cookie = (void*)INTEL_I2C_IO_C;
error = ddc2_read_edid1(&bus, &gInfo->edid_info, NULL, NULL);
if (error == B_OK) {
edid_dump(&gInfo->edid_info);
gInfo->has_edid = true;
} else {
TRACE(("intel_extreme: getting EDID on port C failed : %s\n",
strerror(error)));
TRACE("getting EDID on port C failed : %s\n",
strerror(error));
// We could not read any EDID info. Fallback to creating a list with
// only the mode set up by the BIOS.
@@ -293,14 +297,14 @@ get_pll_limits(pll_limits &limits)
limits = kLimits;
}
TRACE(("PLL limits, min: p %lu (p1 %lu, p2 %lu), n %lu, m %lu "
TRACE("PLL limits, min: p %lu (p1 %lu, p2 %lu), n %lu, m %lu "
"(m1 %lu, m2 %lu)\n", limits.min.post, limits.min.post1,
limits.min.post2, limits.min.n, limits.min.m, limits.min.m1,
limits.min.m2));
TRACE(("PLL limits, max: p %lu (p1 %lu, p2 %lu), n %lu, m %lu "
limits.min.m2);
TRACE("PLL limits, max: p %lu (p1 %lu, p2 %lu), n %lu, m %lu "
"(m1 %lu, m2 %lu)\n", limits.max.post, limits.max.post1,
limits.max.post2, limits.max.n, limits.max.m, limits.max.m1,
limits.max.m2));
limits.max.m2);
}
@@ -331,7 +335,7 @@ compute_pll_divisors(const display_mode &current, pll_divisors& divisors,
pll_limits limits;
get_pll_limits(limits);
TRACE(("required MHz: %g\n", requestedPixelClock));
TRACE("%s: required MHz: %g\n", __func__, requestedPixelClock);
if (isLVDS) {
if ((read32(INTEL_DISPLAY_LVDS_PORT) & LVDS_CLKB_POWER_MASK)
@@ -386,11 +390,11 @@ compute_pll_divisors(const display_mode &current, pll_divisors& divisors,
divisors = bestDivisors;
TRACE(("found: %g MHz, p = %lu (p1 = %lu, p2 = %lu), n = %lu, m = %lu "
"(m1 = %lu, m2 = %lu)\n",
TRACE("%s: found: %g MHz, p = %lu (p1 = %lu, p2 = %lu), n = %lu, m = %lu "
"(m1 = %lu, m2 = %lu)\n", __func__,
((referenceClock * divisors.m) / divisors.n) / divisors.post,
divisors.post, divisors.post1, divisors.post2, divisors.n,
divisors.m, divisors.m1, divisors.m2));
divisors.m, divisors.m1, divisors.m2);
}
@@ -635,7 +639,7 @@ sanitize_display_mode(display_mode& mode)
uint32
intel_accelerant_mode_count(void)
{
TRACE(("intel_accelerant_mode_count()\n"));
CALLED();
return gInfo->shared_info->mode_count;
}
@@ -643,7 +647,7 @@ intel_accelerant_mode_count(void)
status_t
intel_get_mode_list(display_mode* modeList)
{
TRACE(("intel_get_mode_info()\n"));
CALLED();
memcpy(modeList, gInfo->mode_list,
gInfo->shared_info->mode_count * sizeof(display_mode));
return B_OK;
@@ -654,7 +658,7 @@ status_t
intel_propose_display_mode(display_mode* target, const display_mode* low,
const display_mode* high)
{
TRACE(("intel_propose_display_mode()\n"));
CALLED();
// first search for the specified mode in the list, if no mode is found
// try to fix the target mode in sanitize_display_mode
@@ -685,8 +689,8 @@ intel_propose_display_mode(display_mode* target, const display_mode* low,
status_t
intel_set_display_mode(display_mode* mode)
{
TRACE(("intel_set_display_mode(%ldx%ld)\n", mode->virtual_width,
mode->virtual_height));
TRACE("%s(%" B_PRIu16 "x%" B_PRIu16 ")\n", __func__,
mode->virtual_width, mode->virtual_height);
if (mode == NULL)
return B_BAD_VALUE;
@@ -697,7 +701,7 @@ intel_set_display_mode(display_mode* mode)
// centering, since the data from propose_display_mode will not actually be
// used as is in this case.
if (sanitize_display_mode(target)) {
TRACE(("intel_extreme: invalid mode set!\n"));
TRACE("%s: invalid mode set!\n", __func__);
return B_BAD_VALUE;
}
@@ -749,7 +753,7 @@ if (first) {
set_frame_buffer_base();
}
TRACE(("intel_extreme : Failed to allocate framebuffer !\n"));
TRACE("%s: Failed to allocate framebuffer !\n", __func__);
return B_NO_MEMORY;
}
@@ -785,8 +789,8 @@ if (first) {
break;
}
}
TRACE(("intel_extreme : hardware mode will actually be %dx%d\n",
hardwareTarget.virtual_width, hardwareTarget.virtual_height));
TRACE("%s: hardware mode will actually be %dx%d\n", __func__,
hardwareTarget.virtual_width, hardwareTarget.virtual_height);
if ((hardwareTarget.virtual_width <= target.virtual_width
&& hardwareTarget.virtual_height <= target.virtual_height
&& hardwareTarget.space <= target.space)
@@ -1149,7 +1153,7 @@ if (first) {
status_t
intel_get_display_mode(display_mode* _currentMode)
{
TRACE(("intel_get_display_mode()\n"));
CALLED();
retrieve_current_mode(*_currentMode, INTEL_DISPLAY_A_PLL);
return B_OK;
@@ -1159,7 +1163,7 @@ intel_get_display_mode(display_mode* _currentMode)
status_t
intel_get_edid_info(void* info, size_t size, uint32* _version)
{
TRACE(("intel_get_edid_info()\n"));
CALLED();
if (!gInfo->has_edid)
return B_ERROR;
@@ -1175,7 +1179,7 @@ intel_get_edid_info(void* info, size_t size, uint32* _version)
status_t
intel_get_frame_buffer_config(frame_buffer_config* config)
{
TRACE(("intel_get_frame_buffer_config()\n"));
CALLED();
uint32 offset = gInfo->shared_info->frame_buffer_offset;
@@ -1191,7 +1195,7 @@ intel_get_frame_buffer_config(frame_buffer_config* config)
status_t
intel_get_pixel_clock_limits(display_mode* mode, uint32* _low, uint32* _high)
{
TRACE(("intel_get_pixel_clock_limits()\n"));
CALLED();
if (_low != NULL) {
// lower limit of about 48Hz vertical refresh
@@ -1216,7 +1220,7 @@ intel_get_pixel_clock_limits(display_mode* mode, uint32* _low, uint32* _high)
status_t
intel_move_display(uint16 horizontalStart, uint16 verticalStart)
{
TRACE(("intel_move_display()\n"));
CALLED();
intel_shared_info &sharedInfo = *gInfo->shared_info;
Autolock locker(sharedInfo.accelerant_lock);
@@ -1239,7 +1243,7 @@ intel_move_display(uint16 horizontalStart, uint16 verticalStart)
status_t
intel_get_timing_constraints(display_timing_constraints* constraints)
{
TRACE(("intel_get_timing_contraints()\n"));
CALLED();
return B_ERROR;
}
@@ -1247,8 +1251,7 @@ intel_get_timing_constraints(display_timing_constraints* constraints)
void
intel_set_indexed_colors(uint count, uint8 first, uint8* colors, uint32 flags)
{
TRACE(("intel_set_indexed_colors(colors = %p, first = %u)\n", colors,
first));
TRACE("%s(colors = %p, first = %u)\n", __func__, colors, first);
if (colors == NULL)
return;
@@ -14,6 +14,7 @@
#include "accelerant_protos.h"
#include "commands.h"
#include <Debug.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -21,14 +22,17 @@
#include <AGP.h>
#undef TRACE
//#define TRACE_OVERLAY
#ifdef TRACE_OVERLAY
extern "C" void _sPrintf(const char* format, ...);
# define TRACE(x) _sPrintf x
# define TRACE(x...) _sPrintf("intel_extreme accelerant:" x)
#else
# define TRACE(x) ;
# define TRACE(x...)
#endif
#define ERROR(x...) _sPrintf("intel_extreme accelerant: " x)
#define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
#define NUM_HORIZONTAL_TAPS 5
#define NUM_VERTICAL_TAPS 3
@@ -243,11 +247,11 @@ update_overlay(bool updateCoefficients)
queue.PutWaitFor(COMMAND_WAIT_FOR_OVERLAY_FLIP);
queue.PutFlush();
TRACE(("update overlay: UP: %lx, TST: %lx, ST: %lx, CMD: %lx (%lx), "
"ERR: %lx\n", read32(INTEL_OVERLAY_UPDATE), read32(INtEL_OVERLAY_TEST),
read32(INTEL_OVERLAY_STATUS),
TRACE("%s: UP: %lx, TST: %lx, ST: %lx, CMD: %lx (%lx), ERR: %lx\n",
__func__, read32(INTEL_OVERLAY_UPDATE),
read32(INTEL_OVERLAY_TEST), read32(INTEL_OVERLAY_STATUS),
*(((uint32*)gInfo->overlay_registers) + 0x68/4), read32(0x30168),
read32(0x2024)));
read32(0x2024));
}
@@ -265,11 +269,11 @@ show_overlay(void)
queue.PutOverlayFlip(COMMAND_OVERLAY_ON, true);
queue.PutFlush();
TRACE(("show overlay: UP: %lx, TST: %lx, ST: %lx, CMD: %lx (%lx), "
"ERR: %lx\n", read32(INTEL_OVERLAY_UPDATE), read32(INTEL_OVERLAY_TEST),
read32(INTEL_OVERLAY_STATUS),
*(((uint32*)gInfo->overlay_registers) + 0x68/4), read32(0x30168),
read32(0x2024)));
TRACE("%s: UP: %lx, TST: %lx, ST: %lx, CMD: %lx (%lx), ERR: %lx\n",
__func__, read32(INTEL_OVERLAY_UPDATE),
read32(INTEL_OVERLAY_TEST), read32(INTEL_OVERLAY_STATUS),
*(((uint32*)gInfo->overlay_registers) + 0x68/4),
read32(0x30168), read32(0x2024));
}
@@ -344,8 +348,8 @@ const overlay_buffer*
intel_allocate_overlay_buffer(color_space colorSpace, uint16 width,
uint16 height)
{
TRACE(("intel_allocate_overlay_buffer(width %u, height %u, "
"colorSpace %lu)\n", width, height, colorSpace));
TRACE("%s(width %u, height %u, colorSpace %lu)\n", __func__, width,
height, colorSpace);
intel_shared_info &sharedInfo = *gInfo->shared_info;
uint32 bytesPerPixel;
@@ -412,9 +416,9 @@ intel_allocate_overlay_buffer(color_space colorSpace, uint16 width,
buffer->buffer_dma = (uint8*)gInfo->shared_info->physical_graphics_memory
+ overlay->buffer_offset;
TRACE(("allocated overlay buffer: base=%x, offset=%x, address=%x, "
"physical address=%x\n", overlay->buffer_base, overlay->buffer_offset,
buffer->buffer, buffer->buffer_dma));
TRACE("%s: base=%x, offset=%x, address=%x, physical address=%x\n",
__func__, overlay->buffer_base, overlay->buffer_offset,
buffer->buffer, buffer->buffer_dma);
return buffer;
}
@@ -423,7 +427,7 @@ intel_allocate_overlay_buffer(color_space colorSpace, uint16 width,
status_t
intel_release_overlay_buffer(const overlay_buffer* buffer)
{
TRACE(("intel_release_overlay_buffer(buffer %p)\n", buffer));
CALLED();
struct overlay* overlay = (struct overlay*)buffer;
@@ -445,7 +449,7 @@ status_t
intel_get_overlay_constraints(const display_mode* mode,
const overlay_buffer* buffer, overlay_constraints* constraints)
{
TRACE(("intel_get_overlay_constraints(buffer %p)\n", buffer));
CALLED();
// taken from the Radeon driver...
@@ -507,7 +511,7 @@ intel_get_overlay_constraints(const display_mode* mode,
overlay_token
intel_allocate_overlay(void)
{
TRACE(("intel_allocate_overlay()\n"));
CALLED();
// we only have a single overlay channel
if (atomic_or(&gInfo->shared_info->overlay_channel_used, 1) != 0)
@@ -520,7 +524,7 @@ intel_allocate_overlay(void)
status_t
intel_release_overlay(overlay_token overlayToken)
{
TRACE(("intel_allocate_overlay(token %ld)\n", (uint32)overlayToken));
CALLED();
// we only have a single token, which simplifies this
if (overlayToken != (overlay_token)gInfo->shared_info->overlay_token)
@@ -537,8 +541,7 @@ intel_configure_overlay(overlay_token overlayToken,
const overlay_buffer* buffer, const overlay_window* window,
const overlay_view* view)
{
TRACE(("intel_configure_overlay: buffer %p, window %p, view %p\n",
buffer, window, view));
CALLED();
if (overlayToken != (overlay_token)gInfo->shared_info->overlay_token)
return B_BAD_VALUE;
@@ -653,9 +656,9 @@ intel_configure_overlay(overlay_token overlayToken,
registers->vertical_scale_rgb = verticalScale >> 12;
registers->vertical_scale_uv = verticalScaleUV >> 12;
TRACE(("scale: h = %ld.%ld, v = %ld.%ld\n", horizontalScale >> 12,
TRACE("scale: h = %ld.%ld, v = %ld.%ld\n", horizontalScale >> 12,
horizontalScale & 0xfff, verticalScale >> 12,
verticalScale & 0xfff));
verticalScale & 0xfff);
if (verticalScale != gInfo->last_vertical_overlay_scale
|| horizontalScale != gInfo->last_horizontal_overlay_scale) {