1 /* 2 * Copyright (c) 2008, 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.scenario.effect.compiler.backend.hw; 27 28 import java.util.HashMap; 29 import java.util.Map; 30 import com.sun.scenario.effect.compiler.JSLParser; 31 import com.sun.scenario.effect.compiler.model.Precision; 32 import com.sun.scenario.effect.compiler.tree.FuncDef; 33 import com.sun.scenario.effect.compiler.tree.ProgramUnit; 34 35 /** 36 */ 37 public class ES2Backend extends GLSLBackend { 38 39 public ES2Backend(JSLParser parser, ProgramUnit program) { 40 super(parser, program); 41 } 42 43 // GLSL v1.10 no longer has gl_TexCoord*; these are now passed in 44 // from vertex shader as texCoord0/1 45 private static final Map<String, String> varMap = new HashMap<String, String>(); 46 static { 47 varMap.put("pos0", "texCoord0"); 48 varMap.put("pos1", "texCoord1"); 49 varMap.put("color", "gl_FragColor"); 50 varMap.put("jsl_vertexColor", "perVertexColor"); 51 } 52 53 private static final Map<String, String> funcMap = new HashMap<String, String>(); 54 static { 55 funcMap.put("sample", "texture2D"); 56 funcMap.put("ddx", "dFdx"); 57 funcMap.put("ddy", "dFdy"); 58 funcMap.put("intcast", "int"); 59 } 60 61 @Override 62 protected String getVar(String v) { 63 String s = varMap.get(v); 64 return (s != null) ? s : v; 65 } 66 67 @Override 68 protected String getFuncName(String f) { 69 String s = funcMap.get(f); 70 return (s != null) ? s : f; 71 } 72 73 @Override 74 protected String getPrecision(Precision p) { 75 return p.name(); 76 } 77 78 @Override 79 public void visitFuncDef(FuncDef d) { 80 // this is a hack to help force the return value of certain Prism 81 // shader functions to have lower precision 82 String name = d.getFunction().getName(); 83 if ("mask".equals(name) || "paint".equals(name)) { 84 output("lowp "); 85 } 86 super.visitFuncDef(d); 87 } 88 89 @Override 90 protected String getHeader() { 91 StringBuilder sb = new StringBuilder(); 92 // For the time being we are attempting to generate fragment programs 93 // that will run on the desktop and on OpenGL ES 2.0 devices. 94 // For OpenGL ES 2.0, fragment programs are required to specify the 95 // precision for all variables. Also for ES 2.0, the default GLSL 96 // version is 1.00, so implicitly we are using "#version 100" for 97 // that case. We are not yet taking advantage of language features 98 // above (desktop GLSL) version 1.10 so we can get away with not 99 // including the #version directive here (it will implicitly be 100 // "#version 110" for the desktop case). It appears that the 101 // desktop and ES versions of the GLSL spec may continue to be 102 // developed independently (see section 10.23 in the GLSL ES spec), 103 // so if we ever need to use a higher version for one case or the 104 // other, it will get awkward since the #version string has to be 105 // the first thing in the file (i.e., you can't put it inside the 106 // "#ifdef GL_ES" section). 107 // TODO: We are currently using highp across the board if it is 108 // supported just to be safe, but there are likely many variables 109 // that could live with mediump or lowp; should experiment with 110 // using lower precision by default... 111 sb.append("#ifdef GL_ES\n"); 112 sb.append("#extension GL_OES_standard_derivatives : enable\n"); 113 sb.append("#ifdef GL_FRAGMENT_PRECISION_HIGH\n"); 114 sb.append("precision highp float;\n"); 115 sb.append("precision highp int;\n"); 116 sb.append("#else\n"); 117 sb.append("precision mediump float;\n"); 118 sb.append("precision mediump int;\n"); 119 sb.append("#endif\n"); 120 sb.append("#else\n"); 121 sb.append("#define highp\n"); 122 sb.append("#define mediump\n"); 123 sb.append("#define lowp\n"); 124 sb.append("#endif\n"); 125 126 // output varying value declarations (passed from the vertex shader) 127 if (maxTexCoordIndex >= 0) { 128 sb.append("varying vec2 texCoord0;\n"); 129 } 130 if (maxTexCoordIndex >= 1) { 131 sb.append("varying vec2 texCoord1;\n"); 132 } 133 if (isVertexColorReferenced) { 134 sb.append("varying lowp vec4 perVertexColor;\n"); 135 } 136 137 // output special pixcoord offset uniform variable declaration 138 // at the top of the program, if needed 139 if (isPixcoordReferenced) { 140 sb.append("uniform vec4 jsl_pixCoordOffset;\n"); 141 sb.append("vec2 pixcoord = vec2(\n"); 142 sb.append(" gl_FragCoord.x-jsl_pixCoordOffset.x,\n"); 143 sb.append(" ((jsl_pixCoordOffset.z-gl_FragCoord.y)*jsl_pixCoordOffset.w)-jsl_pixCoordOffset.y);\n"); 144 } 145 146 return sb.toString(); 147 } 148 }