1 /*
   2  * Copyright (c) 2009, 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.glass.ui.Screen;
  29 import com.sun.glass.utils.NativeLibLoader;
  30 import com.sun.prism.GraphicsPipeline;
  31 import com.sun.prism.ResourceFactory;
  32 import com.sun.prism.impl.PrismSettings;
  33 import com.sun.javafx.PlatformUtil;
  34 import java.util.List;
  35 import java.security.AccessController;
  36 import java.security.PrivilegedAction;
  37 import java.util.HashMap;
  38 
  39 public class ES2Pipeline extends GraphicsPipeline {
  40 
  41     public static final GLFactory glFactory;
  42     public static final GLPixelFormat.Attributes
  43             pixelFormatAttributes = new GLPixelFormat.Attributes();
  44     static final boolean antiAliasingSupported;
  45     private static boolean es2Enabled;
  46     private static boolean isEglfb = false;
  47 
  48     static {
  49         AccessController.doPrivileged(new PrivilegedAction<Void>() {
  50 
  51             public Void run() {
  52                 String libName = "prism_es2";
  53 
  54                 String eglType = PlatformUtil.getEmbeddedType();
  55                 if ("eglfb".equals(eglType)) {
  56                     isEglfb = true;
  57                     libName = "prism_es2_eglfb";
  58                 }
  59                 else if ("monocle".equals(eglType)) {
  60                     isEglfb = true;
  61                     libName = "prism_es2_monocle";
  62                 }
  63                 else if ("eglx11".equals(eglType))
  64                     libName = "prism_es2_eglx11";
  65 
  66                 if (PrismSettings.verbose) {
  67                     System.out.println("Loading ES2 native library ... " + libName);
  68                 }
  69                 NativeLibLoader.loadLibrary(libName);
  70                 if (PrismSettings.verbose) {
  71                     System.out.println("\tsucceeded.");
  72                 }
  73                 return null;
  74             }
  75         });
  76 
  77         // Initialize the prism-es2 pipe and a handler of it
  78         glFactory = GLFactory.getFactory();
  79 
  80         creator = Thread.currentThread();
  81 
  82         if (glFactory != null) {
  83             es2Enabled = glFactory.initialize(PrismSettings.class,
  84                     pixelFormatAttributes);
  85         } else {
  86             es2Enabled = false;
  87         }
  88 
  89         if (es2Enabled) {
  90             theInstance = new ES2Pipeline();
  91             factories = new ES2ResourceFactory[glFactory.getAdapterCount()];
  92         } else {
  93             theInstance = null;
  94         }
  95 
  96         antiAliasingSupported = (glFactory.isGLExtensionSupported("GL_ARB_multisample"));
  97     }
  98     private static Thread creator;
  99     private static final ES2Pipeline theInstance;
 100     private static ES2ResourceFactory factories[];
 101 
 102     public static ES2Pipeline getInstance() {
 103         return theInstance;
 104     }
 105 
 106     @Override
 107     public boolean init() {
 108         if (es2Enabled) {
 109             HashMap devDetails = new HashMap();
 110             glFactory.updateDeviceDetails(devDetails);
 111             setDeviceDetails(devDetails);
 112             if (!PrismSettings.forceGPU) {
 113                 es2Enabled = glFactory.isGLGPUQualify();
 114                 if (PrismSettings.verbose) {
 115                     if (!es2Enabled) {
 116                         System.err.println("Failed Graphics Hardware Qualifier check."
 117                                 + "\nSystem GPU doesn't meet the es2 pipe requirement");
 118                     }
 119                 }
 120             }
 121         } else if (PrismSettings.verbose) {
 122             System.err.println("Failed to initialize ES2 backend: ");
 123         }
 124         return es2Enabled;
 125     }
 126 
 127     private static ES2ResourceFactory getES2ResourceFactory(int adapterOrdinal,
 128             Screen screen) {
 129         ES2ResourceFactory factory = factories[adapterOrdinal];
 130         if (factory == null && screen != null) {
 131             factory = new ES2ResourceFactory(screen);
 132             factories[adapterOrdinal] = factory;
 133         }
 134         return factory;
 135     }
 136 
 137     /*
 138      * we need screen only because BaseShaderContext requres Screen in the constructor
 139      */
 140     private static Screen getScreenForAdapter(List<Screen> screens, int adapterOrdinal) {
 141         for (Screen screen : screens) {
 142             if (glFactory.getAdapterOrdinal(screen.getNativeScreen()) == adapterOrdinal) {
 143                 return screen;
 144             }
 145         }
 146         return Screen.getMainScreen();
 147     }
 148 
 149     private static ES2ResourceFactory findDefaultResourceFactory(List<Screen> screens) {
 150         for (int adapter = 0, n = glFactory.getAdapterCount(); adapter != n; ++adapter) {
 151             ES2ResourceFactory rf =
 152                     getES2ResourceFactory(adapter, getScreenForAdapter(screens, adapter));
 153 
 154             if (rf != null) {
 155                 if (PrismSettings.verbose) {
 156                     glFactory.printDriverInformation(adapter);
 157                 }
 158                 return rf;
 159             } else {
 160                 if (!PrismSettings.disableBadDriverWarning) {
 161                     System.err.println("disableBadDriverWarning is unsupported on prism-es2");
 162 //                    printDriverWarning(adapter);
 163                 }
 164             }
 165         }
 166         return null;
 167     }
 168     ES2ResourceFactory _default;
 169 
 170     @Override
 171     public ResourceFactory getDefaultResourceFactory(List<Screen> screens) {
 172         if (_default == null) {
 173             _default = findDefaultResourceFactory(screens);
 174         }
 175         return _default;
 176     }
 177 
 178     @Override
 179     public ResourceFactory getResourceFactory(Screen screen) {
 180         return getES2ResourceFactory(
 181                 glFactory.getAdapterOrdinal(screen.getNativeScreen()), screen);
 182     }
 183 
 184     @Override
 185     public void dispose() {
 186         if (creator != Thread.currentThread()) {
 187             throw new IllegalStateException(
 188                     "This operation is not permitted on the current thread ["
 189                     + Thread.currentThread().getName() + "]");
 190         }
 191         if (isEglfb) {
 192             _default.dispose();
 193         }
 194         super.dispose();
 195     }
 196 
 197     @Override
 198     public boolean is3DSupported() {
 199         // It is okay to just returns true if we plan to support 3D on all
 200         // ES2 platforms that are PS 3 capable. However we are not ready to
 201         // support 3D on the embedded platform. Some of this platforms may be
 202         // PS 3 capable but have other limitations such as NPOT. 
 203         return PlatformUtil.isEmbedded() ? PlatformUtil.isEmbedded3DEnabled() : true;
 204     }
 205 
 206     @Override
 207     public final boolean isAntiAliasingSupported() {
 208         return antiAliasingSupported;
 209     }
 210 
 211     @Override
 212     public boolean isVsyncSupported() {
 213         return true;
 214     }
 215 
 216     @Override
 217     public boolean supportsShaderType(ShaderType type) {
 218         switch (type) {
 219             case GLSL:
 220                 return true;
 221             default:
 222                 return false;
 223         }
 224     }
 225 
 226     @Override
 227     public boolean supportsShaderModel(ShaderModel model) {
 228         switch (model) {
 229             case SM3:
 230                 return true;
 231             default:
 232                 return false;
 233         }
 234     }
 235 }