1 /* 2 * Copyright (c) 2013, 2015, 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; 27 28 import com.sun.glass.ui.Application; 29 import com.sun.glass.ui.Pixels; 30 import com.sun.glass.ui.Screen; 31 import com.sun.glass.ui.View; 32 import com.sun.glass.ui.Window; 33 34 /** 35 * PresentableState is intended to provide for a shadow copy of View/Window 36 * state for use off the event thread. It is the task of the invoker of 37 * Prism to make sure that the state is consistent for a rendering probably 38 * by use of the AbstractPainter.renderLock to ensure consistent state. 39 */ 40 public abstract class PresentableState { 41 42 /** The underlying Window and View */ 43 protected Window window; 44 protected View view; 45 46 // Captured state 47 protected int nativeFrameBuffer; 48 protected int windowX, windowY; 49 protected float windowAlpha; 50 protected long nativeWindowHandle; 51 protected long nativeView; 52 protected int viewWidth, viewHeight; 53 protected float renderScaleX, renderScaleY; 54 protected int renderWidth, renderHeight; 55 protected float outputScaleX, outputScaleY; 56 protected int outputWidth, outputHeight; 57 protected int screenHeight; 58 protected int screenWidth; 59 protected boolean isWindowVisible; 60 protected boolean isWindowMinimized; 61 protected static final boolean hasWindowManager = 62 Application.GetApplication().hasWindowManager(); 63 // Between PaintCollector and *Painter, there is a window where 64 // the associated View can be closed. This variable allows us 65 // to shortcut the queued *Painter task. 66 protected boolean isClosed; 67 protected final int pixelFormat = Pixels.getNativeFormat(); 68 69 /** Create a PresentableState based on a View. 70 * 71 * Must be called on the event thread. 72 */ 73 public PresentableState() { 74 } 75 76 /** 77 * The screen relative window X 78 * @return The screen relative window X 79 * 80 * May be called on any thread. 81 */ 82 public int getWindowX() { 83 return windowX; 84 } 85 86 /** 87 * The screen relative window Y 88 * @return The screen relative window Y 89 * 90 * May be called on any thread. 91 */ 92 public int getWindowY() { 93 return windowY; 94 } 95 96 /** 97 * @return the width of the View 98 * 99 * May be called on any thread. 100 */ 101 public int getWidth() { 102 return viewWidth; 103 } 104 105 /** 106 * @return the height of the View 107 * 108 * May be called on any thread. 109 */ 110 public int getHeight() { 111 return viewHeight; 112 } 113 114 public int getRenderWidth() { 115 return renderWidth; 116 } 117 118 public int getRenderHeight() { 119 return renderHeight; 120 } 121 122 public int getOutputWidth() { 123 return outputWidth; 124 } 125 126 public int getOutputHeight() { 127 return outputHeight; 128 } 129 130 /** 131 * @return Screen.getScale 132 * 133 * May be called on any thread 134 */ 135 public float getRenderScaleX() { 136 return renderScaleX; 137 } 138 139 /** 140 * @return Screen.getScale 141 * 142 * May be called on any thread 143 */ 144 public float getRenderScaleY() { 145 return renderScaleY; 146 } 147 148 public float getOutputScaleX() { 149 return outputScaleX; 150 } 151 152 public float getOutputScaleY() { 153 return outputScaleY; 154 } 155 156 /** 157 * @return the window's alpha level 158 * 159 * May be called on any thread. 160 */ 161 public float getAlpha() { 162 return windowAlpha; 163 } 164 165 /** 166 * @return the native handle of the window represented by this 167 * PresentableState 168 * 169 * May be called on any thread. 170 */ 171 public long getNativeWindow() { 172 return nativeWindowHandle; 173 } 174 175 /** 176 * @return the native handle of the View represented by this 177 * PresentableState 178 * 179 * May be called on any thread. 180 */ 181 public long getNativeView() { 182 return nativeView; 183 } 184 185 /** 186 * @return the current height of the screen 187 * 188 * May be called on any thread. 189 */ 190 public int getScreenHeight() { 191 return screenHeight; 192 } 193 194 /** 195 * @return the current width of the screen 196 * 197 * May be called on any thread. 198 */ 199 public int getScreenWidth() { 200 return screenWidth; 201 } 202 203 /** 204 * @return true if the underlying View is closed, false otherwise 205 * 206 * May be called on any thread. 207 */ 208 public boolean isViewClosed() { 209 return isClosed; 210 } 211 212 /** 213 * @return true if the underlying Window is minimized, false otherwise 214 * 215 * May be called on any thread. 216 */ 217 public boolean isWindowMinimized() { 218 return isWindowMinimized; 219 } 220 221 /** 222 * @return true if the underlying Window is Visible, false otherwise 223 * 224 * May be called on any thread. 225 */ 226 public boolean isWindowVisible() { 227 return isWindowVisible; 228 } 229 230 /** 231 * @return true if the underlying window is managed by a window manager 232 * external to JavaFX 233 * 234 * May be called on any thread. 235 */ 236 public boolean hasWindowManager() { 237 return hasWindowManager; 238 } 239 240 /** 241 * @return the underlying Window 242 * 243 * May be called on any thread. 244 */ 245 public Window getWindow() { 246 return window; 247 } 248 249 public boolean isMSAA() { return false; } 250 251 /** 252 * @return the underlying View 253 * 254 * May be called on any thread. 255 */ 256 public View getView() { 257 return view; 258 } 259 260 /** 261 * @return native pixel format 262 * 263 * May be called on any thread. 264 */ 265 public int getPixelFormat() { 266 return pixelFormat; 267 } 268 269 /** 270 * @return native native frame buffer 271 * 272 * May be called on any thread. 273 */ 274 public int getNativeFrameBuffer() { 275 return nativeFrameBuffer; 276 } 277 278 /** 279 * Locks the underlying view for rendering 280 * 281 * Must be called on Prism renderer thread. 282 */ 283 public void lock() { 284 if (view != null) { 285 view.lock(); 286 nativeFrameBuffer = view.getNativeFrameBuffer(); 287 } 288 } 289 290 /** 291 * Unlocks the underlying view after rendering 292 * 293 * Must be called on Prism renderer thread. 294 */ 295 public void unlock() { 296 if (view != null) view.unlock(); 297 } 298 299 /** 300 * Put the pixels on the screen. 301 * 302 * @param source - the source for the Pixels object to be uploaded 303 */ 304 public void uploadPixels(PixelSource source) { 305 Pixels pixels = source.getLatestPixels(); 306 if (pixels != null) { 307 try { 308 view.uploadPixels(pixels); 309 } finally { 310 source.doneWithPixels(pixels); 311 } 312 } 313 } 314 315 private int scale(int dim, float fromScale, float toScale) { 316 return (fromScale == toScale) 317 ? dim 318 : (int) Math.ceil(dim * toScale / fromScale); 319 } 320 321 protected void update(float viewScaleX, float viewScaleY, 322 float renderScaleX, float renderScaleY, 323 float outputScaleX, float outputScaleY) 324 { 325 this.renderScaleX = renderScaleX; 326 this.renderScaleY = renderScaleY; 327 this.outputScaleX = outputScaleX; 328 this.outputScaleY = outputScaleY; 329 if (renderScaleX == viewScaleX && renderScaleY == viewScaleY) { 330 renderWidth = viewWidth; 331 renderHeight = viewHeight; 332 } else { 333 renderWidth = scale(viewWidth, viewScaleX, renderScaleX); 334 renderHeight = scale(viewHeight, viewScaleY, renderScaleY); 335 } 336 if (outputScaleX == viewScaleX && outputScaleY == viewScaleY) { 337 outputWidth = viewWidth; 338 outputHeight = viewHeight; 339 } else if (outputScaleX == renderScaleX && outputScaleY == renderScaleY) { 340 outputWidth = renderWidth; 341 outputHeight = renderHeight; 342 } else { 343 outputWidth = scale(viewWidth, viewScaleX, outputScaleX); 344 outputHeight = scale(viewHeight, viewScaleY, outputScaleY); 345 } 346 } 347 348 /** Updates the state of this object based on the current state of its 349 * nativeWindow. 350 * 351 * May only be called from the event thread. 352 */ 353 public void update() { 354 // should only be called on the event thread 355 if (view != null) { 356 viewWidth = view.getWidth(); 357 viewHeight = view.getHeight(); 358 window = view.getWindow(); 359 } else { 360 viewWidth = viewHeight = -1; 361 window = null; 362 } 363 if (window != null) { 364 windowX = window.getX(); 365 windowY = window.getY(); 366 windowAlpha = window.getAlpha(); 367 nativeView = view.getNativeView(); 368 nativeWindowHandle = window.getNativeWindow(); 369 isClosed = view.isClosed(); 370 isWindowVisible = window.isVisible(); 371 isWindowMinimized = window.isMinimized(); 372 update(window.getPlatformScaleX(), window.getPlatformScaleY(), 373 window.getRenderScaleX(), window.getRenderScaleY(), 374 window.getOutputScaleX(), window.getOutputScaleY()); 375 Screen screen = window.getScreen(); 376 if (screen != null) { 377 // note only used by Embedded Z order painting 378 // !hasWindowManager so should be safe to ignore 379 // when null, most likely because of "In Browswer" 380 screenHeight = screen.getHeight(); 381 screenWidth = screen.getWidth(); 382 } 383 } else { 384 //TODO - should other variables be cleared? 385 nativeView = -1; 386 nativeWindowHandle = -1; 387 isClosed = true; 388 } 389 } 390 }