modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGNode.java

Print this page




  36 import com.sun.javafx.geom.Point2D;
  37 import com.sun.javafx.geom.RectBounds;
  38 import com.sun.javafx.geom.Rectangle;
  39 import com.sun.javafx.geom.transform.Affine3D;
  40 import com.sun.javafx.geom.transform.BaseTransform;
  41 import com.sun.javafx.geom.transform.GeneralTransform3D;
  42 import com.sun.javafx.geom.transform.NoninvertibleTransformException;
  43 import com.sun.prism.CompositeMode;
  44 import com.sun.prism.Graphics;
  45 import com.sun.prism.GraphicsPipeline;
  46 import com.sun.prism.RTTexture;
  47 import com.sun.prism.ReadbackGraphics;
  48 import com.sun.prism.impl.PrismSettings;
  49 import com.sun.scenario.effect.Blend;
  50 import com.sun.scenario.effect.Effect;
  51 import com.sun.scenario.effect.FilterContext;
  52 import com.sun.scenario.effect.ImageData;
  53 import com.sun.scenario.effect.impl.prism.PrDrawable;
  54 import com.sun.scenario.effect.impl.prism.PrEffectHelper;
  55 import com.sun.scenario.effect.impl.prism.PrFilterContext;
  56 import static com.sun.javafx.logging.PulseLogger.PULSE_LOGGER;
  57 import static com.sun.javafx.logging.PulseLogger.PULSE_LOGGING_ENABLED;
  58 
  59 /**
  60  * NGNode is the abstract base class peer of Node, forming
  61  * the basis for Prism and Scenario render graphs.
  62  * <p>
  63  * During synchronization, the FX scene graph will pass down to us
  64  * the transform which takes us from local space to parent space, the
  65  * content bounds (ie: geom bounds), and the transformed bounds
  66  * (ie: boundsInParent), and the clippedBounds. The effect bounds have
  67  * already been passed to the Effect peer (if there is one).
  68  * <p>
  69  * Whenever the transformedBounds of the NGNode are changed, we update
  70  * the dirtyBounds, so that the next time we need to accumulate dirty
  71  * regions, we will have the information we need to make sure we create
  72  * an appropriate dirty region.
  73  * <p>
  74  * NGNode maintains a single "dirty" flag, which indicates that this
  75  * node itself is dirty and must contribute to the dirty region. More
  76  * specifically, it indicates that this node is now dirty with respect


1928         return false;
1929     }
1930 
1931     /***************************************************************************
1932      *                                                                         *
1933      * Rendering                                                               *
1934      *                                                                         *
1935      **************************************************************************/
1936 
1937     /**
1938      * Render the tree of nodes to the specified G (graphics) object
1939      * descending from this node as the root. This method is designed to avoid
1940      * generated trash as much as possible while descending through the
1941      * render graph while rendering. This is the appropriate method both to
1942      * initiate painting of an entire scene, and for a branch. The NGGroup
1943      * implementation must call this method on each child, not doRender directly.
1944      *
1945      * @param g The graphics object we're rendering to. This must never be null.
1946      */
1947     public final void render(Graphics g) {
1948         if (PULSE_LOGGING_ENABLED) PULSE_LOGGER.renderIncrementCounter("Nodes visited during render");
1949         // Clear the visuals changed flag
1950         clearDirty();
1951         // If it isn't visible, then punt
1952         if (!visible || opacity == 0f) return;
1953 
1954         // We know that we are going to render this node, so we call the
1955         // doRender method, which subclasses implement to do the actual
1956         // rendering work.
1957         doRender(g);
1958     }
1959 
1960     // This node requires 2D graphics state for rendering
1961     boolean isShape3D() {
1962         return false;
1963     }
1964 
1965     /**
1966      * Invoked only by the final render method. Implementations
1967      * of this method should make sure to save & restore the transform state.
1968      */


