1 /* 2 * Copyright (c) 2012, 2013, 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 71 factoryClassName = "com.sun.prism.es2.X11GLFactory"; 72 } else if (PlatformUtil.isWindows()) { 73 factoryClassName = "com.sun.prism.es2.WinGLFactory"; 74 } else if (PlatformUtil.isMac()) { 75 factoryClassName = "com.sun.prism.es2.MacGLFactory"; 76 } else if (PlatformUtil.isIOS()) { 77 factoryClassName = "com.sun.prism.es2.IOSGLFactory"; 78 } else if (PlatformUtil.isAndroid()) { 79 if ("eglfb".equals(PlatformUtil.getEmbeddedType())) { 80 factoryClassName = "com.sun.prism.es2.EGLFBGLFactory"; 81 } else { 82 factoryClassName = null; 83 System.err.println("GLFactory.static - Only eglfb supported for Android!"); 84 } 85 } else { 86 factoryClassName = null; 87 System.err.println("GLFactory.static - No Platform Factory for: " + System.getProperty("os.name")); 88 } 89 if (PrismSettings.verbose) { 90 System.out.println("GLFactory using " + factoryClassName); 91 } 92 platformFactory = factoryClassName == null ? null : 93 AccessController.doPrivileged(new FactoryLoader(factoryClassName)); 94 } 95 96 private static class FactoryLoader implements PrivilegedAction<GLFactory> { 97 private final String factoryClassName; 98 FactoryLoader(String factoryClassName) { 99 this.factoryClassName = factoryClassName; 100 } 101 public GLFactory run() { 102 GLFactory factory = null; 103 try { 104 factory = (GLFactory) Class.forName(factoryClassName).newInstance(); 105 } catch (Throwable t) { 106 System.err.println("GLFactory.static - Platform: " 107 + System.getProperty("os.name") 108 + " - not available: " 109 + factoryClassName); 110 t.printStackTrace(); 111 } 112 return factory; 113 } 114 } 115 116 /** 117 * Returns the sole GLFactory instance. 118 */ 119 static GLFactory getFactory() throws RuntimeException { 120 if (null != platformFactory) { 121 return platformFactory; 122 } 123 throw new RuntimeException("No native platform GLFactory available."); 124 } 125 126 // Consists of a list of prequalifying GPUs that we may use for the es2 pipe. 127 // A null preQualificationFilter implies we may consider any GPU 128 abstract GLGPUInfo[] getPreQualificationFilter(); 129 130 // Consists of a list of GPUs that we will block from using the es2 pipe. 131 abstract GLGPUInfo[] getBlackList(); 132 133 private static GLGPUInfo readGPUInfo(long nativeCtxInfo) { 134 String glVendor = nGetGLVendor(nativeCtxInfo); 135 String glRenderer = nGetGLRenderer(nativeCtxInfo); 136 return new GLGPUInfo(glVendor.toLowerCase(), 137 glRenderer.toLowerCase()); 138 } 139 140 private static boolean matches(GLGPUInfo gpuInfo, GLGPUInfo[] gpuInfoArr) { 141 if (gpuInfoArr != null) { 142 for (int i = 0; i < gpuInfoArr.length; i++) { 143 if (gpuInfo.matches(gpuInfoArr[i])) { 144 return true; 145 } 146 } 147 } 148 return false; 149 } 150 151 private boolean inPreQualificationFilter(GLGPUInfo gpuInfo) { 152 GLGPUInfo[] preQualificationFilter = getPreQualificationFilter(); 153 if (preQualificationFilter == null) { 154 // We will consider any GPU if preQualificationFilter is null 155 return true; 156 } 157 return matches(gpuInfo, preQualificationFilter); 158 } 159 160 private boolean inBlackList(GLGPUInfo gpuInfo) { 161 return matches(gpuInfo, getBlackList()); 162 } 163 164 boolean isQualified(long nativeCtxInfo) { 165 // Read the GPU (graphics hardware) information and qualifying it by 166 // checking against the preQualificationFilter and the "blocking" 167 // blackLis. 168 GLGPUInfo gpuInfo = readGPUInfo(nativeCtxInfo); 169 170 if (gpuInfo.vendor == null || gpuInfo.model == null 171 || gpuInfo.vendor.contains("unknown") 172 || gpuInfo.model.contains("unknown")) { 173 // Return false if we can't determine the vendor and model of the 174 // gpu installed on the system 175 return false; 176 } 177 178 return inPreQualificationFilter(gpuInfo) && !inBlackList(gpuInfo); 179 } 180 181 abstract GLContext createGLContext(long nativeCtxInfo); 182 183 abstract GLContext createGLContext(GLDrawable drawable, 184 GLPixelFormat pixelFormat, GLContext shareCtx, boolean vSyncRequest); 185 186 abstract GLDrawable createGLDrawable(long nativeWindow, GLPixelFormat pixelFormat); 187 188 abstract GLDrawable createDummyGLDrawable(GLPixelFormat pixelFormat); 189 190 abstract GLPixelFormat createGLPixelFormat(long nativeScreen, GLPixelFormat.Attributes attrs); 191 192 boolean isGLGPUQualify() { 193 return isQualified(nativeCtxInfo); 194 } 195 196 abstract boolean initialize(Class psClass, GLPixelFormat.Attributes attrs); 197 198 GLContext getShareContext() { 199 if (shareCtx == null) { 200 shareCtx = createGLContext(nativeCtxInfo); 201 } 202 return shareCtx; 203 } 204 205 // Returns true if this pipe supports GL2 profile, false for GLES2 206 boolean isGL2() { 207 return gl2; 208 } 209 210 boolean isGLExtensionSupported(String sglExtStr) { 211 return nIsGLExtensionSupported(nativeCtxInfo, sglExtStr); 212 } 213 214 abstract int getAdapterCount(); 215 216 abstract int getAdapterOrdinal(long nativeScreen); 217 218 abstract void updateDeviceDetails(HashMap deviceDetails); 219 220 // JIRA: RT-21739 221 // TODO: This is a temporary mechanism to work well with Glass on Mac due 222 // to the CALayer work. Need to be removed in the early future for 3.0 223 void updateDeviceDetails(HashMap deviceDetails, GLContext glContext) { 224 // NOP for all platforms except for Mac which will override it in its 225 // platform specific implementation code 226 } 227 228 void printDriverInformation(int adapter) { 229 /* We are assuming a system with a single or homogeneous GPUs. */ 230 System.out.println("Graphics Vendor: " + nGetGLVendor(nativeCtxInfo)); 231 System.out.println(" Renderer: " + nGetGLRenderer(nativeCtxInfo)); 232 System.out.println(" Version: " + nGetGLVersion(nativeCtxInfo)); 233 } 234 }