43 import com.sun.javafx.embed.EmbeddedSceneDTInterface; 44 import com.sun.javafx.embed.EmbeddedSceneInterface; 45 import com.sun.javafx.embed.HostInterface; 46 import com.sun.javafx.scene.input.KeyCodeMap; 47 import com.sun.javafx.scene.traversal.Direction; 48 import com.sun.javafx.sg.prism.NGNode; 49 import com.sun.javafx.tk.TKClipboard; 50 import com.sun.javafx.tk.Toolkit; 51 import com.sun.prism.paint.Color; 52 import com.sun.prism.paint.Paint; 53 import com.sun.glass.ui.Pixels; 54 import java.nio.ByteOrder; 55 56 final class EmbeddedScene extends GlassScene implements EmbeddedSceneInterface { 57 58 // TODO: synchronize access to embedder from ET and RT 59 private HostInterface host; 60 61 private UploadingPainter painter; 62 private PaintRenderJob paintRenderJob; 63 private float renderScale; 64 65 private final EmbeddedSceneDnD embeddedDnD; 66 67 private volatile IntBuffer texBits; 68 private volatile int texLineStride; // pre-scaled 69 private volatile float texScaleFactor = 1.0f; 70 71 private volatile PixelFormat<?> pixelFormat; 72 73 public EmbeddedScene(HostInterface host, boolean depthBuffer, boolean msaa) { 74 super(depthBuffer, msaa); 75 sceneState = new EmbeddedState(this); 76 77 this.host = host; 78 this.embeddedDnD = new EmbeddedSceneDnD(this); 79 80 PaintCollector collector = PaintCollector.getInstance(); 81 painter = new UploadingPainter(this); 82 paintRenderJob = new PaintRenderJob(this, collector.getRendered(), painter); 83 84 int nativeFormat = Pixels.getNativeFormat(); 85 ByteOrder byteorder = ByteOrder.nativeOrder(); 86 87 if (nativeFormat == Pixels.Format.BYTE_BGRA_PRE && 88 byteorder == ByteOrder.LITTLE_ENDIAN) 89 { 132 @Override 133 public TKClipboard createDragboard(boolean isDragSource) { 134 return embeddedDnD.createDragboard(isDragSource); 135 } 136 137 @Override 138 public void enableInputMethodEvents(boolean enable) { 139 if (QuantumToolkit.verbose) { 140 System.err.println("EmbeddedScene.enableInputMethodEvents " + enable); 141 } 142 } 143 144 @Override 145 public void finishInputMethodComposition() { 146 if (QuantumToolkit.verbose) { 147 System.err.println("EmbeddedScene.finishInputMethodComposition"); 148 } 149 } 150 151 @Override 152 public void setPixelScaleFactor(float scale) { 153 renderScale = scale; 154 entireSceneNeedsRepaint(); 155 } 156 157 public float getRenderScale() { 158 return renderScale; 159 } 160 161 public PixelFormat<?> getPixelFormat() { 162 return pixelFormat; 163 } 164 165 // Called by EmbeddedPainter on the render thread under renderLock 166 void uploadPixels(Pixels pixels) { 167 texBits = (IntBuffer)pixels.getPixels(); 168 texLineStride = pixels.getWidthUnsafe(); 169 texScaleFactor = pixels.getScaleUnsafe(); 170 if (host != null) { 171 host.repaint(); 172 } 173 } 174 175 // EmbeddedSceneInterface methods 176 177 @Override 178 public void repaint() { 179 Toolkit tk = Toolkit.getToolkit(); 180 tk.addRenderJob(paintRenderJob); 181 } 182 183 @Override 184 public boolean traverseOut(Direction dir) { 185 if (dir == Direction.NEXT) { 186 return host.traverseFocusOut(true); 187 } else if (dir == Direction.PREVIOUS) { 188 return host.traverseFocusOut(false); 189 } 199 } 200 return null; 201 }, getAccessControlContext()); 202 }); 203 } 204 205 /** 206 * @param dest the destination buffer 207 * @param width the logical width of the buffer 208 * @param height the logical height of the buffer 209 * @param scale the scale factor 210 * @return 211 */ 212 @Override 213 public boolean getPixels(final IntBuffer dest, final int width, final int height) { 214 return QuantumToolkit.runWithRenderLock(() -> { 215 int scaledWidth = width; 216 int scaledHeight = height; 217 218 // The dest buffer scale factor is expected to match painter.getPixelScaleFactor(). 219 if (getRenderScale() != texScaleFactor || texBits == null) { 220 return false; 221 } 222 scaledWidth = (int)Math.round(scaledWidth * texScaleFactor); 223 scaledHeight = (int)Math.round(scaledHeight * texScaleFactor); 224 225 dest.rewind(); 226 texBits.rewind(); 227 if (dest.capacity() != texBits.capacity()) { 228 // Calculate the intersection of the dest & src images. 229 int w = Math.min(scaledWidth, texLineStride); 230 int h = Math.min(scaledHeight, texBits.capacity() / texLineStride); 231 232 // Copy the intersection to the dest. 233 // The backed array of the textureBits may not be available, 234 // so not relying on it. 235 int[] linebuf = new int[w]; 236 for (int i = 0; i < h; i++) { 237 texBits.position(i * texLineStride); 238 texBits.get(linebuf, 0, w); 239 dest.position(i * scaledWidth); 240 dest.put(linebuf); 241 } 242 return true; 243 } | 43 import com.sun.javafx.embed.EmbeddedSceneDTInterface; 44 import com.sun.javafx.embed.EmbeddedSceneInterface; 45 import com.sun.javafx.embed.HostInterface; 46 import com.sun.javafx.scene.input.KeyCodeMap; 47 import com.sun.javafx.scene.traversal.Direction; 48 import com.sun.javafx.sg.prism.NGNode; 49 import com.sun.javafx.tk.TKClipboard; 50 import com.sun.javafx.tk.Toolkit; 51 import com.sun.prism.paint.Color; 52 import com.sun.prism.paint.Paint; 53 import com.sun.glass.ui.Pixels; 54 import java.nio.ByteOrder; 55 56 final class EmbeddedScene extends GlassScene implements EmbeddedSceneInterface { 57 58 // TODO: synchronize access to embedder from ET and RT 59 private HostInterface host; 60 61 private UploadingPainter painter; 62 private PaintRenderJob paintRenderJob; 63 private float renderScaleX; 64 private float renderScaleY; 65 66 private final EmbeddedSceneDnD embeddedDnD; 67 68 private volatile IntBuffer texBits; 69 private volatile int texLineStride; // pre-scaled 70 private volatile float texScaleFactorX = 1.0f; 71 private volatile float texScaleFactorY = 1.0f; 72 73 private volatile PixelFormat<?> pixelFormat; 74 75 public EmbeddedScene(HostInterface host, boolean depthBuffer, boolean msaa) { 76 super(depthBuffer, msaa); 77 sceneState = new EmbeddedState(this); 78 79 this.host = host; 80 this.embeddedDnD = new EmbeddedSceneDnD(this); 81 82 PaintCollector collector = PaintCollector.getInstance(); 83 painter = new UploadingPainter(this); 84 paintRenderJob = new PaintRenderJob(this, collector.getRendered(), painter); 85 86 int nativeFormat = Pixels.getNativeFormat(); 87 ByteOrder byteorder = ByteOrder.nativeOrder(); 88 89 if (nativeFormat == Pixels.Format.BYTE_BGRA_PRE && 90 byteorder == ByteOrder.LITTLE_ENDIAN) 91 { 134 @Override 135 public TKClipboard createDragboard(boolean isDragSource) { 136 return embeddedDnD.createDragboard(isDragSource); 137 } 138 139 @Override 140 public void enableInputMethodEvents(boolean enable) { 141 if (QuantumToolkit.verbose) { 142 System.err.println("EmbeddedScene.enableInputMethodEvents " + enable); 143 } 144 } 145 146 @Override 147 public void finishInputMethodComposition() { 148 if (QuantumToolkit.verbose) { 149 System.err.println("EmbeddedScene.finishInputMethodComposition"); 150 } 151 } 152 153 @Override 154 public void setPixelScaleFactors(float scalex, float scaley) { 155 renderScaleX = scalex; 156 renderScaleY = scaley; 157 entireSceneNeedsRepaint(); 158 } 159 160 public float getRenderScaleX() { 161 return renderScaleX; 162 } 163 164 public float getRenderScaleY() { 165 return renderScaleY; 166 } 167 168 @Override 169 public PixelFormat<?> getPixelFormat() { 170 return pixelFormat; 171 } 172 173 // Called by EmbeddedPainter on the render thread under renderLock 174 void uploadPixels(Pixels pixels) { 175 texBits = (IntBuffer)pixels.getPixels(); 176 texLineStride = pixels.getWidthUnsafe(); 177 texScaleFactorX = pixels.getScaleXUnsafe(); 178 texScaleFactorY = pixels.getScaleYUnsafe(); 179 if (host != null) { 180 host.repaint(); 181 } 182 } 183 184 // EmbeddedSceneInterface methods 185 186 @Override 187 public void repaint() { 188 Toolkit tk = Toolkit.getToolkit(); 189 tk.addRenderJob(paintRenderJob); 190 } 191 192 @Override 193 public boolean traverseOut(Direction dir) { 194 if (dir == Direction.NEXT) { 195 return host.traverseFocusOut(true); 196 } else if (dir == Direction.PREVIOUS) { 197 return host.traverseFocusOut(false); 198 } 208 } 209 return null; 210 }, getAccessControlContext()); 211 }); 212 } 213 214 /** 215 * @param dest the destination buffer 216 * @param width the logical width of the buffer 217 * @param height the logical height of the buffer 218 * @param scale the scale factor 219 * @return 220 */ 221 @Override 222 public boolean getPixels(final IntBuffer dest, final int width, final int height) { 223 return QuantumToolkit.runWithRenderLock(() -> { 224 int scaledWidth = width; 225 int scaledHeight = height; 226 227 // The dest buffer scale factor is expected to match painter.getPixelScaleFactor(). 228 if (getRenderScaleX() != texScaleFactorX || 229 getRenderScaleY() != texScaleFactorY || 230 texBits == null) 231 { 232 return false; 233 } 234 scaledWidth = Math.round(scaledWidth * texScaleFactorX); 235 scaledHeight = Math.round(scaledHeight * texScaleFactorY); 236 237 dest.rewind(); 238 texBits.rewind(); 239 if (dest.capacity() != texBits.capacity()) { 240 // Calculate the intersection of the dest & src images. 241 int w = Math.min(scaledWidth, texLineStride); 242 int h = Math.min(scaledHeight, texBits.capacity() / texLineStride); 243 244 // Copy the intersection to the dest. 245 // The backed array of the textureBits may not be available, 246 // so not relying on it. 247 int[] linebuf = new int[w]; 248 for (int i = 0; i < h; i++) { 249 texBits.position(i * texLineStride); 250 texBits.get(linebuf, 0, w); 251 dest.position(i * scaledWidth); 252 dest.put(linebuf); 253 } 254 return true; 255 } |