Merge branch 'master' of https://github.com/neutrino-mp/neutrino-mp into ni/mp/tuxbox

Origin commit data
------------------
Branch: ni/coolstream
Commit: c5e829a1d4
Author: vanhofen <vanhofen@gmx.de>
Date: 2017-09-21 (Thu, 21 Sep 2017)


------------------
No further description and justification available within origin commit message!

------------------
This commit was generated by Migit
This commit is contained in:
vanhofen
2017-09-21 10:37:09 +02:00
2 changed files with 87 additions and 9 deletions

View File

@@ -42,6 +42,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <linux/stmfb.h> #include <linux/stmfb.h>
#include <bpamem.h> #include <bpamem.h>
@@ -59,6 +62,56 @@ static size_t lbb_sz = 1920 * 1080; /* offset from fb start in 'pixels' */
static size_t lbb_off = lbb_sz * sizeof(fb_pixel_t); /* same in bytes */ static size_t lbb_off = lbb_sz * sizeof(fb_pixel_t); /* same in bytes */
static int backbuf_sz = 0; static int backbuf_sz = 0;
static char lockfunc[256];
static pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
#if 1
#define mutex __invalid_mutex__
#define LOCK_WAIT_MS 5
#define NS_IN_SEC 1000000000LL
#define NS_IN_MS 1000000
#define TRYLOCK_RET(m) \
do { \
struct timespec wait; \
clock_gettime(CLOCK_REALTIME, &wait); \
wait.tv_nsec += (LOCK_WAIT_MS * NS_IN_MS); \
wait.tv_sec += wait.tv_nsec % NS_IN_SEC; \
wait.tv_nsec %= NS_IN_SEC; \
int status = pthread_mutex_timedlock(&mymutex, &wait); \
if (status) { \
printf(LOGTAG "::%s timedlock failed: %d (%s) locked: '%s'\n", __func__, \
status, strerror(status), lockfunc); \
return; \
} \
strcpy(lockfunc, __func__); \
} while(0)
#define UNLOCK(m) pthread_mutex_unlock(&mymutex)
#else
#define TRYLOCK_RET(m) \
do { \
time_t _start = time_monotonic_ms(); \
time_t _now = _start; \
while (true) { \
int status = m.trylock(); \
if (status == 0) \
break; \
_now = time_monotonic_ms(); \
usleep(1000); \
if (_now - _start < LOCK_WAIT_MS) \
continue; \
printf(LOGTAG "::%s trylock failed after %dms: %d (%s) locked '%s'\n", __func__, \
LOCK_WAIT_MS, status, (status > 0) ? strerror(status) : strerror(errno), \
lockfunc); \
return; \
} \
strcpy(lockfunc, __func__); \
} while(0)
#define UNLOCK(m) m.unlock()
#endif
void CFbAccelSTi::waitForIdle(const char *) void CFbAccelSTi::waitForIdle(const char *)
{ {
#if 0 /* blits too often and does not seem to be necessary */ #if 0 /* blits too often and does not seem to be necessary */
@@ -71,8 +124,10 @@ void CFbAccelSTi::waitForIdle(const char *)
} }
blit_mutex.unlock(); blit_mutex.unlock();
#endif #endif
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex); // OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
TRYLOCK_RET(mutex);
ioctl(fd, STMFBIO_SYNC_BLITTER); ioctl(fd, STMFBIO_SYNC_BLITTER);
UNLOCK(mutex);
} }
CFbAccelSTi::CFbAccelSTi() CFbAccelSTi::CFbAccelSTi()
@@ -271,10 +326,12 @@ void CFbAccelSTi::paintRect(const int x, const int y, const int dx, const int dy
bltData.colour = col; bltData.colour = col;
mark(xx, yy, bltData.dst_right, bltData.dst_bottom); mark(xx, yy, bltData.dst_right, bltData.dst_bottom);
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex); // OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
TRYLOCK_RET(mutex);
if (ioctl(fd, STMFBIO_BLT, &bltData ) < 0) if (ioctl(fd, STMFBIO_BLT, &bltData ) < 0)
fprintf(stderr, "blitRect FBIO_BLIT: %m x:%d y:%d w:%d h:%d s:%d\n", xx,yy,width,height,stride); fprintf(stderr, "blitRect FBIO_BLIT: %m x:%d y:%d w:%d h:%d s:%d\n", xx,yy,width,height,stride);
blit(); blit();
UNLOCK(mutex);
} }
void CFbAccelSTi::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool transp) void CFbAccelSTi::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool transp)
@@ -314,7 +371,8 @@ void CFbAccelSTi::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_
blt_data.dstMemSize = stride * yRes + lbb_off; blt_data.dstMemSize = stride * yRes + lbb_off;
mark(x, y, blt_data.dst_right, blt_data.dst_bottom); mark(x, y, blt_data.dst_right, blt_data.dst_bottom);
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex); // OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
TRYLOCK_RET(mutex);
ioctl(fd, STMFBIO_SYNC_BLITTER); ioctl(fd, STMFBIO_SYNC_BLITTER);
if (fbbuff != backbuffer) if (fbbuff != backbuffer)
memmove(backbuffer, fbbuff, mem_sz); memmove(backbuffer, fbbuff, mem_sz);
@@ -323,7 +381,7 @@ void CFbAccelSTi::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_
if (ioctl(fd, STMFBIO_BLT_EXTERN, &blt_data) < 0) if (ioctl(fd, STMFBIO_BLT_EXTERN, &blt_data) < 0)
perror(LOGTAG "blit2FB STMFBIO_BLT_EXTERN"); perror(LOGTAG "blit2FB STMFBIO_BLT_EXTERN");
return; UNLOCK(mutex);
} }
#define BLIT_INTERVAL_MIN 40 #define BLIT_INTERVAL_MIN 40
@@ -377,10 +435,13 @@ void CFbAccelSTi::_blit()
printf("%s %ld\n", __func__, now - last); printf("%s %ld\n", __func__, now - last);
last = now; last = now;
#endif #endif
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex); // OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
TRYLOCK_RET(mutex);
#ifdef PARTIAL_BLIT #ifdef PARTIAL_BLIT
if (to_blit.xs == INT_MAX) if (to_blit.xs == INT_MAX) {
UNLOCK(mutex);
return; return;
}
int srcXa = to_blit.xs; int srcXa = to_blit.xs;
int srcYa = to_blit.ys; int srcYa = to_blit.ys;
@@ -467,13 +528,15 @@ void CFbAccelSTi::_blit()
to_blit.xs = to_blit.ys = INT_MAX; to_blit.xs = to_blit.ys = INT_MAX;
to_blit.xe = to_blit.ye = 0; to_blit.xe = to_blit.ye = 0;
#endif #endif
UNLOCK(mutex);
} }
/* not really used yet */ /* not really used yet */
#ifdef PARTIAL_BLIT #ifdef PARTIAL_BLIT
void CFbAccelSTi::mark(int xs, int ys, int xe, int ye) void CFbAccelSTi::mark(int xs, int ys, int xe, int ye)
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex); // OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
TRYLOCK_RET(mutex);
if (xs < to_blit.xs) if (xs < to_blit.xs)
to_blit.xs = xs; to_blit.xs = xs;
if (ys < to_blit.ys) if (ys < to_blit.ys)
@@ -502,6 +565,7 @@ void CFbAccelSTi::mark(int xs, int ys, int xe, int ye)
*kill = 1; /* oh my */ *kill = 1; /* oh my */
} }
#endif #endif
UNLOCK(mutex);
} }
#else #else
void CFbAccelSTi::mark(int, int, int, int) void CFbAccelSTi::mark(int, int, int, int)

