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