1 /* 2 * Copyright (c) 2019, 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 sun.java2d.metal; 27 28 import sun.java2d.pipe.BufferedContext; 29 import sun.java2d.pipe.RenderBuffer; 30 import sun.java2d.pipe.RenderQueue; 31 import sun.java2d.pipe.hw.ContextCapabilities; 32 33 import java.lang.annotation.Native; 34 35 import static sun.java2d.pipe.BufferedOpCodes.*; 36 37 /** 38 * Note that the RenderQueue lock must be acquired before calling any of 39 * the methods in this class. 40 */ 41 public class MTLContext extends BufferedContext { 42 43 private final MTLGraphicsConfigBase config; 44 45 public MTLContext(RenderQueue rq, MTLGraphicsConfigBase config) { 46 super(rq); 47 this.config = config; 48 } 49 50 /** 51 * Convenience method that delegates to setScratchSurface() below. 52 */ 53 static void setScratchSurface(MTLGraphicsConfigBase gc) { 54 setScratchSurface(gc.getNativeConfigInfo()); 55 } 56 57 /** 58 * Makes the given GraphicsConfig's context current to its associated 59 * "scratch surface". Each GraphicsConfig maintains a native context 60 * (MTLDevice) as well as a native pbuffer 61 * known as the "scratch surface". By making the context current to the 62 * scratch surface, we are assured that we have a current context for 63 * the relevant GraphicsConfig, and can therefore perform operations 64 * depending on the capabilities of that GraphicsConfig. 65 * This method should be used for operations with an MTL texture 66 * as the destination surface (e.g. a sw->texture blit loop), or in those 67 * situations where we may not otherwise have a current context (e.g. 68 * when disposing a texture-based surface). 69 */ 70 public static void setScratchSurface(long pConfigInfo) { 71 // assert MTLRenderQueue.getInstance().lock.isHeldByCurrentThread(); 72 73 // invalidate the current context 74 currentContext = null; 75 76 // set the scratch context 77 MTLRenderQueue rq = MTLRenderQueue.getInstance(); 78 RenderBuffer buf = rq.getBuffer(); 79 rq.ensureCapacityAndAlignment(12, 4); 80 buf.putInt(SET_SCRATCH_SURFACE); 81 buf.putLong(pConfigInfo); 82 } 83 84 /** 85 * Invalidates the currentContext field to ensure that we properly 86 * revalidate the MTLContext (make it current, etc.) next time through 87 * the validate() method. This is typically invoked from methods 88 * that affect the current context state (e.g. disposing a context or 89 * surface). 90 */ 91 public static void invalidateCurrentContext() { 92 // assert MTLRenderQueue.getInstance().lock.isHeldByCurrentThread(); 93 94 // invalidate the current Java-level context so that we 95 // revalidate everything the next time around 96 if (currentContext != null) { 97 currentContext.invalidateContext(); 98 currentContext = null; 99 } 100 101 // invalidate the context reference at the native level, and 102 // then flush the queue so that we have no pending operations 103 // dependent on the current context 104 MTLRenderQueue rq = MTLRenderQueue.getInstance(); 105 rq.ensureCapacity(4); 106 rq.getBuffer().putInt(INVALIDATE_CONTEXT); 107 rq.flushNow(); 108 } 109 110 public RenderQueue getRenderQueue() { 111 return MTLRenderQueue.getInstance(); 112 } 113 114 /** 115 * Returns a string representing adapter id (vendor, renderer, version). 116 * Must be called on the rendering thread. 117 * 118 * @return an id string for the adapter 119 */ 120 public static final native String getMTLIdString(); 121 122 @Override 123 public void saveState() { 124 // assert rq.lock.isHeldByCurrentThread(); 125 126 // reset all attributes of this and current contexts 127 invalidateContext(); 128 invalidateCurrentContext(); 129 130 setScratchSurface(config); 131 132 // save the state on the native level 133 rq.ensureCapacity(4); 134 buf.putInt(SAVE_STATE); 135 rq.flushNow(); 136 } 137 138 @Override 139 public void restoreState() { 140 // assert rq.lock.isHeldByCurrentThread(); 141 142 // reset all attributes of this and current contexts 143 invalidateContext(); 144 invalidateCurrentContext(); 145 146 setScratchSurface(config); 147 148 // restore the state on the native level 149 rq.ensureCapacity(4); 150 buf.putInt(RESTORE_STATE); 151 rq.flushNow(); 152 } 153 154 public static class MTLContextCaps extends ContextCapabilities { 155 /** 156 * This cap will only be set if the fbobject system property has been 157 * enabled and we are able to create an FBO with depth buffer. 158 */ 159 @Native 160 public static final int CAPS_EXT_FBOBJECT = 161 (CAPS_RT_TEXTURE_ALPHA | CAPS_RT_TEXTURE_OPAQUE); 162 /** Indicates that the context is doublebuffered. */ 163 @Native 164 public static final int CAPS_DOUBLEBUFFERED = (FIRST_PRIVATE_CAP << 0); 165 /** 166 * This cap will only be set if the lcdshader system property has been 167 * enabled and the hardware supports the minimum number of texture units 168 */ 169 @Native 170 static final int CAPS_EXT_LCD_SHADER = (FIRST_PRIVATE_CAP << 1); 171 /** 172 * This cap will only be set if the biopshader system property has been 173 * enabled and the hardware meets our minimum requirements. 174 */ 175 @Native 176 static final int CAPS_EXT_BIOP_SHADER = (FIRST_PRIVATE_CAP << 2); 177 /** 178 * This cap will only be set if the gradshader system property has been 179 * enabled and the hardware meets our minimum requirements. 180 */ 181 @Native 182 static final int CAPS_EXT_GRAD_SHADER = (FIRST_PRIVATE_CAP << 3); 183 /** Indicates the presence of the GL_ARB_texture_rectangle extension. */ 184 @Native 185 static final int CAPS_EXT_TEXRECT = (FIRST_PRIVATE_CAP << 4); 186 /** Indicates the presence of the GL_NV_texture_barrier extension. */ 187 @Native 188 static final int CAPS_EXT_TEXBARRIER = (FIRST_PRIVATE_CAP << 5); 189 190 191 public MTLContextCaps(int caps, String adapterId) { 192 super(caps, adapterId); 193 } 194 195 @Override 196 public String toString() { 197 StringBuilder sb = new StringBuilder(super.toString()); 198 if ((caps & CAPS_EXT_FBOBJECT) != 0) { 199 sb.append("CAPS_EXT_FBOBJECT|"); 200 } 201 if ((caps & CAPS_DOUBLEBUFFERED) != 0) { 202 sb.append("CAPS_DOUBLEBUFFERED|"); 203 } 204 if ((caps & CAPS_EXT_LCD_SHADER) != 0) { 205 sb.append("CAPS_EXT_LCD_SHADER|"); 206 } 207 if ((caps & CAPS_EXT_BIOP_SHADER) != 0) { 208 sb.append("CAPS_BIOP_SHADER|"); 209 } 210 if ((caps & CAPS_EXT_GRAD_SHADER) != 0) { 211 sb.append("CAPS_EXT_GRAD_SHADER|"); 212 } 213 if ((caps & CAPS_EXT_TEXRECT) != 0) { 214 sb.append("CAPS_EXT_TEXRECT|"); 215 } 216 if ((caps & CAPS_EXT_TEXBARRIER) != 0) { 217 sb.append("CAPS_EXT_TEXBARRIER|"); 218 } 219 return sb.toString(); 220 } 221 } 222 }