diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index e241ab13a..b0c0a63c1 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -98,6 +98,8 @@ public class Base { } } + static String nativeArch = System.getProperty("os.arch"); + static private boolean commandLine; // A single instance of the preferences window @@ -1543,6 +1545,30 @@ public class Base { return nativeBits; } + /** + * Return the value of the os.arch propery + */ + static public String getNativeArch() { + return nativeArch; + } + + /* + * Return a string that identifies the variant of a platform + * e.g. "32" or "64" on Intel + */ + static public String getVariant() { + return getVariant(PApplet.platform, getNativeArch(), getNativeBits()); + } + + static public String getVariant(int platform, String arch, int bits) { + if (platform == PConstants.LINUX && bits == 32 && "arm".equals(Base.getNativeArch())) { + // assume armv6hf for now + return "armv6hf"; + } else { + // 32 or 64 + return Integer.toString(bits); + } + } /* static public String getPlatformName() { diff --git a/app/src/processing/app/Library.java b/app/src/processing/app/Library.java index 4b9c3f74a..fef59cafd 100644 --- a/app/src/processing/app/Library.java +++ b/app/src/processing/app/Library.java @@ -173,6 +173,7 @@ public class Library extends LocalContribution { String platformName = platformNames[i]; String platformName32 = platformName + "32"; String platformName64 = platformName + "64"; + String platformNameArmv6hh = platformName + "-armv6hf"; // First check for things like 'application.macosx=' or 'application.windows32' in the export.txt file. // These will override anything in the platform-specific subfolders. @@ -182,6 +183,8 @@ public class Library extends LocalContribution { String[] platformList32 = platform32 == null ? null : PApplet.splitTokens(platform32, ", "); String platform64 = exportTable.get("application." + platformName + "64"); String[] platformList64 = platform64 == null ? null : PApplet.splitTokens(platform64, ", "); + String platformArmv6hf = exportTable.get("application." + platformName + "-armv6hf"); + String[] platformListArmv6hf = platformArmv6hf == null ? null : PApplet.splitTokens(platformArmv6hf, ", "); // If nothing specified in the export.txt entries, look for the platform-specific folders. if (platformAll == null) { @@ -193,14 +196,17 @@ public class Library extends LocalContribution { if (platform64 == null) { platformList64 = listPlatformEntries(libraryFolder, platformName64, baseList); } + if (platformListArmv6hf == null) { + platformListArmv6hf = listPlatformEntries(libraryFolder, platformNameArmv6hh, baseList); + } - if (platformList32 != null || platformList64 != null) { + if (platformList32 != null || platformList64 != null || platformListArmv6hf != null) { multipleArch[i] = true; } // if there aren't any relevant imports specified or in their own folders, // then use the baseList (root of the library folder) as the default. - if (platformList == null && platformList32 == null && platformList64 == null) { + if (platformList == null && platformList32 == null && platformList64 == null && platformListArmv6hf == null) { exportList.put(platformName, baseList); } else { @@ -215,6 +221,9 @@ public class Library extends LocalContribution { if (platformList64 != null) { exportList.put(platformName64, platformList64); } + if (platformListArmv6hf != null) { + exportList.put(platformNameArmv6hh, platformListArmv6hf); + } } } // for (String p : exportList.keySet()) { @@ -369,8 +378,8 @@ public class Library extends LocalContribution { } - public File[] getApplicationExports(int platform, int bits) { - String[] list = getApplicationExportList(platform, bits); + public File[] getApplicationExports(int platform, String variant) { + String[] list = getApplicationExportList(platform, variant); return wrapFiles(list); } @@ -380,14 +389,17 @@ public class Library extends LocalContribution { * If no 32 or 64-bit version of the exports exists, it returns the version * that doesn't specify bit depth. */ - public String[] getApplicationExportList(int platform, int bits) { + public String[] getApplicationExportList(int platform, String variant) { String platformName = PConstants.platformNames[platform]; - if (bits == 32) { + if (variant.equals("32")) { String[] pieces = exportList.get(platformName + "32"); if (pieces != null) return pieces; - } else if (bits == 64) { + } else if (variant.equals("64")) { String[] pieces = exportList.get(platformName + "64"); if (pieces != null) return pieces; + } else if (variant.equals("armv6hf")) { + String[] pieces = exportList.get(platformName + "-armv6hf"); + if (pieces != null) return pieces; } return exportList.get(platformName); } @@ -408,12 +420,12 @@ public class Library extends LocalContribution { } - public boolean supportsArch(int platform, int bits) { + public boolean supportsArch(int platform, String variant) { // If this is a universal library, or has no natives, then we're good. if (multipleArch[platform] == false) { return true; } - return getApplicationExportList(platform, bits) != null; + return getApplicationExportList(platform, variant) != null; } diff --git a/build/build.xml b/build/build.xml index 2efcf03e3..b684a5b06 100644 --- a/build/build.xml +++ b/build/build.xml @@ -37,6 +37,7 @@ + diff --git a/core/build.xml b/core/build.xml index 5d31d4673..6e5781730 100644 --- a/core/build.xml +++ b/core/build.xml @@ -63,8 +63,8 @@ - - + + diff --git a/core/library/export.txt b/core/library/export.txt index 308d1a35a..88d0bc274 100644 --- a/core/library/export.txt +++ b/core/library/export.txt @@ -8,3 +8,4 @@ application.windows32=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-wind application.windows64=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-windows-amd64.jar,gluegen-rt-natives-windows-amd64.jar application.linux32=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-linux-i586.jar,gluegen-rt-natives-linux-i586.jar application.linux64=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-linux-amd64.jar,gluegen-rt-natives-linux-amd64.jar +application.linux-armv6hf=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-linux-armv6hf.jar,gluegen-rt-natives-linux-armv6hf.jar \ No newline at end of file diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index de8a1e796..b0c61414d 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -7042,9 +7042,15 @@ public class PGraphicsOpenGL extends PGraphics { if (smooth < 1) { pgl.disable(PGL.MULTISAMPLE); } else { - pgl.enable(PGL.MULTISAMPLE); + // work around runtime exceptions in Broadcom's VC IV driver + if (false == OPENGL_RENDERER.equals("VideoCore IV HW")) { + pgl.enable(PGL.MULTISAMPLE); + } + } + // work around runtime exceptions in Broadcom's VC IV driver + if (false == OPENGL_RENDERER.equals("VideoCore IV HW")) { + pgl.disable(PGL.POLYGON_SMOOTH); } - pgl.disable(PGL.POLYGON_SMOOTH); if (sized) { // reapplySettings(); @@ -7154,14 +7160,27 @@ public class PGraphicsOpenGL extends PGraphics { pgl.getIntegerv(PGL.MAX_TEXTURE_SIZE, intBuffer); maxTextureSize = intBuffer.get(0); - pgl.getIntegerv(PGL.MAX_SAMPLES, intBuffer); - maxSamples = intBuffer.get(0); + // work around runtime exceptions in Broadcom's VC IV driver + if (false == OPENGL_RENDERER.equals("VideoCore IV HW")) { + pgl.getIntegerv(PGL.MAX_SAMPLES, intBuffer); + maxSamples = intBuffer.get(0); + } if (anisoSamplingSupported) { pgl.getFloatv(PGL.MAX_TEXTURE_MAX_ANISOTROPY, floatBuffer); maxAnisoAmount = floatBuffer.get(0); } + // overwrite the default shaders with vendor specific versions + // if needed + if (OPENGL_RENDERER.equals("VideoCore IV HW") || // Broadcom's binary driver for Raspberry Pi + OPENGL_RENDERER.equals("Gallium 0.4 on VC4")) { // Mesa driver for same hardware + defLightShaderVertURL = + PGraphicsOpenGL.class.getResource("/processing/opengl/shaders/LightVert-vc4.glsl"); + defTexlightShaderVertURL = + PGraphicsOpenGL.class.getResource("/processing/opengl/shaders/TexLightVert-vc4.glsl"); + } + glParamsRead = true; } diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 1cf3a6383..0764d2ff2 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -195,7 +195,13 @@ public class PSurfaceJOGL implements PSurface { if (profile == null) { if (PJOGL.profile == 2) { try { - profile = GLProfile.getGL2ES1(); + if ("arm".equals(System.getProperty("os.arch"))) { + // request at least GL2 or GLES2 + profile = GLProfile.getGL2ES2(); + } else { + // stay compatible with previous versions for now + profile = GLProfile.getGL2ES1(); + } } catch (GLException ex) { profile = GLProfile.getMaxFixedFunc(true); } diff --git a/core/src/processing/opengl/shaders/LightVert-vc4.glsl b/core/src/processing/opengl/shaders/LightVert-vc4.glsl new file mode 100644 index 000000000..d008c529c --- /dev/null +++ b/core/src/processing/opengl/shaders/LightVert-vc4.glsl @@ -0,0 +1,153 @@ +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2011-13 Ben Fry and Casey Reas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + */ + +#define PROCESSING_LIGHT_SHADER + +uniform mat4 modelviewMatrix; +uniform mat4 transformMatrix; +uniform mat3 normalMatrix; + +uniform int lightCount; +uniform vec4 lightPosition[8]; +uniform vec3 lightNormal[8]; +uniform vec3 lightAmbient[8]; +uniform vec3 lightDiffuse[8]; +uniform vec3 lightSpecular[8]; +uniform vec3 lightFalloff[8]; +uniform vec2 lightSpot[8]; + +attribute vec4 position; +attribute vec4 color; +attribute vec3 normal; + +attribute vec4 ambient; +attribute vec4 specular; +attribute vec4 emissive; +attribute float shininess; + +varying vec4 vertColor; +varying vec4 backVertColor; + +const float zero_float = 0.0; +const float one_float = 1.0; +const vec3 zero_vec3 = vec3(0); + +float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) { + vec3 lpv = lightPos - vertPos; + vec3 dist = vec3(one_float); + dist.z = dot(lpv, lpv); + dist.y = sqrt(dist.z); + return one_float / dot(dist, coeff); +} + +float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, float spotExp) { + vec3 lpv = normalize(lightPos - vertPos); + vec3 nln = -one_float * lightNorm; + float spotCos = dot(nln, lpv); + return spotCos <= minCos ? zero_float : pow(spotCos, spotExp); +} + +float lambertFactor(vec3 lightDir, vec3 vecNormal) { + return max(zero_float, dot(lightDir, vecNormal)); +} + +float blinnPhongFactor(vec3 lightDir, vec3 vertPos, vec3 vecNormal, float shine) { + vec3 np = normalize(vertPos); + vec3 ldp = normalize(lightDir - np); + return pow(max(zero_float, dot(ldp, vecNormal)), shine); +} + +void main() { + // Vertex in clip coordinates + gl_Position = transformMatrix * position; + + // Vertex in eye coordinates + vec3 ecVertex = vec3(modelviewMatrix * position); + + // Normal vector in eye coordinates + vec3 ecNormal = normalize(normalMatrix * normal); + vec3 ecNormalInv = ecNormal * -one_float; + + // Light calculations + vec3 totalAmbient = vec3(0, 0, 0); + + vec3 totalFrontDiffuse = vec3(0, 0, 0); + vec3 totalFrontSpecular = vec3(0, 0, 0); + + vec3 totalBackDiffuse = vec3(0, 0, 0); + vec3 totalBackSpecular = vec3(0, 0, 0); + + // prevent register allocation failure by limiting ourselves to + // two lights for now + for (int i = 0; i < 2; i++) { + if (lightCount == i) break; + + vec3 lightPos = lightPosition[i].xyz; + bool isDir = zero_float < lightPosition[i].w; + float spotCos = lightSpot[i].x; + float spotExp = lightSpot[i].y; + + vec3 lightDir; + float falloff; + float spotf; + + if (isDir) { + falloff = one_float; + lightDir = -one_float * lightNormal[i]; + } else { + falloff = falloffFactor(lightPos, ecVertex, lightFalloff[i]); + lightDir = normalize(lightPos - ecVertex); + } + + spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i], + spotCos, spotExp) + : one_float; + + if (any(greaterThan(lightAmbient[i], zero_vec3))) { + totalAmbient += lightAmbient[i] * falloff; + } + + if (any(greaterThan(lightDiffuse[i], zero_vec3))) { + totalFrontDiffuse += lightDiffuse[i] * falloff * spotf * + lambertFactor(lightDir, ecNormal); + totalBackDiffuse += lightDiffuse[i] * falloff * spotf * + lambertFactor(lightDir, ecNormalInv); + } + + if (any(greaterThan(lightSpecular[i], zero_vec3))) { + totalFrontSpecular += lightSpecular[i] * falloff * spotf * + blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess); + totalBackSpecular += lightSpecular[i] * falloff * spotf * + blinnPhongFactor(lightDir, ecVertex, ecNormalInv, shininess); + } + } + + // Calculating final color as result of all lights (plus emissive term). + // Transparency is determined exclusively by the diffuse component. + vertColor = vec4(totalAmbient, 0) * ambient + + vec4(totalFrontDiffuse, 1) * color + + vec4(totalFrontSpecular, 0) * specular + + vec4(emissive.rgb, 0); + + backVertColor = vec4(totalAmbient, 0) * ambient + + vec4(totalBackDiffuse, 1) * color + + vec4(totalBackSpecular, 0) * specular + + vec4(emissive.rgb, 0); +} \ No newline at end of file diff --git a/core/src/processing/opengl/shaders/LightVert.glsl b/core/src/processing/opengl/shaders/LightVert.glsl index 8d75f970a..747e0295d 100644 --- a/core/src/processing/opengl/shaders/LightVert.glsl +++ b/core/src/processing/opengl/shaders/LightVert.glsl @@ -29,7 +29,7 @@ uniform vec4 lightPosition[8]; uniform vec3 lightNormal[8]; uniform vec3 lightAmbient[8]; uniform vec3 lightDiffuse[8]; -uniform vec3 lightSpecular[8]; +uniform vec3 lightSpecular[8]; uniform vec3 lightFalloff[8]; uniform vec2 lightSpot[8]; diff --git a/core/src/processing/opengl/shaders/TexLightVert-vc4.glsl b/core/src/processing/opengl/shaders/TexLightVert-vc4.glsl new file mode 100644 index 000000000..ef5ed5a61 --- /dev/null +++ b/core/src/processing/opengl/shaders/TexLightVert-vc4.glsl @@ -0,0 +1,159 @@ +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2011-13 Ben Fry and Casey Reas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + */ + +#define PROCESSING_TEXLIGHT_SHADER + +uniform mat4 modelviewMatrix; +uniform mat4 transformMatrix; +uniform mat3 normalMatrix; +uniform mat4 texMatrix; + +uniform int lightCount; +uniform vec4 lightPosition[8]; +uniform vec3 lightNormal[8]; +uniform vec3 lightAmbient[8]; +uniform vec3 lightDiffuse[8]; +uniform vec3 lightSpecular[8]; +uniform vec3 lightFalloff[8]; +uniform vec2 lightSpot[8]; + +attribute vec4 position; +attribute vec4 color; +attribute vec3 normal; +attribute vec2 texCoord; + +attribute vec4 ambient; +attribute vec4 specular; +attribute vec4 emissive; +attribute float shininess; + +varying vec4 vertColor; +varying vec4 backVertColor; +varying vec4 vertTexCoord; + +const float zero_float = 0.0; +const float one_float = 1.0; +const vec3 zero_vec3 = vec3(0); + +float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) { + vec3 lpv = lightPos - vertPos; + vec3 dist = vec3(one_float); + dist.z = dot(lpv, lpv); + dist.y = sqrt(dist.z); + return one_float / dot(dist, coeff); +} + +float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, float spotExp) { + vec3 lpv = normalize(lightPos - vertPos); + vec3 nln = -one_float * lightNorm; + float spotCos = dot(nln, lpv); + return spotCos <= minCos ? zero_float : pow(spotCos, spotExp); +} + +float lambertFactor(vec3 lightDir, vec3 vecNormal) { + return max(zero_float, dot(lightDir, vecNormal)); +} + +float blinnPhongFactor(vec3 lightDir, vec3 vertPos, vec3 vecNormal, float shine) { + vec3 np = normalize(vertPos); + vec3 ldp = normalize(lightDir - np); + return pow(max(zero_float, dot(ldp, vecNormal)), shine); +} + +void main() { + // Vertex in clip coordinates + gl_Position = transformMatrix * position; + + // Vertex in eye coordinates + vec3 ecVertex = vec3(modelviewMatrix * position); + + // Normal vector in eye coordinates + vec3 ecNormal = normalize(normalMatrix * normal); + vec3 ecNormalInv = ecNormal * -one_float; + + // Light calculations + vec3 totalAmbient = vec3(0, 0, 0); + + vec3 totalFrontDiffuse = vec3(0, 0, 0); + vec3 totalFrontSpecular = vec3(0, 0, 0); + + vec3 totalBackDiffuse = vec3(0, 0, 0); + vec3 totalBackSpecular = vec3(0, 0, 0); + + // prevent register allocation failure by limiting ourselves to + // two lights for now + for (int i = 0; i < 2; i++) { + if (lightCount == i) break; + + vec3 lightPos = lightPosition[i].xyz; + bool isDir = zero_float < lightPosition[i].w; + float spotCos = lightSpot[i].x; + float spotExp = lightSpot[i].y; + + vec3 lightDir; + float falloff; + float spotf; + + if (isDir) { + falloff = one_float; + lightDir = -one_float * lightNormal[i]; + } else { + falloff = falloffFactor(lightPos, ecVertex, lightFalloff[i]); + lightDir = normalize(lightPos - ecVertex); + } + + spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i], + spotCos, spotExp) + : one_float; + + if (any(greaterThan(lightAmbient[i], zero_vec3))) { + totalAmbient += lightAmbient[i] * falloff; + } + + if (any(greaterThan(lightDiffuse[i], zero_vec3))) { + totalFrontDiffuse += lightDiffuse[i] * falloff * spotf * + lambertFactor(lightDir, ecNormal); + totalBackDiffuse += lightDiffuse[i] * falloff * spotf * + lambertFactor(lightDir, ecNormalInv); + } + + if (any(greaterThan(lightSpecular[i], zero_vec3))) { + totalFrontSpecular += lightSpecular[i] * falloff * spotf * + blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess); + totalBackSpecular += lightSpecular[i] * falloff * spotf * + blinnPhongFactor(lightDir, ecVertex, ecNormalInv, shininess); + } + } + + // Calculating final color as result of all lights (plus emissive term). + // Transparency is determined exclusively by the diffuse component. + vertColor = vec4(totalAmbient, 0) * ambient + + vec4(totalFrontDiffuse, 1) * color + + vec4(totalFrontSpecular, 0) * specular + + vec4(emissive.rgb, 0); + + backVertColor = vec4(totalAmbient, 0) * ambient + + vec4(totalBackDiffuse, 1) * color + + vec4(totalBackSpecular, 0) * specular + + vec4(emissive.rgb, 0); + + // Calculating texture coordinates, with r and q set both to one + vertTexCoord = texMatrix * vec4(texCoord, 1.0, 1.0); +} diff --git a/core/src/processing/opengl/shaders/TexLightVert.glsl b/core/src/processing/opengl/shaders/TexLightVert.glsl index d9f2cde3a..a69c66dc0 100644 --- a/core/src/processing/opengl/shaders/TexLightVert.glsl +++ b/core/src/processing/opengl/shaders/TexLightVert.glsl @@ -30,7 +30,7 @@ uniform vec4 lightPosition[8]; uniform vec3 lightNormal[8]; uniform vec3 lightAmbient[8]; uniform vec3 lightDiffuse[8]; -uniform vec3 lightSpecular[8]; +uniform vec3 lightSpecular[8]; uniform vec3 lightFalloff[8]; uniform vec2 lightSpot[8]; diff --git a/java/src/processing/mode/java/Commander.java b/java/src/processing/mode/java/Commander.java index 4d3ecf0e4..fc46ba66d 100644 --- a/java/src/processing/mode/java/Commander.java +++ b/java/src/processing/mode/java/Commander.java @@ -35,6 +35,7 @@ import processing.app.SketchException; import processing.app.Util; import processing.app.contrib.ModeContribution; import processing.core.PApplet; +import processing.core.PConstants; import processing.mode.java.runner.Runner; @@ -280,14 +281,9 @@ public class Commander implements RunnerListener { JavaBuild build = new JavaBuild(sketch); build.build(true); if (build != null) { -// if (platformBits == 0) { -// platformBits = Base.getNativeBits(); -// } -// if (platformBits == 0 && -// Library.hasMultipleArch(platform, build.getImportedLibraries())) { -// complainAndQuit("This sketch can be exported for 32- or 64-bit, please specify one.", true); -// } - success = build.exportApplication(outputFolder, platform, platformBits, embedJava); + + String variant = Base.getVariant(); + success = build.exportApplication(outputFolder, platform, variant, embedJava); } } } diff --git a/java/src/processing/mode/java/JavaBuild.java b/java/src/processing/mode/java/JavaBuild.java index deda39941..3950a6831 100644 --- a/java/src/processing/mode/java/JavaBuild.java +++ b/java/src/processing/mode/java/JavaBuild.java @@ -796,17 +796,24 @@ public class JavaBuild { if (Library.hasMultipleArch(platform, importedLibraries)) { // export the 32-bit version folder = new File(sketch.getFolder(), "application." + platformName + "32"); - if (!exportApplication(folder, platform, 32, embedJava && Base.getNativeBits() == 32)) { + if (!exportApplication(folder, platform, "32", embedJava && Base.getNativeBits() == 32 && "x86".equals(Base.getNativeArch()))) { return false; } // export the 64-bit version folder = new File(sketch.getFolder(), "application." + platformName + "64"); - if (!exportApplication(folder, platform, 64, embedJava && Base.getNativeBits() == 64)) { + if (!exportApplication(folder, platform, "64", embedJava && Base.getNativeBits() == 64 && "x86".equals(Base.getNativeArch()))) { return false; } + if (platform == PConstants.LINUX) { + // export the armv6hf version as well + folder = new File(sketch.getFolder(), "application.linux-armv6hf"); + if (!exportApplication(folder, platform, "armv6hf", embedJava && Base.getNativeBits() == 32 && "arm".equals(Base.getNativeArch()))) { + return false; + } + } } else { // just make a single one for this platform folder = new File(sketch.getFolder(), "application." + platformName); - if (!exportApplication(folder, platform, 0, embedJava)) { + if (!exportApplication(folder, platform, "", embedJava)) { return false; } } @@ -847,18 +854,18 @@ public class JavaBuild { */ protected boolean exportApplication(File destFolder, int exportPlatform, - int exportBits, + String exportVariant, boolean embedJava) throws IOException, SketchException { // TODO this should probably be a dialog box instead of a warning // on the terminal. And the message should be written better than this. // http://code.google.com/p/processing/issues/detail?id=884 for (Library library : importedLibraries) { - if (!library.supportsArch(exportPlatform, exportBits)) { + if (!library.supportsArch(exportPlatform, exportVariant)) { String pn = PConstants.platformNames[exportPlatform]; Base.showWarning("Quibbles 'n Bits", - "The application." + pn + exportBits + + "The application." + pn + exportVariant + " folder will not be created\n" + - "because no " + exportBits + "-bit version of " + + "because no " + exportVariant + " version of " + library.getName() + " is available for " + pn, null); return true; // don't cancel all exports for this, just move along } @@ -1062,7 +1069,7 @@ public class JavaBuild { /// add contents of 'library' folders to the export for (Library library : importedLibraries) { // add each item from the library folder / export list to the output - for (File exportFile : library.getApplicationExports(exportPlatform, exportBits)) { + for (File exportFile : library.getApplicationExports(exportPlatform, exportVariant)) { // System.out.println("export: " + exportFile); String exportName = exportFile.getName(); if (!exportFile.exists()) { diff --git a/java/src/processing/mode/java/runner/Runner.java b/java/src/processing/mode/java/runner/Runner.java index efb17f00d..2e910b93a 100644 --- a/java/src/processing/mode/java/runner/Runner.java +++ b/java/src/processing/mode/java/runner/Runner.java @@ -90,9 +90,11 @@ public class Runner implements MessageConsumer { // Make sure all the imported libraries will actually run with this setup. int bits = Base.getNativeBits(); + String variant = Base.getVariant(); + for (Library library : build.getImportedLibraries()) { - if (!library.supportsArch(PApplet.platform, bits)) { - sketchErr.println(library.getName() + " does not run in " + bits + "-bit mode."); + if (!library.supportsArch(PApplet.platform, variant)) { + sketchErr.println(library.getName() + " does not run on this architecture: " + variant); int opposite = (bits == 32) ? 64 : 32; if (Base.isMacOS()) { //if (library.supportsArch(PConstants.MACOSX, opposite)) { // should always be true @@ -668,7 +670,7 @@ public class Runner implements MessageConsumer { listener.statusError("A library used by this sketch is not installed properly."); err.println("A library relies on native code that's not available."); err.println("Or only works properly when the sketch is run as a " + - ((Base.getNativeBits() == 32) ? "64-bit " : "32-bit ") + " application."); + ((Base.getNativeBits() == 32) ? "64-bit" : "32-bit") + " application."); } else if (exceptionClass.equals("java.lang.StackOverflowError")) { listener.statusError("StackOverflowError: This sketch is attempting too much recursion.");