2047             p = true;
2048         } else {
2049             renderContent(g);
2050             if (PrismSettings.showOverdraw) {
2051                 p = this instanceof NGRegion || !(this instanceof NGGroup);
2052             }
2053         }
2054 
2055         if (preCullingTurnedOff) {
2056             g.setHasPreCullingBits(true);
2057         }
2058 
2059         // restore previous transform state
2060         g.setTransform3D(mxx, mxy, mxz, mxt,
2061                          myx, myy, myz, myt,
2062                          mzx, mzy, mzz, mzt);
2063 
2064         // restore previous depth test state
2065         g.setDepthTest(prevDepthTest);
2066 
2067         if (PULSE_LOGGING_ENABLED) PULSE_LOGGER.renderIncrementCounter("Nodes rendered");
2068 
2069         // Used for debug purposes. This is not entirely accurate, as it doesn't measure the
2070         // number of times this node drew to the pixels, and in some cases reports a node as
2071         // having been drawn even when it didn't lay down any pixels. We'd need to integrate
2072         // with our shaders or do something much more invasive to get better data here.
2073         if (PrismSettings.showOverdraw) {
2074             if (p) {
2075                 painted |= 3 << (g.getClipRectIndex() * 2);
2076             } else {
2077                 painted |= 1 << (g.getClipRectIndex() * 2);
2078             }
2079         }
2080     }
2081 
2082     /**
2083      * Return true if this node has a blend mode that requires special
2084      * processing.
2085      * Regular nodes can handle null or SRC_OVER just by rendering into
2086      * the existing buffer.
2087      * Groups override this since they must collect their children into




  36 import com.sun.javafx.geom.Point2D;
  37 import com.sun.javafx.geom.RectBounds;
  38 import com.sun.javafx.geom.Rectangle;
  39 import com.sun.javafx.geom.transform.Affine3D;
  40 import com.sun.javafx.geom.transform.BaseTransform;
  41 import com.sun.javafx.geom.transform.GeneralTransform3D;
  42 import com.sun.javafx.geom.transform.NoninvertibleTransformException;
  43 import com.sun.prism.CompositeMode;
  44 import com.sun.prism.Graphics;
  45 import com.sun.prism.GraphicsPipeline;
  46 import com.sun.prism.RTTexture;
  47 import com.sun.prism.ReadbackGraphics;
  48 import com.sun.prism.impl.PrismSettings;
  49 import com.sun.scenario.effect.Blend;
  50 import com.sun.scenario.effect.Effect;
  51 import com.sun.scenario.effect.FilterContext;
  52 import com.sun.scenario.effect.ImageData;
  53 import com.sun.scenario.effect.impl.prism.PrDrawable;
  54 import com.sun.scenario.effect.impl.prism.PrEffectHelper;
  55 import com.sun.scenario.effect.impl.prism.PrFilterContext;
  56 import com.sun.javafx.logging.PulseLogger;
  57 import static com.sun.javafx.logging.PulseLogger.PULSE_LOGGING_ENABLED;
  58 
  59 /**
  60  * NGNode is the abstract base class peer of Node, forming
  61  * the basis for Prism and Scenario render graphs.
  62  * <p>
  63  * During synchronization, the FX scene graph will pass down to us
  64  * the transform which takes us from local space to parent space, the
  65  * content bounds (ie: geom bounds), and the transformed bounds
  66  * (ie: boundsInParent), and the clippedBounds. The effect bounds have
  67  * already been passed to the Effect peer (if there is one).
  68  * <p>
  69  * Whenever the transformedBounds of the NGNode are changed, we update
  70  * the dirtyBounds, so that the next time we need to accumulate dirty
  71  * regions, we will have the information we need to make sure we create
  72  * an appropriate dirty region.
  73  * <p>
  74  * NGNode maintains a single "dirty" flag, which indicates that this
  75  * node itself is dirty and must contribute to the dirty region. More
  76  * specifically, it indicates that this node is now dirty with respect


1928         return false;
1929     }
1930 
1931     /***************************************************************************
1932      *                                                                         *
1933      * Rendering                                                               *
1934      *                                                                         *
1935      **************************************************************************/
1936 
1937     /**
1938      * Render the tree of nodes to the specified G (graphics) object
1939      * descending from this node as the root. This method is designed to avoid
1940      * generated trash as much as possible while descending through the
1941      * render graph while rendering. This is the appropriate method both to
1942      * initiate painting of an entire scene, and for a branch. The NGGroup
1943      * implementation must call this method on each child, not doRender directly.
1944      *
1945      * @param g The graphics object we're rendering to. This must never be null.
1946      */
1947     public final void render(Graphics g) {
1948         if (PULSE_LOGGING_ENABLED) PulseLogger.incrementCounter("Nodes visited during render");
1949         // Clear the visuals changed flag
1950         clearDirty();
1951         // If it isn't visible, then punt
1952         if (!visible || opacity == 0f) return;
1953 
1954         // We know that we are going to render this node, so we call the
1955         // doRender method, which subclasses implement to do the actual
1956         // rendering work.
1957         doRender(g);
1958     }
1959 
1960     // This node requires 2D graphics state for rendering
1961     boolean isShape3D() {
1962         return false;
1963     }
1964 
1965     /**
1966      * Invoked only by the final render method. Implementations
1967      * of this method should make sure to save & restore the transform state.
1968      */


2047             p = true;
2048         } else {
2049             renderContent(g);
2050             if (PrismSettings.showOverdraw) {
2051                 p = this instanceof NGRegion || !(this instanceof NGGroup);
2052             }
2053         }
2054 
2055         if (preCullingTurnedOff) {
2056             g.setHasPreCullingBits(true);
2057         }
2058 
2059         // restore previous transform state
2060         g.setTransform3D(mxx, mxy, mxz, mxt,
2061                          myx, myy, myz, myt,
2062                          mzx, mzy, mzz, mzt);
2063 
2064         // restore previous depth test state
2065         g.setDepthTest(prevDepthTest);
2066 
2067         if (PULSE_LOGGING_ENABLED) PulseLogger.incrementCounter("Nodes rendered");
2068 
2069         // Used for debug purposes. This is not entirely accurate, as it doesn't measure the
2070         // number of times this node drew to the pixels, and in some cases reports a node as
2071         // having been drawn even when it didn't lay down any pixels. We'd need to integrate
2072         // with our shaders or do something much more invasive to get better data here.
2073         if (PrismSettings.showOverdraw) {
2074             if (p) {
2075                 painted |= 3 << (g.getClipRectIndex() * 2);
2076             } else {
2077                 painted |= 1 << (g.getClipRectIndex() * 2);
2078             }
2079         }
2080     }
2081 
2082     /**
2083      * Return true if this node has a blend mode that requires special
2084      * processing.
2085      * Regular nodes can handle null or SRC_OVER just by rendering into
2086      * the existing buffer.
2087      * Groups override this since they must collect their children into