1 /* 2 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.prism.es2; 27 28 import com.sun.prism.impl.PrismSettings; 29 import com.sun.javafx.PlatformUtil; 30 import java.security.AccessController; 31 import java.security.PrivilegedAction; 32 import java.util.HashMap; 33 34 abstract class GLFactory { 35 36 private static native boolean 37 nIsGLExtensionSupported(long nativeContextObject, String glExtStr); 38 private static native String nGetGLVendor(long nativeCtxInfo); 39 private static native String nGetGLRenderer(long nativeCtxInfo); 40 private static native String nGetGLVersion(long nativeCtxInfo); 41 42 private static final GLFactory platformFactory; 43 44 /* Note: We are only storing the string information of a driver in this 45 * object. We are assuming a system with a single or homogeneous GPUs. 46 * For the case of heterogeneous GPUs system the string information 47 * will need to move to GLContext class. */ 48 long nativeCtxInfo; 49 boolean gl2 = false; 50 private GLContext shareCtx = null; 51 52 /** 53 * Creates a new GLFactory instance. End users do not need 54 * to call this method. 55 */ 56 GLFactory() { 57 } 58 59 /** 60 * Instantiate singleton factories if available, the OS native ones. 61 */ 62 static { 63 64 final String factoryClassName; 65 if (PlatformUtil.isUnix()) { 66 if ("eglx11".equals(PlatformUtil.getEmbeddedType())) 67 factoryClassName = "com.sun.prism.es2.EGLX11GLFactory"; 68 else if ("eglfb".equals(PlatformUtil.getEmbeddedType())) 69 factoryClassName = "com.sun.prism.es2.EGLFBGLFactory"; 70 else if ("monocle".equals(PlatformUtil.getEmbeddedType())) 71 factoryClassName = "com.sun.prism.es2.MonocleGLFactory"; 72 else 73 factoryClassName = "com.sun.prism.es2.X11GLFactory"; 74 } else if (PlatformUtil.isWindows()) { 75 factoryClassName = "com.sun.prism.es2.WinGLFactory"; 76 } else if (PlatformUtil.isMac()) { 77 factoryClassName = "com.sun.prism.es2.MacGLFactory"; 78 } else if (PlatformUtil.isIOS()) { 79 factoryClassName = "com.sun.prism.es2.IOSGLFactory"; 80 } else if (PlatformUtil.isAndroid()) { 81 if ("eglfb".equals(PlatformUtil.getEmbeddedType())) { 82 factoryClassName = "com.sun.prism.es2.EGLFBGLFactory"; 83 } else { 84 factoryClassName = null; 85 System.err.println("GLFactory.static - Only eglfb supported for Android!"); 86 } 87 } else { 88 factoryClassName = null; 89 System.err.println("GLFactory.static - No Platform Factory for: " + System.getProperty("os.name")); 90 } 91 if (PrismSettings.verbose) { 92 System.out.println("GLFactory using " + factoryClassName); 93 } 94 platformFactory = factoryClassName == null ? null : 95 AccessController.doPrivileged(new FactoryLoader(factoryClassName)); 96 } 97 98 private static class FactoryLoader implements PrivilegedAction<GLFactory> { 99 private final String factoryClassName; 100 FactoryLoader(String factoryClassName) { 101 this.factoryClassName = factoryClassName; 102 } 103 public GLFactory run() { 104 GLFactory factory = null; 105 try { 106 factory = (GLFactory) Class.forName(factoryClassName).newInstance(); 107 } catch (Throwable t) { 108 System.err.println("GLFactory.static - Platform: " 109 + System.getProperty("os.name") 110 + " - not available: " 111 + factoryClassName); 112 t.printStackTrace(); 113 } 114 return factory; 115 } 116 } 117 118 /** 119 * Returns the sole GLFactory instance. 120 */ 121 static GLFactory getFactory() throws RuntimeException { 122 if (null != platformFactory) { 123 return platformFactory; 124 } 125 throw new RuntimeException("No native platform GLFactory available."); 126 } 127 128 // Consists of a list of prequalifying GPUs that we may use for the es2 pipe. 129 // A null preQualificationFilter implies we may consider any GPU 130 abstract GLGPUInfo[] getPreQualificationFilter(); 131 132 // Consists of a list of GPUs that we will block from using the es2 pipe. 133 abstract GLGPUInfo[] getBlackList(); 134 135 private static GLGPUInfo readGPUInfo(long nativeCtxInfo) { 136 String glVendor = nGetGLVendor(nativeCtxInfo); 137 String glRenderer = nGetGLRenderer(nativeCtxInfo); 138 return new GLGPUInfo(glVendor.toLowerCase(), 139 glRenderer.toLowerCase()); 140 } 141 142 private static boolean matches(GLGPUInfo gpuInfo, GLGPUInfo[] gpuInfoArr) { 143 if (gpuInfoArr != null) { 144 for (int i = 0; i < gpuInfoArr.length; i++) { 145 if (gpuInfo.matches(gpuInfoArr[i])) { 146 return true; 147 } 148 } 149 } 150 return false; 151 } 152 153 private boolean inPreQualificationFilter(GLGPUInfo gpuInfo) { 154 GLGPUInfo[] preQualificationFilter = getPreQualificationFilter(); 155 if (preQualificationFilter == null) { 156 // We will consider any GPU if preQualificationFilter is null 157 return true; 158 } 159 return matches(gpuInfo, preQualificationFilter); 160 } 161 162 private boolean inBlackList(GLGPUInfo gpuInfo) { 163 return matches(gpuInfo, getBlackList()); 164 } 165 166 boolean isQualified(long nativeCtxInfo) { 167 // Read the GPU (graphics hardware) information and qualifying it by 168 // checking against the preQualificationFilter and the "blocking" 169 // blackLis. 170 GLGPUInfo gpuInfo = readGPUInfo(nativeCtxInfo); 171 172 if (gpuInfo.vendor == null || gpuInfo.model == null 173 || gpuInfo.vendor.contains("unknown") 174 || gpuInfo.model.contains("unknown")) { 175 // Return false if we can't determine the vendor and model of the 176 // gpu installed on the system 177 return false; 178 } 179 180 return inPreQualificationFilter(gpuInfo) && !inBlackList(gpuInfo); 181 } 182 183 abstract GLContext createGLContext(long nativeCtxInfo); 184 185 abstract GLContext createGLContext(GLDrawable drawable, 186 GLPixelFormat pixelFormat, GLContext shareCtx, boolean vSyncRequest); 187 188 abstract GLDrawable createGLDrawable(long nativeWindow, GLPixelFormat pixelFormat); 189 190 abstract GLDrawable createDummyGLDrawable(GLPixelFormat pixelFormat); 191 192 abstract GLPixelFormat createGLPixelFormat(long nativeScreen, GLPixelFormat.Attributes attrs); 193 194 boolean isGLGPUQualify() { 195 return isQualified(nativeCtxInfo); 196 } 197 198 abstract boolean initialize(Class psClass, GLPixelFormat.Attributes attrs); 199 200 GLContext getShareContext() { 201 if (shareCtx == null) { 202 shareCtx = createGLContext(nativeCtxInfo); 203 } 204 return shareCtx; 205 } 206 207 // Returns true if this pipe supports GL2 profile, false for GLES2 208 boolean isGL2() { 209 return gl2; 210 } 211 212 boolean isGLExtensionSupported(String sglExtStr) { 213 return nIsGLExtensionSupported(nativeCtxInfo, sglExtStr); 214 } 215 216 boolean isNPOTSupported() { 217 return (isGLExtensionSupported("GL_ARB_texture_non_power_of_two") 218 || isGLExtensionSupported("GL_OES_texture_npot")); 219 } 220 221 abstract int getAdapterCount(); 222 223 abstract int getAdapterOrdinal(long nativeScreen); 224 225 abstract void updateDeviceDetails(HashMap deviceDetails); 226 227 void printDriverInformation(int adapter) { 228 /* We are assuming a system with a single or homogeneous GPUs. */ 229 System.out.println("Graphics Vendor: " + nGetGLVendor(nativeCtxInfo)); 230 System.out.println(" Renderer: " + nGetGLRenderer(nativeCtxInfo)); 231 System.out.println(" Version: " + nGetGLVersion(nativeCtxInfo)); 232 } 233 }