aboutsummaryrefslogtreecommitdiffstats
path: root/src/native
diff options
context:
space:
mode:
Diffstat (limited to 'src/native')
-rwxr-xr-xsrc/native/jogl/EGLDrawableFactory.c319
-rwxr-xr-xsrc/native/jogl/Mixer.cpp199
2 files changed, 518 insertions, 0 deletions
diff --git a/src/native/jogl/EGLDrawableFactory.c b/src/native/jogl/EGLDrawableFactory.c
new file mode 100755
index 000000000..41e0f67e1
--- /dev/null
+++ b/src/native/jogl/EGLDrawableFactory.c
@@ -0,0 +1,319 @@
+#include <EGL/egl.h>
+#include <KD/kd.h>
+#include <KD/NV_extwindowprops.h>
+#include "com_sun_opengl_impl_egl_EGLDrawableFactory.h"
+
+// FIXME: move the glViewport call up to Java
+#include <GLES/gl.h>
+
+static EGLDisplay display = NULL;
+static EGLSurface surface = NULL;
+static EGLContext context = NULL;
+static EGLConfig config = NULL;
+static KDWindow* window = NULL;
+static EGLNativeWindowType nativewin = NULL;
+static EGLint lastWidth = 0;
+static EGLint lastHeight = 0;
+
+// FIXME: need to move this up to Java to conditionalize between ES 1 and ES 2
+//static KDint nv_egl_renderable_flags = EGL_OPENGL_ES2_BIT;
+static KDint nv_egl_renderable_flags = EGL_OPENGL_ES_BIT;
+static KDint nv_egl_surface_flags = EGL_WINDOW_BIT;
+static KDust jogPressUST = 0;
+
+typedef struct
+{
+ KDint index;
+ KDboolean wasPressed;
+ KDust pressTime;
+} DeviceButtonState;
+#define NVM_BTNS_MAX 5
+typedef enum
+{
+ NVM_BTN_JOGDIAL,
+ NVM_BTN_WIDGET,
+ NVM_BTN_BACK,
+ NVM_BTN_CAMHALF,
+ NVM_BTN_CAMFULL,
+};
+DeviceButtonState conButtons[NVM_BTNS_MAX] =
+{
+ {KD_INPUT_JOGDIAL_SELECT, 0, 0},
+ {KD_INPUT_BUTTONS_0+0, 0, 0},
+ {KD_INPUT_BUTTONS_0+1, 0, 0},
+ {KD_INPUT_BUTTONS_0+2, 0, 0},
+ {KD_INPUT_BUTTONS_0+3, 0, 0},
+};
+
+JNIEXPORT jboolean JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_initEGL
+ (JNIEnv *env, jobject unused)
+{
+ display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (display == EGL_NO_DISPLAY) {
+ kdLogMessage("Error - EGL get display failed\n");
+ return JNI_FALSE;
+ }
+ if (!eglInitialize(display, 0, 0)) {
+ kdLogMessage("Error - EGL init failed\n");
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_chooseConfig
+ (JNIEnv *env, jobject unused)
+{
+ #define MAX_CONFIGS 64
+ EGLConfig confs[MAX_CONFIGS];
+ EGLint numConfigs;
+ EGLint fbAttrs[] =
+ {
+/*
+ // FIXME
+ // OpenGL ES 2 settings
+ EGL_RENDERABLE_TYPE, nv_egl_renderable_flags,
+ EGL_DEPTH_SIZE, 16,
+ EGL_SURFACE_TYPE, nv_egl_surface_flags,
+ EGL_RED_SIZE, 5,
+ EGL_GREEN_SIZE, 6,
+ EGL_BLUE_SIZE, 5,
+ EGL_ALPHA_SIZE, 0,
+ EGL_NONE
+*/
+
+/*
+ // FIXME
+ // OpenGL ES 1 settings
+ EGL_RED_SIZE, 1,
+ EGL_GREEN_SIZE, 1,
+ EGL_BLUE_SIZE, 1,
+ EGL_ALPHA_SIZE, EGL_DONT_CARE,
+ EGL_DEPTH_SIZE, 1,
+ EGL_STENCIL_SIZE, EGL_DONT_CARE,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
+ EGL_NONE
+*/
+
+ // FIXME
+ // OpenGL ES 1 settings
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
+ EGL_DEPTH_SIZE, 16,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RED_SIZE, 5,
+ EGL_GREEN_SIZE, 6,
+ EGL_BLUE_SIZE, 5,
+ EGL_ALPHA_SIZE, 0,
+ EGL_NONE
+ };
+
+ if (!(eglChooseConfig(display, fbAttrs, confs, MAX_CONFIGS, &numConfigs) && numConfigs)) {
+ kdLogMessage("Error - EGL choose config failed\n");
+ return JNI_FALSE;
+ }
+ /* Use the first */
+ config = confs[0];
+ return JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_checkDisplay
+ (JNIEnv *env, jobject unused)
+{
+ if (display == NULL) {
+ kdLogMessage("Error - EGL get display returned null\n");
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_checkConfig
+ (JNIEnv *env, jobject unused)
+{
+ if (config == NULL) {
+ kdLogMessage("Error - EGL choose config returned null\n");
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_createWindow
+ (JNIEnv *env, jobject unused)
+{
+ window = kdCreateWindow(display, config, KD_NULL);
+ if (!window) {
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+JNIEXPORT void JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_setWindowVisible
+ (JNIEnv *env, jobject unused)
+{
+ KDboolean visible = KD_TRUE;
+ kdSetWindowPropertybv(window,
+ KD_WINDOWPROPERTY_VISIBILITY, &visible);
+}
+
+JNIEXPORT void JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_setWindowFullscreen
+ (JNIEnv *env, jobject unused)
+{
+ KDboolean fullscreen = KD_TRUE;
+ kdSetWindowPropertybv(window,
+ KD_WINDOWPROPERTY_FULLSCREEN_NV, &fullscreen);
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_realizeWindow
+ (JNIEnv *env, jobject unused)
+{
+ if (kdRealizeWindow(window, &nativewin) != 0) {
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_createSurface
+ (JNIEnv *env, jobject unused)
+{
+ surface = eglCreateWindowSurface(display,
+ config, nativewin, 0);
+ if (!surface)
+ {
+ kdLogMessage("Error - EGL create window surface failed\n");
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_createContext
+ (JNIEnv *env, jobject unused)
+{
+ /*a
+ static EGLint contextAttrs[] =
+ {
+ // FIXME
+ // OpenGL ES 2 settings
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+ */
+
+ const EGLint contextAttrs[] =
+ {
+ // FIXME
+ // OpenGL ES 1 settings
+ EGL_CONTEXT_CLIENT_VERSION, 1,
+ EGL_NONE
+ };
+
+ context = eglCreateContext(display,
+ config, 0, contextAttrs);
+ if (!context)
+ {
+ kdLogMessage("Error - EGL create context failed\n");
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_makeCurrent
+ (JNIEnv *env, jobject unused)
+{
+ if (!eglMakeCurrent(display, surface, surface, context))
+ {
+ kdLogMessage("Error - EGL make current failed\n");
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+JNIEXPORT void JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_updateWindowSize
+ (JNIEnv *env, jobject unused)
+{
+ EGLint drawWidth;
+ EGLint drawHeight;
+
+ eglQuerySurface(display, surface, EGL_WIDTH, &drawWidth);
+ eglQuerySurface(display, surface, EGL_HEIGHT, &drawHeight);
+ if ((lastWidth != drawWidth) || (lastHeight != drawHeight))
+ {
+ glViewport(0, 0, drawWidth, drawHeight);
+ lastWidth = drawWidth;
+ lastHeight = drawHeight;
+ }
+}
+
+JNIEXPORT void JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_swapBuffers0
+ (JNIEnv *env, jobject unused)
+{
+ eglSwapBuffers(display, surface);
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_shouldExit
+ (JNIEnv *env, jobject unused)
+{
+ const KDEvent* ev = NULL;
+ do {
+ ev = kdWaitEvent(0);
+ if (ev != 0) {
+ switch (ev->type) {
+ case KD_EVENT_WINDOW_CLOSE:
+ case KD_EVENT_QUIT:
+ return JNI_TRUE;
+ default:
+ break;
+ /*
+ case KD_EVENT_INPUT:
+ {
+ if (!s_runningInLauncher)
+ {
+ int btn;
+ for (btn=0; btn<NVM_BTNS_MAX; btn++)
+ {
+ if (InputDown(ev, conButtons[btn].index))
+ {
+ if (!conButtons[btn].wasPressed)
+ {
+ conButtons[btn].pressTime = ev->timestamp;
+ conButtons[btn].wasPressed = KD_TRUE;
+ }
+ }
+ else
+ {
+ conButtons[btn].wasPressed = KD_FALSE;
+ }
+ }
+ }
+ break;
+ }
+ */
+ }
+ }
+ } while (ev != 0);
+ return JNI_FALSE;
+}
+
+JNIEXPORT void JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_shutdown
+ (JNIEnv *env, jobject unused)
+{
+ if (context) {
+ eglMakeCurrent(display,
+ EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroyContext(display, context);
+ context = EGL_NO_CONTEXT;
+ }
+ if (surface) {
+ eglDestroySurface(display, surface);
+ surface = EGL_NO_SURFACE;
+ }
+ kdDestroyWindow(window);
+ if (display) {
+ eglTerminate(display);
+ display = EGL_NO_DISPLAY;
+ }
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_opengl_impl_egl_EGLDrawableFactory_getDirectBufferAddress
+ (JNIEnv *env, jobject unused, jobject buffer)
+{
+ return (jint) (*env)->GetDirectBufferAddress(env, buffer);
+}
diff --git a/src/native/jogl/Mixer.cpp b/src/native/jogl/Mixer.cpp
new file mode 100755
index 000000000..8843c00ec
--- /dev/null
+++ b/src/native/jogl/Mixer.cpp
@@ -0,0 +1,199 @@
+#include <windows.h>
+#include <stdlib.h>
+#include <mmsystem.h>
+#include <mmreg.h>
+#include "com_sun_javafx_audio_windows_waveout_Mixer.h"
+
+static HANDLE event = NULL;
+static HWAVEOUT output = NULL;
+// We use only two buffers to keep latency down
+#define NUM_BUFFERS 2
+//#define NUM_BUFFERS 4
+// This is about 20 ms of data for WAVE_FORMAT_PCM:
+// (44100 samples / sec) * (20 ms / 1000 ms) * (2 bytes / sample) * (2 channels)
+//#define BUFFER_SIZE 3528
+
+// This is about 50 ms of data for WAVE_FORMAT_PCM:
+// (44100 samples / sec) * (50 ms / 1000 ms) * (2 bytes / sample) * (1 channel)
+//#define BUFFER_SIZE 4410
+
+// This is about 200 ms of data for WAVE_FORMAT_PCM:
+// (44100 samples / sec) * (200 ms / 1000 ms) * (2 bytes / sample) * (1 channel)
+//#define BUFFER_SIZE 17640
+
+// This is about 200 ms of data for WAVE_FORMAT_PCM:
+// (44100 samples / sec) * (200 ms / 1000 ms) * (2 bytes / sample) * (2 channel)
+//#define BUFFER_SIZE 35280
+
+// This is about 1000 ms of data for WAVE_FORMAT_PCM:
+// (44100 samples / sec) * (1000 ms / 1000 ms) * (2 bytes / sample) * (1 channel)
+//#define BUFFER_SIZE 88200
+
+// This is about 50 ms of data for WAVE_FORMAT_PCM:
+// (44100 samples / sec) * (50 ms / 1000 ms) * (2 bytes / sample) * (2 channels)
+//#define BUFFER_SIZE 8820
+
+// This is about 50 ms of data for WAVE_FORMAT_IEEE_FLOAT:
+// (44100 samples / sec) * (50 ms / 1000 ms) * (4 bytes / sample) * (2 channels)
+//#define BUFFER_SIZE 17640
+
+// This is about 200 ms of data for WAVE_FORMAT_PCM:
+// (11025 samples / sec) * (200 ms / 1000 ms) * (2 bytes / sample) * (2 channel)
+#define BUFFER_SIZE 8820
+
+//#define BUFFER_SIZE 8192
+static WAVEHDR** buffers = NULL;
+
+void CALLBACK playbackCallback(HWAVEOUT output,
+ UINT msg,
+ DWORD_PTR userData,
+ DWORD_PTR param1,
+ DWORD_PTR param2)
+{
+ if (msg == WOM_DONE) {
+ WAVEHDR* hdr = (WAVEHDR*) param1;
+ hdr->dwFlags |= WHDR_DONE;
+ SetEvent(event);
+ }
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sun_javafx_audio_windows_waveout_Mixer_initializeWaveOut
+ (JNIEnv *env, jclass unused, jlong eventObject)
+{
+ event = (HANDLE) eventObject;
+
+ // Note the hard requirements on the RawSoundConverter's output format
+ WAVEFORMATEX format;
+ format.wFormatTag = WAVE_FORMAT_PCM;
+ // format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
+ format.nChannels = 2;
+ // format.nChannels = 1;
+ // format.nSamplesPerSec = 44100;
+ format.nSamplesPerSec = 11025;
+ format.wBitsPerSample = 16;
+ // format.wBitsPerSample = 32;
+ format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
+ format.nAvgBytesPerSec = format.nBlockAlign * format.nSamplesPerSec;
+ format.cbSize = 0;
+ MMRESULT res = waveOutOpen(&output,
+ WAVE_MAPPER,
+ &format,
+ /* NULL, */ (DWORD_PTR) &playbackCallback,
+ NULL, // No user data right now
+ /* CALLBACK_NULL */ CALLBACK_FUNCTION);
+ if (res != MMSYSERR_NOERROR) {
+ return JNI_FALSE;
+ }
+
+ buffers = (WAVEHDR**) calloc(NUM_BUFFERS, sizeof(WAVEHDR));
+ for (int i = 0; i < NUM_BUFFERS; i++) {
+ char* data = (char*) calloc(BUFFER_SIZE, 1);
+ WAVEHDR* hdr = (WAVEHDR*) calloc(1, sizeof(WAVEHDR));
+ hdr->lpData = data;
+ hdr->dwBufferLength = BUFFER_SIZE;
+ hdr->dwFlags |= WHDR_DONE;
+ buffers[i] = hdr;
+ }
+
+ return JNI_TRUE;
+}
+
+JNIEXPORT void JNICALL Java_com_sun_javafx_audio_windows_waveout_Mixer_shutdownWaveOut
+ (JNIEnv *env, jclass unused)
+{
+ // writeString("Pausing\n");
+ waveOutPause(output);
+ // writeString("Resetting\n");
+ waveOutReset(output);
+ // writeString("Closing output\n");
+ waveOutClose(output);
+}
+
+JNIEXPORT jlong JNICALL Java_com_sun_javafx_audio_windows_waveout_Mixer_getNextMixerBuffer
+ (JNIEnv *env, jclass unused)
+{
+ WAVEHDR* hdr = NULL;
+ for (int i = 0; i < NUM_BUFFERS; i++) {
+ if (buffers[i] != NULL && ((buffers[i]->dwFlags & WHDR_DONE) != 0)) {
+ hdr = buffers[i];
+ hdr->dwFlags &= ~WHDR_DONE;
+ break;
+ }
+ }
+ return (jlong) hdr;
+}
+
+JNIEXPORT jobject JNICALL Java_com_sun_javafx_audio_windows_waveout_Mixer_getMixerBufferData
+ (JNIEnv *env, jclass unused, jlong mixerBuffer)
+{
+ WAVEHDR* hdr = (WAVEHDR*) mixerBuffer;
+ return env->NewDirectByteBuffer(hdr->lpData, hdr->dwBufferLength);
+}
+
+JNIEXPORT jlong JNICALL Java_com_sun_javafx_audio_windows_waveout_Mixer_getMixerBufferDataAddress
+ (JNIEnv *env, jclass unused, jlong mixerBuffer)
+{
+ WAVEHDR* hdr = (WAVEHDR*) mixerBuffer;
+ return (jlong) hdr->lpData;
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_javafx_audio_windows_waveout_Mixer_getMixerBufferDataCapacity
+ (JNIEnv *env, jclass unused, jlong mixerBuffer)
+{
+ WAVEHDR* hdr = (WAVEHDR*) mixerBuffer;
+ return (jint) hdr->dwBufferLength;
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sun_javafx_audio_windows_waveout_Mixer_prepareMixerBuffer
+ (JNIEnv *env, jclass unused, jlong mixerBuffer)
+{
+ MMRESULT res = waveOutPrepareHeader(output,
+ (WAVEHDR*) mixerBuffer,
+ sizeof(WAVEHDR));
+ if (res == MMSYSERR_NOERROR) {
+ return JNI_TRUE;
+ }
+ return JNI_FALSE;
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sun_javafx_audio_windows_waveout_Mixer_writeMixerBuffer
+ (JNIEnv *env, jclass unused, jlong mixerBuffer)
+{
+ MMRESULT res = waveOutWrite(output,
+ (WAVEHDR*) mixerBuffer,
+ sizeof(WAVEHDR));
+ if (res == MMSYSERR_NOERROR) {
+ waveOutRestart(output);
+
+ return JNI_TRUE;
+ }
+ return JNI_FALSE;
+}
+
+JNIEXPORT jlong JNICALL Java_com_sun_javafx_audio_windows_waveout_Mixer_CreateEvent
+ (JNIEnv *env, jclass unused)
+{
+ return (jlong) CreateEvent(NULL, FALSE, TRUE, NULL);
+}
+
+JNIEXPORT jboolean JNICALL Java_com_sun_javafx_audio_windows_waveout_Mixer_WaitForSingleObject
+ (JNIEnv *env, jclass unused, jlong eventObject)
+{
+ DWORD res = WaitForSingleObject((HANDLE) eventObject, INFINITE);
+ if (res == WAIT_OBJECT_0) {
+ return JNI_TRUE;
+ }
+ return JNI_FALSE;
+}
+
+JNIEXPORT void JNICALL Java_com_sun_javafx_audio_windows_waveout_Mixer_SetEvent
+ (JNIEnv *env, jclass unused, jlong eventObject)
+{
+ SetEvent((HANDLE) eventObject);
+}
+
+JNIEXPORT void JNICALL Java_com_sun_javafx_audio_windows_waveout_Mixer_CloseHandle
+ (JNIEnv *env, jclass unused, jlong eventObject)
+{
+ CloseHandle((HANDLE) eventObject);
+}