< prev index next >

modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/PaintCollector.java

Print this page


   1 /*
   2  * Copyright (c) 2010, 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


 161                 // bad thing. It might have happened during shutdown,
 162                 // perhaps? Or somebody is poking the FX thread and
 163                 // asking it to interrupt. Either way, it means
 164                 // that we have not yet completed rendering some
 165                 // scenes and we're about to make a mess of things.
 166                 // Best thing to do is to retry.
 167             }
 168         }
 169     }
 170 
 171     /**
 172      * Gets whether there are any dirty scenes that need to be rendered. If
 173      * true, then a subsequent pulse event and renderAll call is required.
 174      *
 175      * @return Whether there are any dirty scenes that need to be rendered.
 176      */
 177     final boolean hasDirty() {
 178         return hasDirty;
 179     }
 180 







 181     /**
 182      * Adds a dirty scene to the PaintCollector for subsequent processing.
 183      * This method simply makes the PaintCollector aware of this new
 184      * scene and ensure it gets processed on the next call to renderAll.
 185      *
 186      * The next QuantumToolkit Glass timer generated pulse or PaintCollector
 187      * rendering vsync hinted pulse will process these dirty scenes.
 188      *
 189      * <p>This method must only be called on the FX Thread</p>
 190      *
 191      * @param scene    The scene which is dirty. This must not be null.
 192      */
 193     final void addDirtyScene(GlassScene scene) {
 194         // Check that we are on the expected thread.
 195         assert Thread.currentThread() == QuantumToolkit.getFxUserThread();
 196         // Scene must not be null (using assert for performance)
 197         assert scene != null;
 198 
 199         if (QuantumToolkit.verbose) {
 200             System.err.println("PC.addDirtyScene: " + System.nanoTime() + scene);
 201         }
 202 
 203         // Because dirtyScenes is ever only accessed from the FX Thread,
 204         // we don't need any form of concurrent access here. Note also
 205         // that doing a contains() call here is probably faster than using
 206         // a HashSet because we are dealing with such a small number of
 207         // scenes that simple iteration is likely to be much faster
 208         if (!dirtyScenes.contains(scene)) {
 209             dirtyScenes.add(scene);
 210             // Now that we know we have added a scene to dirtyScenes,
 211             // we should ensure hasDirty is true.
 212             hasDirty = true;
 213         }
 214     }
 215 
 216     /**
 217      * Removes a scene from the dirtyScene list. If the given scene
 218      * was previously added with a call to addDirtyScene, it will
 219      * be removed. Potentially this means that after this call the
 220      * PaintCollector will no longer have any dirty scenes and will
 221      * no longer require a repaint.
 222      *
 223      * <p>This method is typically called when a scene is removed
 224      * from a stage, or when visible becomes false.
 225      * </p>
 226      *
 227      * <p>This method must only be called on the FX Thread</p>
 228      *
 229      * @param scene    The scene which is no longer dirty. Must not be null.
 230      */
 231     final void removeDirtyScene(GlassScene scene) {
 232         // Ensure we're called only from the FX thread
 233         assert Thread.currentThread() == QuantumToolkit.getFxUserThread();
 234         assert scene != null;
 235 
 236         // Need to convert to use JavaFX Logging instead.
 237         if (QuantumToolkit.verbose) {
 238             System.err.println("PC.removeDirtyScene: " + scene);
 239         }
 240 
 241         // Remove the scene
 242         dirtyScenes.remove(scene);
 243         // Update hasDirty
 244         hasDirty = !dirtyScenes.isEmpty();
 245     }
 246 
 247     /**
 248      * Gets the CompletionListener which must be notified when a
 249      * GlassScene has completed rendering.
 250      *
 251      * @return The CompletionListener. Will never be null.
 252      */
 253     final CompletionListener getRendered() {
 254         return this;
 255     }
 256 
 257     /**
 258      * This object is a CompletionListener is registered with every GlassScene,
 259      * such that when the repaint has completed, this method is called.
 260      * This method will decrement the count on the allWorkCompletedLatch.
 261      */
 262     @Override public void done(RenderJob job) {
 263         // It would be better to have an assertive check that
 264         // this call is being made on the render thread, rather


 344         }
 345 
 346         // Since hasDirty can only be set to true from the FX Thread,
 347         // we can do just a simple boolean check here. If we don't
 348         // have any dirty scenes to process, then we are done.
 349         if (!hasDirty) {
 350             return;
 351         }
 352 
 353         // Because hasDirty is tied to dirtyScenes, it should
 354         // not be possible that we reach this point if dirtyScenes
 355         // is empty (since hasDirty was true)
 356         assert !dirtyScenes.isEmpty();
 357 
 358         // Sort the dirty scenes based on whether they are
 359         // synchronous or not. If they are not synchronous,
 360         // then we want to process them first.
 361         Collections.sort(dirtyScenes, DIRTY_SCENE_SORTER);
 362 
 363         // Reset the fields
 364         hasDirty = false;
 365         needsHint = false;
 366 
 367         // If pulse logging is enabled, then we must call renderStart
 368         // BEFORE we actually call repaint on any of the dirty scenes.
 369         if (PULSE_LOGGING_ENABLED) {
 370             PulseLogger.renderStart();
 371         }
 372 
 373         // This part needs to be handled a bit differently depending on whether our platform has a native
 374         // window manager or not.
 375         // So, check to see if we do (Note: how we determine this need to be improved, this should
 376         // eventually call down into platform-specific glass code and not rely on
 377         // a system property, but we will use this for now)
 378         if (!Application.GetApplication().hasWindowManager()) {
 379             // No native window manager.  We call repaint on every scene (to make sure it gets recopied
 380             // to the screen) but we may be able to skip some steps in the repaint.
 381 
 382             // Obtain a z-ordered window list from glass.  For platforms without a native window manager,
 383             // we need to recopy the all of the window contents to the screen on every frame.
 384             final List<com.sun.glass.ui.Window> glassWindowList = com.sun.glass.ui.Window.getWindows();


   1 /*
   2  * Copyright (c) 2010, 2018, 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


 161                 // bad thing. It might have happened during shutdown,
 162                 // perhaps? Or somebody is poking the FX thread and
 163                 // asking it to interrupt. Either way, it means
 164                 // that we have not yet completed rendering some
 165                 // scenes and we're about to make a mess of things.
 166                 // Best thing to do is to retry.
 167             }
 168         }
 169     }
 170 
 171     /**
 172      * Gets whether there are any dirty scenes that need to be rendered. If
 173      * true, then a subsequent pulse event and renderAll call is required.
 174      *
 175      * @return Whether there are any dirty scenes that need to be rendered.
 176      */
 177     final boolean hasDirty() {
 178         return hasDirty;
 179     }
 180 
 181     final void setDirty(boolean value) {
 182         hasDirty = value;
 183         if (hasDirty) {
 184             QuantumToolkit.getToolkit().requestNextPulse();
 185         }
 186     }
 187 
 188     /**
 189      * Adds a dirty scene to the PaintCollector for subsequent processing.
 190      * This method simply makes the PaintCollector aware of this new
 191      * scene and ensure it gets processed on the next call to renderAll.
 192      *
 193      * The next QuantumToolkit Glass timer generated pulse or PaintCollector
 194      * rendering vsync hinted pulse will process these dirty scenes.
 195      *
 196      * <p>This method must only be called on the FX Thread</p>
 197      *
 198      * @param scene    The scene which is dirty. This must not be null.
 199      */
 200     final void addDirtyScene(GlassScene scene) {
 201         // Check that we are on the expected thread.
 202         assert Thread.currentThread() == QuantumToolkit.getFxUserThread();
 203         // Scene must not be null (using assert for performance)
 204         assert scene != null;
 205 
 206         if (QuantumToolkit.verbose) {
 207             System.err.println("PC.addDirtyScene: " + System.nanoTime() + scene);
 208         }
 209 
 210         // Because dirtyScenes is ever only accessed from the FX Thread,
 211         // we don't need any form of concurrent access here. Note also
 212         // that doing a contains() call here is probably faster than using
 213         // a HashSet because we are dealing with such a small number of
 214         // scenes that simple iteration is likely to be much faster
 215         if (!dirtyScenes.contains(scene)) {
 216             dirtyScenes.add(scene);
 217             // Now that we know we have added a scene to dirtyScenes,
 218             // we should ensure hasDirty is true.
 219             setDirty(true);
 220         }
 221     }
 222 
 223     /**
 224      * Removes a scene from the dirtyScene list. If the given scene
 225      * was previously added with a call to addDirtyScene, it will
 226      * be removed. Potentially this means that after this call the
 227      * PaintCollector will no longer have any dirty scenes and will
 228      * no longer require a repaint.
 229      *
 230      * <p>This method is typically called when a scene is removed
 231      * from a stage, or when visible becomes false.
 232      * </p>
 233      *
 234      * <p>This method must only be called on the FX Thread</p>
 235      *
 236      * @param scene    The scene which is no longer dirty. Must not be null.
 237      */
 238     final void removeDirtyScene(GlassScene scene) {
 239         // Ensure we're called only from the FX thread
 240         assert Thread.currentThread() == QuantumToolkit.getFxUserThread();
 241         assert scene != null;
 242 
 243         // Need to convert to use JavaFX Logging instead.
 244         if (QuantumToolkit.verbose) {
 245             System.err.println("PC.removeDirtyScene: " + scene);
 246         }
 247 
 248         // Remove the scene
 249         dirtyScenes.remove(scene);
 250         // Update hasDirty
 251         setDirty(!dirtyScenes.isEmpty());
 252     }
 253 
 254     /**
 255      * Gets the CompletionListener which must be notified when a
 256      * GlassScene has completed rendering.
 257      *
 258      * @return The CompletionListener. Will never be null.
 259      */
 260     final CompletionListener getRendered() {
 261         return this;
 262     }
 263 
 264     /**
 265      * This object is a CompletionListener is registered with every GlassScene,
 266      * such that when the repaint has completed, this method is called.
 267      * This method will decrement the count on the allWorkCompletedLatch.
 268      */
 269     @Override public void done(RenderJob job) {
 270         // It would be better to have an assertive check that
 271         // this call is being made on the render thread, rather


 351         }
 352 
 353         // Since hasDirty can only be set to true from the FX Thread,
 354         // we can do just a simple boolean check here. If we don't
 355         // have any dirty scenes to process, then we are done.
 356         if (!hasDirty) {
 357             return;
 358         }
 359 
 360         // Because hasDirty is tied to dirtyScenes, it should
 361         // not be possible that we reach this point if dirtyScenes
 362         // is empty (since hasDirty was true)
 363         assert !dirtyScenes.isEmpty();
 364 
 365         // Sort the dirty scenes based on whether they are
 366         // synchronous or not. If they are not synchronous,
 367         // then we want to process them first.
 368         Collections.sort(dirtyScenes, DIRTY_SCENE_SORTER);
 369 
 370         // Reset the fields
 371         setDirty(false);
 372         needsHint = false;
 373 
 374         // If pulse logging is enabled, then we must call renderStart
 375         // BEFORE we actually call repaint on any of the dirty scenes.
 376         if (PULSE_LOGGING_ENABLED) {
 377             PulseLogger.renderStart();
 378         }
 379 
 380         // This part needs to be handled a bit differently depending on whether our platform has a native
 381         // window manager or not.
 382         // So, check to see if we do (Note: how we determine this need to be improved, this should
 383         // eventually call down into platform-specific glass code and not rely on
 384         // a system property, but we will use this for now)
 385         if (!Application.GetApplication().hasWindowManager()) {
 386             // No native window manager.  We call repaint on every scene (to make sure it gets recopied
 387             // to the screen) but we may be able to skip some steps in the repaint.
 388 
 389             // Obtain a z-ordered window list from glass.  For platforms without a native window manager,
 390             // we need to recopy the all of the window contents to the screen on every frame.
 391             final List<com.sun.glass.ui.Window> glassWindowList = com.sun.glass.ui.Window.getWindows();


< prev index next >