View File

@@ -75,6 +75,9 @@ static bool saved_orig_termio = false;
static bool input_stopped = false; static bool input_stopped = false;
static struct timespec devinput_mtime = { 0, 0 }; static struct timespec devinput_mtime = { 0, 0 };
static unsigned int _start_ms = 0;
static unsigned int _repeat_ms = 0;
#ifdef RCDEBUG #ifdef RCDEBUG
#define d_printf printf #define d_printf printf
#else #else
@@ -243,6 +246,7 @@ void CRCInput::open(bool recheck)
indev.push_back(id); indev.push_back(id);
} }
closedir(dir); closedir(dir);
setKeyRepeatDelay(0, 0);
id.path = "/tmp/neutrino.input"; id.path = "/tmp/neutrino.input";
if (! checkpath(id)) { if (! checkpath(id)) {
id.fd = ::open(id.path.c_str(), O_RDWR|O_NONBLOCK|O_CLOEXEC); id.fd = ::open(id.path.c_str(), O_RDWR|O_NONBLOCK|O_CLOEXEC);
@@ -1304,7 +1308,10 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
} }
} }
for (std::vector<in_dev>::iterator i = indev.begin(); i != indev.end(); ++i) { /* iterate backwards or the vector will be corrupted by the indev.erase(i) */
std::vector<in_dev>::iterator i = indev.end();
while (i != indev.begin()) {
--i;
if (((*i).fd != -1) && (FD_ISSET((*i).fd, &rfds))) { if (((*i).fd != -1) && (FD_ISSET((*i).fd, &rfds))) {
uint64_t now_pressed = 0; uint64_t now_pressed = 0;
t_input_event ev; t_input_event ev;
@@ -1316,7 +1323,7 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
if (errno == ENODEV) { if (errno == ENODEV) {
/* hot-unplugged? */ /* hot-unplugged? */
::close((*i).fd); ::close((*i).fd);
indev.erase(i); i = indev.erase(i);
} }
continue; continue;
} }
@@ -1740,6 +1747,13 @@ int CRCInput::translate(int code)
void CRCInput::setKeyRepeatDelay(unsigned int start_ms, unsigned int repeat_ms) void CRCInput::setKeyRepeatDelay(unsigned int start_ms, unsigned int repeat_ms)
{ {
if (start_ms == 0 && repeat_ms == 0) {
start_ms = _start_ms;
repeat_ms = _repeat_ms;
} else {
_start_ms = start_ms;
_repeat_ms = repeat_ms;
}
for (std::vector<in_dev>::iterator it = indev.begin(); it != indev.end(); ++it) { for (std::vector<in_dev>::iterator it = indev.begin(); it != indev.end(); ++it) {
int fd = (*it).fd; int fd = (*it).fd;
std::string path = (*it).path; std::string path = (*it).path;