From e23e062be98dc1db55d52aca4c60f797a66e3f46 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 20 Feb 2021 18:16:54 +0100 Subject: [PATCH] Some fixes and attempts to fix the screen --- .../java/sznp/virtualcomputer/Computer.java | 37 +++++++++++++------ .../java/sznp/virtualcomputer/PluginMain.java | 2 +- .../virtualcomputer/renderer/GPURenderer.java | 1 + .../renderer/MCFrameBuffer.java | 29 +++++++++++---- 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/Computer.java b/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/Computer.java index e1d3d8b..542a24f 100644 --- a/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/Computer.java +++ b/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/Computer.java @@ -66,8 +66,10 @@ public final class Computer { synchronized (session) { if (plugin.runEmbedded.get()) machine.lockMachine(session, LockType.VM); //Run in our process <-- Need the VM type to have console access - else - machine.launchVMProcess(session, "headless", Collections.emptyList()); //Run in a separate process + else { + val progress = machine.launchVMProcess(session, "headless", Collections.emptyList()); //Run in a separate process + onStartSetProgress(progress, sender); + } } } catch (VBoxException e) { if (e.getResultCode() == 0x80070005) { //lockMachine: "The object functionality is limited" @@ -100,22 +102,35 @@ public final class Computer { * @param sender The sender which started the machine */ public void onLock(CommandSender sender) { + System.out.println("A"); machine = session.getMachine(); // This is the Machine object we can work with final IConsole console = session.getConsole(); + if (plugin.runEmbedded.get()) { //Otherwise it's set while starting the VM + IProgress progress = console.powerUp(); // https://marc.info/?l=vbox-dev&m=142780789819967&w=2 + onStartSetProgress(progress, sender); + } + System.out.println("B"); + System.out.println("State: " + console.getState()); + listener = handler.registerTo(console.getEventSource()); + System.out.println("State: " + console.getState()); + val fb = new MCFrameBuffer(console.getDisplay(), plugin, direct); + System.out.println("C"); + if (plugin.runEmbedded.get()) + fb.startEmbedded(); + String fbid = console.getDisplay().attachFramebuffer(0L, + COMUtils.gimmeAFramebuffer(fb)); + System.out.println("State: " + console.getState()); + System.out.println("D"); //TODO: No UpdateImage + fb.setId(fbid); + framebuffer = fb; + } + + private void onStartSetProgress(IProgress progress, CommandSender sender) { if (handler != null) handler.disable(); handler = new MachineEventHandler(Computer.this, sender); - listener = handler.registerTo(console.getEventSource()); - IProgress progress = console.powerUp(); // https://marc.info/?l=vbox-dev&m=142780789819967&w=2 handler.setProgress(progress); handler.registerTo(progress.getEventSource()); //TODO: Show progress bar some way? - val fb = new MCFrameBuffer(console.getDisplay(), plugin, direct); - if (plugin.runEmbedded.get()) - fb.start(); - String fbid = console.getDisplay().attachFramebuffer(0L, - COMUtils.gimmeAFramebuffer(fb)); - fb.setId(fbid); - framebuffer = fb; } private void sendMessage(@Nullable CommandSender sender, String message) { diff --git a/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/PluginMain.java b/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/PluginMain.java index 6893885..80ca547 100644 --- a/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/PluginMain.java +++ b/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/PluginMain.java @@ -109,7 +109,7 @@ public class PluginMain extends ButtonPlugin { System.setProperty("java.library.path", vbpath); Utils.addLibraryPath(vbpath); //TODO: Jacob DLL must be in the server folder final VirtualBoxManager manager = VirtualBoxManager.createInstance(getDataFolder().getAbsolutePath()); - if (!windows) { + if (!windows && runEmbedded.get()) { VBoxLib vbl = LibraryLoader.create(VBoxLib.class).load("vboxjxpcom"); vbl.RTR3InitExe(0, "", 0); } diff --git a/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/renderer/GPURenderer.java b/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/renderer/GPURenderer.java index b9a2779..ef4d81b 100644 --- a/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/renderer/GPURenderer.java +++ b/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/renderer/GPURenderer.java @@ -71,6 +71,7 @@ public class GPURenderer extends MapRenderer implements IRenderer { renderers.add(this); map.addRenderer(this); + enabled = true; //Enable at each plugin (re)enable } @Override diff --git a/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/renderer/MCFrameBuffer.java b/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/renderer/MCFrameBuffer.java index 3b599d1..dcdb3de 100644 --- a/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/renderer/MCFrameBuffer.java +++ b/VirtualComputer-Core/src/main/java/sznp/virtualcomputer/renderer/MCFrameBuffer.java @@ -25,7 +25,13 @@ public class MCFrameBuffer implements IMCFrameBuffer { private final Holder holder = new Holder<>(); private final Logger logger; private final PluginMain plugin; + /** + * Whether the VM is running inside the server + */ private final boolean embedded; + /** + * Whether the GPU is being used to render + */ private final boolean direct; private BukkitTask tt; /** @@ -103,9 +109,7 @@ public class MCFrameBuffer implements IMCFrameBuffer { @Override public void notifyUpdate(long x, long y, long width, long height) { - /*if (this.width > 1024 || this.height > 768) - return;*/ - if (!direct || shouldUpdate.get()) + if (shouldUpdate.get()) return; //Don't wait for lock, ignore update since we're updating everything anyway - TODO: Not always synchronized (this) { shouldUpdate.set(true); @@ -129,9 +133,7 @@ public class MCFrameBuffer implements IMCFrameBuffer { updateScreen((int) x, (int) y, (int) width, (int) height); } - public void start() { - if (!direct) - return; + public void startEmbedded() { running = true; Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { try { @@ -140,7 +142,7 @@ public class MCFrameBuffer implements IMCFrameBuffer { while (!shouldUpdate.get()) wait(1000); if (pointer == null) { - System.out.println("Screen pointer is null"); + logger.warning("Embedded screen data pointer is null"); shouldUpdate.set(false); continue; } @@ -155,18 +157,29 @@ public class MCFrameBuffer implements IMCFrameBuffer { } private void updateScreenDirectInternal(byte[] pixels, int x, int y, int width, int height) { + if (pixels == null) { + logger.warning("Direct pixel data is null"); + return; + } Timing t = new Timing(); GPURenderer.update(pixels, this.width, this.height, x, y, width, height); if (t.elapsedMS() > 60) //Typically 1ms max - logger.warning("Update took " + t.elapsedMS() + "ms"); + logger.warning("Direct update took " + t.elapsedMS() + "ms"); } private void updateScreenIndirectInternal(ByteBuffer buffer, int x, int y, int width, int height) { + if (buffer == null) { + logger.warning("Indirect pixel buffer is null"); + return; + } if (this.width * this.height > 640 * 480) buffer.limit(640 * 480 * 4); else buffer.limit(this.width * this.height * 4); + Timing t = new Timing(); BukkitRenderer.update(buffer, x, y, width, height); + if (t.elapsedMS() > 60) + logger.warning("Indirect update took " + t.elapsedMS() + "ms"); } /**