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 }