From 85d1e7d71350a0df69cd2f478fe0d6c01f16a043 Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Wed, 13 Dec 2017 22:34:15 +0100 Subject: [PATCH] Updated JNI tests --- .cproject | 11 ++- MmapByteBuffer.java | 33 ++++++++ .../org/warp/picalculator/MmapByteBuffer.java | 34 ++++++++ .../java/org/warp/picalculator/TestJNI.java | 38 +++++---- .../graphicengine/framebuffer/FBEngine.java | 41 +++++----- src/main/jni/.gitignore | 1 + src/main/jni/CMakeLists.txt | 17 ++++ src/main/jni/TestJNI.c | 9 --- src/main/jni/TestJNI.cpp | 75 ++++++++++++++++++ src/main/jni/TestJNI.h | 12 ++- src/main/jni/TestJNI.o | Bin 884 -> 0 bytes src/main/jni/{makefile => makefileOLD} | 14 +++- src/main/resources/picalculatornative.dll | Bin 256696 -> 256696 bytes 13 files changed, 232 insertions(+), 53 deletions(-) create mode 100644 MmapByteBuffer.java create mode 100644 src/main/java/org/warp/picalculator/MmapByteBuffer.java create mode 100644 src/main/jni/.gitignore create mode 100644 src/main/jni/CMakeLists.txt delete mode 100644 src/main/jni/TestJNI.c create mode 100644 src/main/jni/TestJNI.cpp delete mode 100644 src/main/jni/TestJNI.o rename src/main/jni/{makefile => makefileOLD} (62%) diff --git a/.cproject b/.cproject index 3d5817da..54283f51 100644 --- a/.cproject +++ b/.cproject @@ -56,7 +56,6 @@ make - TestJNI.h true true @@ -64,7 +63,6 @@ make - all true true @@ -72,12 +70,19 @@ make - clean true true true + + make + + picalculatornative.dll + true + true + true + diff --git a/MmapByteBuffer.java b/MmapByteBuffer.java new file mode 100644 index 00000000..e2772a5a --- /dev/null +++ b/MmapByteBuffer.java @@ -0,0 +1,33 @@ +package org.warp.picalculator; + +import java.nio.ByteBuffer; + +public class MmapByteBuffer { + private int fd; + private int address; + private int length; + private ByteBuffer buffer; + + public MmapByteBuffer(int fd, int address, int length, ByteBuffer buffer) { + this.fd = fd; + this.address = address; + this.length = length; + this.buffer = buffer; + } + + public int getFd() { + return fd; + } + + public int getAddress() { + return address; + } + + public int getLength() { + return length; + } + + public ByteBuffer getBuffer() { + return buffer; + } +} \ No newline at end of file diff --git a/src/main/java/org/warp/picalculator/MmapByteBuffer.java b/src/main/java/org/warp/picalculator/MmapByteBuffer.java new file mode 100644 index 00000000..a12a5bf2 --- /dev/null +++ b/src/main/java/org/warp/picalculator/MmapByteBuffer.java @@ -0,0 +1,34 @@ +package org.warp.picalculator; + + +import java.nio.ByteBuffer; + +public class MmapByteBuffer { + private int fd; + private int address; + private int length; + private ByteBuffer buffer; + + public MmapByteBuffer(int fd, int address, int length, ByteBuffer buffer) { + this.fd = fd; + this.address = address; + this.length = length; + this.buffer = buffer; + } + + public int getFd() { + return fd; + } + + public int getAddress() { + return address; + } + + public int getLength() { + return length; + } + + public ByteBuffer getBuffer() { + return buffer; + } +} \ No newline at end of file diff --git a/src/main/java/org/warp/picalculator/TestJNI.java b/src/main/java/org/warp/picalculator/TestJNI.java index d2853888..b5cebb85 100644 --- a/src/main/java/org/warp/picalculator/TestJNI.java +++ b/src/main/java/org/warp/picalculator/TestJNI.java @@ -1,21 +1,31 @@ package org.warp.picalculator; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import org.warp.picalculator.MmapByteBuffer; -import cz.adamh.utils.NativeUtils; public class TestJNI { - static { - try { - NativeUtils.loadLibraryFromJar("/picalculatornative.dll"); - } catch (IOException e) { - e.printStackTrace(); // This is probably not the best way to handle exception :-) - } - } - private native void sayHello(); - - public static void main(String[] args) { - // invoke the native method - new TestJNI().sayHello(); - } + public TestJNI() { + + } + + static { + System.load("/boot/libpicalc.so"); + } + + private native MmapByteBuffer getDisplayBuffer(); + + private native void disposeDisplayBuffer(); + + public MmapByteBuffer retrieveBuffer() { + return getDisplayBuffer(); + } + + public void deleteBuffer() { + disposeDisplayBuffer(); + } } \ No newline at end of file diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/framebuffer/FBEngine.java b/src/main/java/org/warp/picalculator/gui/graphicengine/framebuffer/FBEngine.java index 55edce99..15eddcbe 100644 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/framebuffer/FBEngine.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/framebuffer/FBEngine.java @@ -8,6 +8,8 @@ import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.util.concurrent.Semaphore; +import org.warp.picalculator.MmapByteBuffer; +import org.warp.picalculator.TestJNI; import org.warp.picalculator.Utils; import org.warp.picalculator.gui.graphicengine.BinaryFont; import org.warp.picalculator.gui.graphicengine.GraphicEngine; @@ -27,13 +29,16 @@ public class FBEngine implements GraphicEngine { private static final int WIDTH = 480; private static final int HEIGHT = 320; private static final int[] SIZE = new int[] {WIDTH, HEIGHT}; + private TestJNI jni = new TestJNI(); public FBRenderer r; - private MappedByteBuffer fb, realFb; + private MappedByteBuffer fb; + MmapByteBuffer realFb; private RandomAccessFile fbFileRW; public volatile boolean initialized = false; public Semaphore exitSemaphore = new Semaphore(0); private boolean resizedTrigger = false; + @Override public int[] getSize() { return SIZE; @@ -59,22 +64,15 @@ public class FBEngine implements GraphicEngine { @Override public void create(Runnable onInitialized) { resizedTrigger = true; - File fbFile = new File("/dev/fb1"); - try { - fbFileRW = new RandomAccessFile(fbFile, "rw"); - final long fbLen = FB_DISPLAY_HEIGHT*FB_DISPLAY_WIDTH*(FB_DISPLAY_BPP/8); - fb = (MappedByteBuffer) MappedByteBuffer.allocateDirect((int) fbLen); - realFb = fbFileRW.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, fbLen); - - r = new FBRenderer(this, fb); - - initialized = true; - if (onInitialized != null) - onInitialized.run(); - } catch (IOException ex) { - System.err.println("Cannot read framebuffer fb1"); - ex.printStackTrace(); - } + realFb = jni.retrieveBuffer(); + final long fbLen = realFb.getLength(); + fb = (MappedByteBuffer) MappedByteBuffer.allocateDirect((int) fbLen); + + r = new FBRenderer(this, fb); + + initialized = true; + if (onInitialized != null) + onInitialized.run(); } @Override @@ -144,15 +142,14 @@ public class FBEngine implements GraphicEngine { _________________TMP = 0; } _________________TMP++; - realFb.clear(); - realFb.put(fb); + realFb.getBuffer().clear(); + realFb.getBuffer().put(fb); for (int i = 0; i < fb.capacity()/2; i++) { - realFb.put(i, (byte) (0xFF)); + realFb.getBuffer().put(i, (byte) (0xFF)); } for (int i = fb.capacity()/2; i < fb.capacity(); i++) { - realFb.put(i, (byte) (0x18)); + realFb.getBuffer().put(i, (byte) (0x18)); } - realFb.force(); } @Override diff --git a/src/main/jni/.gitignore b/src/main/jni/.gitignore new file mode 100644 index 00000000..50638950 --- /dev/null +++ b/src/main/jni/.gitignore @@ -0,0 +1 @@ +/buffermanager.c diff --git a/src/main/jni/CMakeLists.txt b/src/main/jni/CMakeLists.txt new file mode 100644 index 00000000..0ffeefd5 --- /dev/null +++ b/src/main/jni/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 2.8) +project(picalculatornative) +SET(COMPILE_DEFINITIONS -Werror) + +find_package(JNI REQUIRED) +include_directories(${JNI_INCLUDE_DIRS}) + +include_directories(/opt/vc/include) +include_directories(/opt/vc/include/interface/vcos/pthreads) +include_directories(/opt/vc/include/interface/vmcs_host) +include_directories(/opt/vc/include/interface/vmcs_host/linux) + +link_directories(/opt/vc/lib) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +set(SOURCE_FILES TestJNI.cpp) +add_library(picalculatornative SHARED ${SOURCE_FILES}) \ No newline at end of file diff --git a/src/main/jni/TestJNI.c b/src/main/jni/TestJNI.c deleted file mode 100644 index a7ca4b05..00000000 --- a/src/main/jni/TestJNI.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include -#include "TestJNI.h" - -JNIEXPORT void JNICALL Java_org_warp_picalculator_TestJNI_sayHello(JNIEnv *env, jobject thisObj) -{ - printf("Hello World!\n"); - return; -} diff --git a/src/main/jni/TestJNI.cpp b/src/main/jni/TestJNI.cpp new file mode 100644 index 00000000..9a951f7a --- /dev/null +++ b/src/main/jni/TestJNI.cpp @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "TestJNI.h" + +int fbfd = -1; +char *fbp = nullptr; +struct fb_var_screeninfo vinfo; +struct fb_fix_screeninfo finfo; + + +JNIEXPORT void JNICALL Java_org_warp_picalculator_TestJNI_disposeDisplayBuffer(JNIEnv *env, jobject thisObj) +{ + if (fbp != nullptr) { + munmap(fbp, finfo.smem_len); + fbp = nullptr; + } + if (fbfd != -1) { + close(fbfd); + fbfd = -1; + } + return; +} + +JNIEXPORT jobject JNICALL Java_org_warp_picalculator_TestJNI_getDisplayBuffer(JNIEnv *env, jobject thisObj) +{ + + syslog(LOG_INFO, "[JNI NATIVE] INIT"); + + fbfd = open("/dev/fb1", O_RDWR); + if (fbfd == -1) { + syslog(LOG_ERR, "Unable to open secondary display"); + return NULL; + } + if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) { + syslog(LOG_ERR, "Unable to get secondary display information"); + return NULL; + } + if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) { + syslog(LOG_ERR, "Unable to get secondary display information"); + return NULL; + } + + syslog(LOG_INFO, "Second display is %d x %d %dbps\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel); + + fbp = (char*) mmap(0, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); + if (fbp <= 0) { + syslog(LOG_ERR, "Unable to create mamory mapping"); + close(fbfd); + return NULL; + } + + char* class_name = "org/warp/picalculator/MmapByteBuffer"; + jclass clz = env->FindClass(class_name); + if (clz == NULL) { + printf("Error, could not find class '%s'\n", class_name); + return NULL; + } + char* signature = "(IIILjava/nio/ByteBuffer;)V"; + jmethodID constructor = env->GetMethodID( clz, "", signature); + if (constructor == NULL) { + printf("Error, could not find constructor %s %s\n", class_name, signature); + return NULL; + } + + syslog(LOG_INFO, "[JNI NATIVE] DONE"); + return env->NewObject(clz, constructor, fbfd, fbp, finfo.smem_len, + env->NewDirectByteBuffer(fbp, finfo.smem_len)); +} diff --git a/src/main/jni/TestJNI.h b/src/main/jni/TestJNI.h index 65b039db..4604c785 100644 --- a/src/main/jni/TestJNI.h +++ b/src/main/jni/TestJNI.h @@ -9,10 +9,18 @@ extern "C" { #endif /* * Class: org_warp_picalculator_TestJNI - * Method: sayHello + * Method: getDisplayBuffer + * Signature: ()Lorg/warp/picalculator/MmapByteBuffer; + */ +JNIEXPORT jobject JNICALL Java_org_warp_picalculator_TestJNI_getDisplayBuffer + (JNIEnv *, jobject); + +/* + * Class: org_warp_picalculator_TestJNI + * Method: disposeDisplayBuffer * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_warp_picalculator_TestJNI_sayHello +JNIEXPORT void JNICALL Java_org_warp_picalculator_TestJNI_disposeDisplayBuffer (JNIEnv *, jobject); #ifdef __cplusplus diff --git a/src/main/jni/TestJNI.o b/src/main/jni/TestJNI.o deleted file mode 100644 index 956366ccbd8b1cff7eec7daed2a6c8640832104e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 884 zcmb7D!AiqG5S{H-4Wdx=(qpW6(@;E!c*-#rlpZWzl(;6b6aop!w#J)K5qc2%K^_YF z0se&GLHq=DW|PvbZ4VCYWOm=%x9seT|F{AaUkqSVRb{YbkV#eNsg9pr#Gi3clyI2P zys~^Dg<4shY-ooi@=$dP;ECDVcxgf5CR$NN#wwz6s78iL^ruWnoMEH6XeTfybH z&j#fAN#My|Fh1iDi-%dgQOg;;JN-}78Jtv{L96OKt<#ndN<*jrYF@q!^>BhPjLh>W z3H>eNFoW+H+}LMLngML*A29cVERGU+RBMQyaHFK{-ijo4^k}TukD(97fbLtTX>!uTqulfB0&}N0KbNU4H)DT*{*QmW9Q*<+-*bHc diff --git a/src/main/jni/makefile b/src/main/jni/makefileOLD similarity index 62% rename from src/main/jni/makefile rename to src/main/jni/makefileOLD index 947fb5ce..8c494755 100644 --- a/src/main/jni/makefile +++ b/src/main/jni/makefileOLD @@ -6,16 +6,24 @@ PATH1B = org.warp.picalculator # Define a virtual path for .class in the bin directory vpath %.class $(CLASS_PATH)/$(PATH1A) -all : picalculatornative.dll +all : picalculatornative.so # $@ matches the target, $< matches the first dependancy -picalculatornative.dll : TestJNI.o +picalculatornative.so : TestJNI.o + gcc -m64 -mtune=generic -Wl,--add-stdcall-alias -shared -o ../resources/$@ $< + +# $@ matches the target, $< matches the first dependancy +picalculatornative.dll : windows_TestJNI.o x86_64-w64-mingw32-gcc.exe -m64 -mtune=generic -Wl,--add-stdcall-alias -shared -o ../resources/$@ $< # $@ matches the target, $< matches the first dependancy -TestJNI.o : TestJNI.c TestJNI.h +windows_TestJNI.o : TestJNI.c TestJNI.h x86_64-w64-mingw32-gcc.exe -m64 -mtune=generic -I"G:\Program Files\Java\jdk1.8.0_144\include" -I"G:\Program Files\Java\jdk1.8.0_144\include\win32" -c $< -o $@ +# $@ matches the target, $< matches the first dependancy +TestJNI.o : TestJNI.c TestJNI.h + gcc -m64 -mtune=generic -I"G:\Program Files\Java\jdk1.8.0_144\include" -I"G:\Program Files\Java\jdk1.8.0_144\include\win32" -c $< -o $@ + # $* matches the target filename without the extension TestJNI.h : TestJNI.class javah -o "$*.h" -classpath "$(CLASS_PATH)" $(PATH1B).$* diff --git a/src/main/resources/picalculatornative.dll b/src/main/resources/picalculatornative.dll index f3258dbbf1e512e2f380f200bd9c48fd94685670..796e44795ec06a349b93e72269719939d2566728 100644 GIT binary patch delta 44 xcmdmSm4C-o{s|q-yAJD3?Dl1TQ^T_Hwq_%U+sxk7&fdfb#7x`So0vCd006@i5=H<3 delta 44 wcmdmSm4C-o{s|q-kE(PgcKb40yk_2bTeA_wZDwz3XK!KzVy5lvP0SlJ0JIYkx&QzG