Merge pull request #3583 from gohai/arm-3.0-for-ben7

Second bunch of arm patches (v5)
This commit is contained in:
Ben Fry
2015-08-11 19:36:40 -04:00
14 changed files with 419 additions and 37 deletions
+26
View File
@@ -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() {
+21 -9
View File
@@ -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;
}
+1
View File
@@ -37,6 +37,7 @@
<!-- there is currently no JRE available -->
<property name="jre.download.jdk" value="true" />
<property name="jre.downloader" value="linux-arm-vfp-hflt.tar.gz" />
<property name="linux.dist" value="linux/processing-${version}-linux-armv6hf.tgz" />
</target>
<!-- Require Java 8 everywhere. -->
+2 -2
View File
@@ -63,8 +63,8 @@
<!-- Copy shaders to bin. (Eclipse does this automatically.) -->
<copy todir="bin">
<fileset dir="src">
<include name="processing/opengl/shaders/*.glsl" />
<include name="icon/*.png" />
<include name="processing/opengl/shaders/*.glsl" />
<include name="icon/*.png" />
</fileset>
</copy>
</target>
+1
View File
@@ -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
@@ -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;
}
+7 -1
View File
@@ -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);
}
@@ -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);
}
@@ -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];
@@ -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);
}
@@ -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];
+4 -8
View File
@@ -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);
}
}
}
+15 -8
View File
@@ -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()) {
@@ -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.");