Skip to content

Commit

Permalink
Libretro: We don't need a separate surface to render
Browse files Browse the repository at this point in the history
Yet another round of lowering FreeJ2ME's libretro overhead.

Turns out that instead of drawing to a separate 3BYTE_BGR surface,
it's faster to just get the current MobilePlatform's "LCD" and
poll data from it directly from either INT_RGB or INT_ARGB then
convert it to a byte array with WritableRaster before sending to
libretro's core. This had the effect of removing any need for a
graphics object in Libretro.java as well, which then made the
custom Runnable useless as well, so all of that was cleaned up.

No color conversions are done on the core itself now, it's back
to converting in the Java side of things again, in a very similar
way to how it was done originally. Except this time the overhead
is so low that it might as well be considered on par with FreeJ2ME's
standalone AWT jar, which is the fastest available.

Anbu also got part of its comment about DataBuffer removed, as it
doesn't really differ from Libretro anymore.
  • Loading branch information
AShiningRay committed Nov 10, 2024
1 parent e5befdd commit 5b5ddef
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 38 deletions.
4 changes: 2 additions & 2 deletions src/libretro/freej2me_libretro.c
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ void retro_run(void)
t = 0;
for(i=0; i<frameSize; i++)
{
frame[i] = (frameBuffer[t]) | (frameBuffer[t+1]<<8) | (frameBuffer[t+2]<<16);
frame[i] = (frameBuffer[t]<<16) | (frameBuffer[t+1]<<8) | (frameBuffer[t+2]);
t+=3;
}
}
Expand All @@ -945,7 +945,7 @@ void retro_run(void)
{
for(i=frameHeight-1; i>=0; i--)
{
frame[(i*frameWidth)+j] = (frameBuffer[t]) | (frameBuffer[t+1]<<8) | (frameBuffer[t+2]<<16);
frame[(i*frameWidth)+j] = (frameBuffer[t]<<16) | (frameBuffer[t+1]<<8) | (frameBuffer[t+2]);
t+=3;
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/org/recompile/freej2me/Anbu.java
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,7 @@ public void paint()

/*
* Like on libretro, access the image's DataBuffer directly instead of using BufferedImage's getRGB() method,
* which is slower. The only difference is that here the data has to be saved as Integers instead of Bytes,
* since the image we copy from is from TYPE_INT_ARGB, and not TYPE_3BYTE_BGR.
* which is slower.
*/
final int[] data = ((DataBufferInt) Mobile.getPlatform().getLCD().getRaster().getDataBuffer()).getData();
pixels.write(0, data, 0, data.length);
Expand Down
50 changes: 16 additions & 34 deletions src/org/recompile/freej2me/Libretro.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,7 @@

import org.recompile.mobile.*;

import java.awt.Image;
import java.awt.Canvas;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;

import java.awt.image.DataBufferInt;
import java.util.Timer;
import java.util.TimerTask;

Expand All @@ -39,11 +34,6 @@ public class Libretro
private int lcdWidth;
private int lcdHeight;

private Runnable painter;

private BufferedImage surface;
private Graphics2D gc;

private Config config;
private boolean rotateDisplay = false;
private boolean soundEnabled = true;
Expand Down Expand Up @@ -147,9 +137,6 @@ public Libretro(String args[])

/* Once it finishes parsing all arguments, it's time to set up freej2me-lr */

surface = new BufferedImage(lcdWidth, lcdHeight, BufferedImage.TYPE_3BYTE_BGR); // libretro display
gc = (Graphics2D)surface.getGraphics();

Mobile.setPlatform(new MobilePlatform(lcdWidth, lcdHeight));

config = new Config();
Expand All @@ -158,18 +145,7 @@ public Libretro(String args[])
lio = new LibretroIO();

lio.start();

painter = new Runnable()
{
public void run()
{
try { gc.drawImage(Mobile.getPlatform().getLCD(), 0, 0, lcdWidth, lcdHeight, null); }
catch (Exception e) { }
}
};

Mobile.getPlatform().setPainter(painter);

Mobile.getPlatform().startEventQueue();

System.out.println("+READY");
Expand Down Expand Up @@ -222,11 +198,11 @@ public void run()
code = (din[1]<<24) | (din[2]<<16) | (din[3]<<8) | din[4];
switch(din[0])
{
case 0: // keyboard key up (unused)
break;
//case 0: // keyboard key up (unused)
//break;

case 1: // keyboard key down (unused)
break;
//case 1: // keyboard key down (unused)
//break;

case 2: // joypad key up
mobikey = getMobileKeyJoy(code);
Expand Down Expand Up @@ -419,13 +395,21 @@ public void run()
/* Vibration duration should be set to zero to prevent constant sends of the same data, so update it here*/
Mobile.vibrationDuration = 0;

frameBuffer = ((DataBufferByte) surface.getRaster().getDataBuffer()).getData();
System.out.write(frameBuffer, 0, frameBuffer.length);
final int[] data = ((DataBufferInt) Mobile.getPlatform().getLCD().getRaster().getDataBuffer()).getData();

for(int i=0; i<data.length; i++)
{
frameBuffer[3*i] = (byte)((data[i]>>16)&0xFF);
frameBuffer[3*i+1] = (byte)((data[i]>>8)&0xFF);
frameBuffer[3*i+2] = (byte)((data[i])&0xFF);
}

System.out.write(frameBuffer, 0, data.length*3);
System.out.flush();
}
catch (Exception e)
{
System.out.print("Error sending frame: "+e.getMessage());
Mobile.log(Mobile.LOG_DEBUG, Libretro.class.getPackage().getName() + "." + Libretro.class.getSimpleName() + ": " + "Error sending frame: "+e.getMessage());
System.exit(0);
}
break;
Expand Down Expand Up @@ -486,8 +470,6 @@ private void settingsChanged()
lcdWidth = w;
lcdHeight = h;
Mobile.getPlatform().resizeLCD(w, h);
surface = new BufferedImage(lcdWidth, lcdHeight, BufferedImage.TYPE_3BYTE_BGR); // libretro display
gc = (Graphics2D)surface.getGraphics();
}
}

Expand Down

0 comments on commit 5b5ddef

Please sign in to comment.