/*
Jpcsp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jpcsp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.graphics.RE.software;
import static jpcsp.util.Utilities.sleep;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import jpcsp.graphics.VideoEngine;
/**
* @author gid15
*
*/
public class RendererExecutor {
private static final int numberThreads = 1;
private static RendererExecutor instance;
private final LinkedBlockingQueue<IRenderer> renderersQueue = new LinkedBlockingQueue<IRenderer>();
private volatile boolean ended;
private volatile int numberThreadsRendering;
private final Object numberThreadsRenderingLock = new Object();
public static RendererExecutor getInstance() {
if (instance == null) {
instance = new RendererExecutor();
}
return instance;
}
private RendererExecutor() {
for (int i = 0; i < numberThreads; i++) {
Thread thread = new ThreadRenderer();
thread.setName(String.format("Thread SoftwareRenderer #%d", i + 1));
thread.setDaemon(true);
thread.start();
}
}
public static void exit() {
if (instance != null) {
instance.ended = true;
}
}
public void render(IRenderer renderer) {
if (numberThreads > 0 && !VideoEngine.log.isTraceEnabled()) {
// Queue for rendering in a ThreadRenderer thread
renderer = renderer.duplicate();
renderersQueue.add(renderer);
} else {
// Threads are disabled or capture is active, render immediately
try {
renderer.render();
} catch (Exception e) {
VideoEngine.log.error("Error while rendering", e);
}
}
}
public void waitForRenderingCompletion() {
if (numberThreads > 0) {
while (!renderersQueue.isEmpty() || numberThreadsRendering > 0) {
sleep(1, 0);
}
}
}
private class ThreadRenderer extends Thread {
@Override
public void run() {
while (!ended) {
IRenderer renderer = null;
try {
renderer = renderersQueue.poll(100, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// Ignore Exception
}
if (renderer != null) {
synchronized (numberThreadsRenderingLock) {
numberThreadsRendering++;
}
try {
renderer.render();
} catch (Exception e) {
VideoEngine.log.error("Error while rendering", e);
}
synchronized (numberThreadsRenderingLock) {
numberThreadsRendering--;
}
}
}
}
}
}