in libs/screen---linux/screen.cpp [50:181]
void WDisplay::updateLoop() {
int cur_page = 1;
int frameNo = 0;
int numPages = vinfo.yres_virtual / vinfo.yres;
int ledScreen = getConfigInt("LED_SCREEN", 0);
int sx = vinfo.xres / width;
int sy = vinfo.yres / height;
if (ledScreen)
sx = ledScreen;
if (sx > sy)
sx = sy;
else
sy = sx;
if (sx > 1)
sx &= ~1;
int offx = (vinfo.xres - width * sx) / 2;
int offy = (vinfo.yres - height * sy) / 2;
if (ledScreen) {
offx = getConfigInt("LED_SCREEN_X", 0);
offy = getConfigInt("LED_SCREEN_Y", 0);
}
int screensize = finfo.line_length * vinfo.yres;
uint32_t skip = offx;
if (sx > 1)
offx &= ~1;
DMESG("sx=%d sy=%d ox=%d oy=%d 32=%d", sx, sy, offx, offy, is32Bit);
DMESG("fbuf=%p sz:%d", fbuf, screensize);
memset(fbuf, 0x00, screensize * numPages);
if (numPages == 1)
cur_page = 0;
dirty = true;
DMESG("loop");
for (;;) {
auto start0 = current_time_us();
while (!dirty)
sleep_core_us(2000);
// auto start = current_time_us();
// DMESG("update");
pthread_mutex_lock(&mutex);
dirty = false;
if (!is32Bit) {
uint16_t *dst =
(uint16_t *)fbuf + cur_page * screensize / 2 + offx + offy * finfo.line_length / 2;
if (sx == 1 && sy == 1) {
skip = vinfo.xres - width * sx;
for (int yy = 0; yy < height; yy++) {
auto shift = yy & 1 ? 4 : 0;
auto src = screenBuf + yy / 2;
for (int xx = 0; xx < width; ++xx) {
int c = this->currPalette[(*src >> shift) & 0xf];
src += height / 2;
*dst++ = c;
}
dst += skip;
}
} else {
uint32_t *d2 = (uint32_t *)dst;
for (int yy = 0; yy < height; yy++) {
auto shift = yy & 1 ? 4 : 0;
for (int i = 0; i < sy; ++i) {
auto src = screenBuf + yy / 2;
for (int xx = 0; xx < width; ++xx) {
int c = this->currPalette[(*src >> shift) & 0xf];
src += height / 2;
for (int j = 0; j < sx / 2; ++j)
*d2++ = c;
}
d2 += skip;
}
}
}
} else {
uint32_t *d2 =
(uint32_t *)fbuf + cur_page * screensize / 4 + offx + offy * finfo.line_length / 4;
skip = vinfo.xres - width * sx;
for (int yy = 0; yy < height; yy++) {
auto shift = yy & 1 ? 4 : 0;
for (int i = 0; i < sy; ++i) {
auto src = screenBuf + yy / 2;
for (int xx = 0; xx < width; ++xx) {
int c = this->currPalette[(*src >> shift) & 0xf];
src += height / 2;
for (int j = 0; j < sx; ++j)
*d2++ = c;
}
d2 += skip;
}
}
}
pthread_mutex_unlock(&mutex);
// auto len = current_time_us() - start;
painted = true;
raiseEvent(DEVICE_ID_NOTIFY_ONE, eventId);
vinfo.yoffset = cur_page * vinfo.yres;
ioctl(fb_fd, FBIOPAN_DISPLAY, &vinfo);
ioctl(fb_fd, FBIO_WAITFORVSYNC, 0);
if (numPages > 1)
cur_page = !cur_page;
frameNo++;
auto fulllen = current_time_us() - start0;
// throttle it to 40fps (really 30fps)
if (fulllen < 25000) {
ioctl(fb_fd, FBIO_WAITFORVSYNC, 0);
}
// auto tot = current_time_us() - start;
// if (frameNo % 37 == 0)
// DMESG("copy %d us, tot %d us delay %d us", (int)len, (int)tot, (int)(start-start0));
}
}