mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
The video decoding thread efficiently waits for a video to be created 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.
This commit is contained in:
@@ -77,8 +77,6 @@ Channel::Channel()
|
||||
, sent(0)
|
||||
, received(0)
|
||||
{
|
||||
mutex = newMutex();
|
||||
cond = newConditional();
|
||||
}
|
||||
|
||||
Channel::Channel(const std::string &name)
|
||||
@@ -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);
|
||||
|
||||
@@ -60,8 +60,8 @@ private:
|
||||
void lockMutex();
|
||||
void unlockMutex();
|
||||
|
||||
Mutex *mutex;
|
||||
Conditional *cond;
|
||||
MutexRef mutex;
|
||||
ConditionalRef cond;
|
||||
std::queue<Variant> queue;
|
||||
bool named;
|
||||
std::string name;
|
||||
|
||||
@@ -43,7 +43,7 @@ Lock::~Lock()
|
||||
}
|
||||
|
||||
EmptyLock::EmptyLock()
|
||||
: mutex(0)
|
||||
: mutex(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -103,11 +103,25 @@ public:
|
||||
~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);
|
||||
|
||||
@@ -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();
|
||||
@@ -145,10 +145,5 @@ double Timer::getTimeSinceEpoch()
|
||||
#endif
|
||||
}
|
||||
|
||||
double Timer::getTime() const
|
||||
{
|
||||
return getTimeSinceEpoch();
|
||||
}
|
||||
|
||||
} // timer
|
||||
} // love
|
||||
|
||||
@@ -76,8 +76,7 @@ public:
|
||||
* and increases monotonically.
|
||||
* @return The time (in seconds)
|
||||
**/
|
||||
virtual double getTime() const;
|
||||
static double getTimeSinceEpoch();
|
||||
static double getTime();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ void Worker::addStream(VideoStream *stream)
|
||||
{
|
||||
love::thread::Lock l(mutex);
|
||||
streams.push_back(stream);
|
||||
cond->broadcast();
|
||||
}
|
||||
|
||||
void Worker::stop()
|
||||
@@ -78,6 +79,7 @@ void Worker::stop()
|
||||
{
|
||||
love::thread::Lock l(mutex);
|
||||
stopping = true;
|
||||
cond->broadcast();
|
||||
}
|
||||
|
||||
owner->wait();
|
||||
@@ -85,34 +87,39 @@ void Worker::stop()
|
||||
|
||||
void Worker::threadFunction()
|
||||
{
|
||||
double lastFrame = love::timer::Timer::getTimeSinceEpoch();
|
||||
double lastFrame = love::timer::Timer::getTime();
|
||||
|
||||
while (true)
|
||||
{
|
||||
double curFrame = love::timer::Timer::getTimeSinceEpoch();
|
||||
love::sleep(2);
|
||||
|
||||
love::thread::Lock l(mutex);
|
||||
|
||||
while (!stopping && streams.empty())
|
||||
{
|
||||
cond->wait(mutex);
|
||||
lastFrame = love::timer::Timer::getTime();
|
||||
}
|
||||
|
||||
if (stopping)
|
||||
return;
|
||||
|
||||
double curFrame = love::timer::Timer::getTime();
|
||||
double dt = curFrame-lastFrame;
|
||||
lastFrame = curFrame;
|
||||
|
||||
for (auto it = streams.begin(); it != streams.end(); ++it)
|
||||
{
|
||||
love::thread::Lock l(mutex);
|
||||
|
||||
if (stopping)
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,10 +68,13 @@ public:
|
||||
void stop();
|
||||
|
||||
private:
|
||||
std::vector<StrongRef<VideoStream>> streams;
|
||||
love::thread::MutexRef mutex;
|
||||
|
||||
volatile bool stopping;
|
||||
std::vector<StrongRef<VideoStream>> streams;
|
||||
|
||||
love::thread::MutexRef mutex;
|
||||
love::thread::ConditionalRef cond;
|
||||
|
||||
bool stopping;
|
||||
}; // Worker
|
||||
|
||||
} // theora
|
||||
|
||||
Reference in New Issue
Block a user