Skip to content

Commit

Permalink
The video decoding thread efficiently waits for a video to be created…
Browse files Browse the repository at this point in the history
… before doing anything, rather than sleeping for 2ms in a loop. Reduces the CPU usage of the video worker thread to ~0% when no videos are loaded.
  • Loading branch information
slime73 committed Mar 6, 2016
1 parent 7370bd5 commit a0bbcce
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 38 deletions.
7 changes: 0 additions & 7 deletions src/modules/thread/Channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ Channel::Channel()
, sent(0)
, received(0)
{
mutex = newMutex();
cond = newConditional();
}

Channel::Channel(const std::string &name)
Expand All @@ -87,15 +85,10 @@ Channel::Channel(const std::string &name)
, sent(0)
, received(0)
{
mutex = newMutex();
cond = newConditional();
}

Channel::~Channel()
{
delete mutex;
delete cond;

if (named)
{
Lock l(namedChannelMutex);
Expand Down
4 changes: 2 additions & 2 deletions src/modules/thread/Channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ friend int w_Channel_performAtomic(lua_State *);
void lockMutex();
void unlockMutex();

Mutex *mutex;
Conditional *cond;
MutexRef mutex;
ConditionalRef cond;
std::queue<Variant> queue;
bool named;
std::string name;
Expand Down
27 changes: 26 additions & 1 deletion src/modules/thread/threads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Lock::~Lock()
}

EmptyLock::EmptyLock()
: mutex(0)
: mutex(nullptr)
{
}

Expand Down Expand Up @@ -119,5 +119,30 @@ MutexRef::operator Mutex*() const
return mutex;
}

Mutex *MutexRef::operator->() const
{
return mutex;
}

ConditionalRef::ConditionalRef()
: conditional(newConditional())
{
}

ConditionalRef::~ConditionalRef()
{
delete conditional;
}

ConditionalRef::operator Conditional*() const
{
return conditional;
}

Conditional *ConditionalRef::operator->() const
{
return conditional;
}

} // thread
} // love
14 changes: 14 additions & 0 deletions src/modules/thread/threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,25 @@ class MutexRef
~MutexRef();

operator Mutex*() const;
Mutex *operator->() const;

private:
Mutex *mutex;
};

class ConditionalRef
{
public:
ConditionalRef();
~ConditionalRef();

operator Conditional*() const;
Conditional *operator->() const;

private:
Conditional *conditional;
};

Mutex *newMutex();
Conditional *newConditional();
Thread *newThread(Threadable *t);
Expand Down
7 changes: 1 addition & 6 deletions src/modules/timer/Timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ double Timer::getTimerPeriod()
return 0;
}

double Timer::getTimeSinceEpoch()
double Timer::getTime()
{
// The timer period (reciprocal of the frequency.)
static const double timerPeriod = getTimerPeriod();
Expand Down Expand Up @@ -145,10 +145,5 @@ double Timer::getTimeSinceEpoch()
#endif
}

double Timer::getTime() const
{
return getTimeSinceEpoch();
}

} // timer
} // love
3 changes: 1 addition & 2 deletions src/modules/timer/Timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ class Timer : public Module
* and increases monotonically.
* @return The time (in seconds)
**/
virtual double getTime() const;
static double getTimeSinceEpoch();
static double getTime();

private:

Expand Down
45 changes: 26 additions & 19 deletions src/modules/video/theora/Video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,48 +71,55 @@ void Worker::addStream(VideoStream *stream)
{
love::thread::Lock l(mutex);
streams.push_back(stream);
cond->broadcast();
}

void Worker::stop()
{
{
love::thread::Lock l(mutex);
stopping = true;
cond->broadcast();
}

owner->wait();
}

void Worker::threadFunction()
{
double lastFrame = love::timer::Timer::getTimeSinceEpoch();
double lastFrame = love::timer::Timer::getTime();

while (true)
{
double curFrame = love::timer::Timer::getTimeSinceEpoch();
double dt = curFrame-lastFrame;
lastFrame = curFrame;
love::sleep(2);

love::thread::Lock l(mutex);

while (!stopping && streams.empty())
{
love::thread::Lock l(mutex);
cond->wait(mutex);
lastFrame = love::timer::Timer::getTime();
}

if (stopping)
return;
if (stopping)
return;

for (auto it = streams.begin(); it != streams.end(); ++it)
double curFrame = love::timer::Timer::getTime();
double dt = curFrame-lastFrame;
lastFrame = curFrame;

for (auto it = streams.begin(); it != streams.end(); ++it)
{
VideoStream *stream = *it;
if (stream->getReferenceCount() == 1)
{
VideoStream *stream = *it;
if (stream->getReferenceCount() == 1)
{
// We're the only ones left
streams.erase(it);
break;
}

stream->threadedFillBackBuffer(dt);
// We're the only ones left
streams.erase(it);
break;
}
}

love::sleep(2);
stream->threadedFillBackBuffer(dt);
}
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/modules/video/theora/Video.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,13 @@ class Worker : public love::thread::Threadable
void stop();

private:

std::vector<StrongRef<VideoStream>> streams;

love::thread::MutexRef mutex;
love::thread::ConditionalRef cond;

volatile bool stopping;
bool stopping;
}; // Worker

} // theora
Expand Down

0 comments on commit a0bbcce

Please sign in to comment.