Package sun.java2d.d3d

Source Code of sun.java2d.d3d.D3DContext

/*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.  Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package sun.java2d.d3d;

import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.GraphicsEnvironment;
import java.awt.geom.AffineTransform;
import sun.awt.Win32GraphicsDevice;
import sun.java2d.InvalidPipeException;
import sun.java2d.SurfaceData;
import sun.java2d.pipe.Region;
import sun.java2d.windows.WindowsFlags;

public class D3DContext {

    public static final int NO_CONTEXT_FLAGS = 0;
    /**
     * Used in D3DBlitLoops: if the source surface is opaque
     * alpha blending can be turned off on the native level
     * (if there's no ea), thus improving performance.
     */
    public static final int SRC_IS_OPAQUE    = 1;

    /**
     * This is a list of capabilities supported by the device this
     * context is associated with.
     * @see getDeviceCaps
     */
    public static final int J2D_D3D_FAILURE                = (0 << 0);
    /**
     * Device supports depth buffer for d3d render targets
     */
    public static final int J2D_D3D_DEPTH_SURFACE_OK       = (1 << 0);
    /**
     * Device supports creation of plain d3d surfaces
     */
    public static final int J2D_D3D_PLAIN_SURFACE_OK       = (1 << 1);
    /**
     * Device supports creation of opaque textures
     */
    public static final int J2D_D3D_OP_TEXTURE_SURFACE_OK  = (1 << 2);
    /**
     * Device supports creation of bitmask textures
     */
    public static final int J2D_D3D_BM_TEXTURE_SURFACE_OK  = (1 << 3);
    /**
     * Device supports creation of translucent textures
     */
    public static final int J2D_D3D_TR_TEXTURE_SURFACE_OK  = (1 << 4);
    /**
     * Device supports creation of opaque render-to-textures
     */
    public static final int J2D_D3D_OP_RTT_SURFACE_OK      = (1 << 5);
    /**
     * Device can render lines correctly (no pixelization issues)
     */
    public static final int J2D_D3D_LINES_OK               = (1 << 6);
    /**
     * Device supports texture mapping (no pixelization issues)
     */
    public static final int J2D_D3D_TEXTURE_BLIT_OK        = (1 << 7);
    /**
     * Device supports texture mapping with transforms (no pixelization issues)
     */
    public static final int J2D_D3D_TEXTURE_TRANSFORM_OK   = (1 << 8);
    /**
     * Device can render clipped lines correctly.
     */
    public static final int J2D_D3D_LINE_CLIPPING_OK       = (1 << 9);
    /**
     * Device has all hw capabilities the d3d pipeline requires
     */
    public static final int J2D_D3D_DEVICE_OK              = (1 <<10);
    /**
     * Device supports all necessary texture formats required by d3d pipeline
     */
    public static final int J2D_D3D_PIXEL_FORMATS_OK       = (1 <<11);
    /**
     * Device supports geometry transformations
     */
    public static final int J2D_D3D_SET_TRANSFORM_OK       = (1 <<12);
    /**
     * The device is not from a list of known bad devices
     * (see D3DRuntimeTest.cpp)
     */
    public static final int J2D_D3D_HW_OK                  = (1 <<13);
    /**
     * Direct3D pipeline is enabled on this device
     */
    public static final int J2D_D3D_ENABLED_OK             = (1 <<14);

    /**
     * The lock object used to synchronize access to the native windowing
     * system layer.  Note that rendering methods should always synchronize on
     * D3DContext.LOCK before calling the D3DContext.getContext() method,
     * or any other method that invokes native D3d commands.
     * REMIND: in D3D case we should really be synchronizing on per-device
     * basis.
     */
    static Object LOCK;

    private Win32GraphicsDevice  gd;
    private boolean         valid;

    protected long          nativeContext;
    private SurfaceData     validatedDstData;
    private Region          validatedClip;
    private Composite       validatedComp;
    private int             validatedPixel;
    private int             validatedFlags;
    private boolean         xformInUse;
    // validated transform's data
    private double vScaleX, vScaleY, vShearX, vShearY, vTransX, vTransY;

    private int             deviceCaps;

    private native void setRenderTarget(long pCtx, long pDst);
    private native void setClip(long pCtx, long pDst, Region clip, boolean isRect,
                                int x1, int y1, int x2, int y2);
    private native void resetClip(long pCtx, long pDst);
    private native void resetComposite(long pCtx);
    private native void setAlphaComposite(long pCtx, int rule,
                                          float extraAlpha, int flags);
    private native void setTransform(long pCtx, long pDst,
                                     AffineTransform xform,
                                     double m00, double m10, double m01,
                                     double m11, double m02, double m12);
    private native void resetTransform(long pCtx, long pDst);
    private native void setColor(long pCtx, int pixel, int flags);
    private native long initNativeContext(int screen);
    private native int getNativeDeviceCaps(long pCtx);

    static {
        if (!GraphicsEnvironment.isHeadless()) {
            LOCK = D3DContext.class;
        }
    }

    public D3DContext(Win32GraphicsDevice gd) {
        this.gd = gd;
        reinitNativeContext();
    }

    /**
     * Reinitializes the context by retrieving a pointer to the native
     * D3DContext object, and resetting the device caps.
     */
    void reinitNativeContext() {
        nativeContext = initNativeContext(gd.getScreen());
        deviceCaps = nativeContext != 0L ?
            getNativeDeviceCaps(nativeContext) : J2D_D3D_FAILURE;
        valid = ((deviceCaps & J2D_D3D_ENABLED_OK) != 0);
        if (WindowsFlags.isD3DVerbose()) {
            if (valid) {
                System.out.println("Direct3D pipeline enabled on screen " +
                                   gd.getScreen());
            } else {
                System.out.println("Could not enable Direct3D pipeline on " +
                                   "screen " + gd.getScreen() +
                                   ". Device Caps: " +
                                   Integer.toHexString(deviceCaps));
            }
        }
    }

    /**
     * Invalidates this context by resetting its status: the validated
     * destination surface, and a pointer to the native context.
     * This method is called in the following cases:
     *  - if a surface loss situation is detected at the native level
     *    during any of the validation methods (setClip, setRenderTarget etc)
     *    and an InvalidPipeException is thrown.
     *    This situation happens when there was a surface loss, but
     *    there were no display change event (like in case of command prompt
     *    going fullscreen).
     *  - as part of surface restoration when a surface is the current
     *    target surface for this context. Since surface restoration
     *    resets the depth buffer contents, we need to make sure the clip
     *    is reset, and since the target surface is reset, we'll set a new
     *    clip the next time we attempt to render to the target surface.
     *  - when a display change occurs, the native D3DContext object is
     *    released and recreated as part of primary surface recreation.
     *    At the time of the release, the java D3DContext object need to be
     *    invalidated because a new D3D device is created and the target
     *    surface will need to be reset.
     *
     *  Invalidation of the context causes its revalidation the next time
     *  someone tries to get the D3DContext for rendering or creating a new
     *  surface.
     *
     *  @see #reinitNativeContext
     */
    private void invalidateContext() {
        valid = false;
        nativeContext = 0L;
        validatedDstData = null;
        // We don't set deviceCaps to J2D_D3D_FAILURE here because
        // it will prevent from creating d3d surfaces, which means that
        // we'll never get a chance to continue using d3d after a single
        // invalidation event (for example, a display change).
    }

    /**
     * Fetches the D3DContext associated with the current
     * thread/GraphicsConfig pair, validates the context using the given
     * parameters, then returns the handle to the native context object.
     * Most rendering operations will call this method first in order to
     * prepare the native D3d layer before issuing rendering commands.
     */
    static long getContext(SurfaceData srcData,
                           SurfaceData dstData,
                            Region clip, Composite comp,
                           AffineTransform xform,
                           int pixel, int flags)
    {
        if (dstData instanceof D3DSurfaceData == false) {
            throw new InvalidPipeException("Incorrect destination surface");
        }

        D3DContext d3dc = ((D3DSurfaceData)dstData).getContext();
        try {
            d3dc.validate(srcData, dstData, clip, comp, xform, pixel, flags);
        } catch (InvalidPipeException e) {
            d3dc.invalidateContext();
            // note that we do not propagate the exception. Once the context
            // is invalidated, any d3d rendering operations are noops, and
            // we are waiting for the primary surface restoration, which
            // happens when VolatileImage is validated. At this point
            // the native D3DContext will be reinitialized, and the next
            // time around validation of the context will succeed.
            // Throwing the exception here will do no good, since the
            // destination surface (which is associated with a VolatileImage
            // or a BufferStrategy) will not be restored until VI.validate()
            // is called by the rendering thread.
        }
        return d3dc.getNativeContext();
    }

    public int getDeviceCaps() {
        return deviceCaps;
    }

    boolean isRTTSupported() {
        return ((deviceCaps & J2D_D3D_OP_RTT_SURFACE_OK) != 0);
    }

    /**
     * Returns a handle to the native D3DContext structure associated with
     * this object.
     */
    long getNativeContext() {
        return nativeContext;
    }

    /**
     * Validates the given parameters against the current state for this
     * context.  If this context is not current, it will be made current
     * for the given source and destination surfaces, and the viewport will
     * be updated.  Then each part of the context state (clip, composite,
     * etc.) is checked against the previous value.  If the value has changed
     * since the last call to validate(), it will be updated accordingly.
     */
    private void validate(SurfaceData srcData, SurfaceData dstData,
                          Region clip, Composite comp, AffineTransform xform,
                          int pixel, int flags)
    {
        boolean updateClip = false;

        if ((srcData != null && !srcData.isValid()) || !dstData.isValid() ||
            dstData.getNativeOps() == 0L || dstData.isSurfaceLost())
        {
            throw new InvalidPipeException("Invalid surface");
        }

        if (!valid) {
            // attempt to reinitialize the context. If the device has been
            // reset, the following calls to setRenderTarget/setClip will
            // succeed and not throw InvalidPipeException.
            reinitNativeContext();
        }

        if (dstData != validatedDstData) {
            // invalidate pixel and clip (so they will be updated below)
            validatedPixel = ~pixel;
            updateClip = true;

            // update the viewport
            long pDst = dstData.getNativeOps();
            setRenderTarget(nativeContext, pDst);

            // keep the reference to the old data until we set the
            // new one on the native level, preventing it from being disposed
            SurfaceData tmpData = dstData;
            validatedDstData = dstData;
            tmpData = null;
        }
        // it's better to use dstData instead of validatedDstData because
        // the latter may be set to null via invalidateContext at any moment.
        long pDest = dstData.getNativeOps();

        // validate clip
        if ((clip != validatedClip) || updateClip) {
            if (clip != null) {
                /**
                 * It's cheaper to make this check than set clip every time.
                 *
                 * Set the new clip only if:
                 *  - we were asked to do it (updateClip == true)
                 *  - no clip was set before
                 *  - if both the old and the new clip are shapes
                 *  - if they're both rectangular but don't represent
                 *    the same rectangle
                 */
                if (updateClip ||
                    validatedClip == null ||
                    !(validatedClip.isRectangular() && clip.isRectangular()) ||
                    ((clip.getLoX() != validatedClip.getLoX() ||
                      clip.getLoY() != validatedClip.getLoY() ||
                      clip.getHiX() != validatedClip.getHiX() ||
                      clip.getHiY() != validatedClip.getHiY())))
                {
                    setClip(nativeContext, pDest,
                            clip, clip.isRectangular(),
                            clip.getLoX(), clip.getLoY(),
                            clip.getHiX(), clip.getHiY());
                }
            } else {
                resetClip(nativeContext, pDest);
            }
            validatedClip = clip;
        }

        if ((comp != validatedComp) || (flags != validatedFlags)) {
            // invalidate pixel
            validatedPixel = ~pixel;
            validatedComp = comp;
            if (comp != null) {
                AlphaComposite ac = (AlphaComposite)comp;
                setAlphaComposite(nativeContext, ac.getRule(),
                                  ac.getAlpha(), flags);
            } else {
                resetComposite(nativeContext);
            }
        }

        // validate transform
        if (xform == null) {
            if (xformInUse) {
                resetTransform(nativeContext, pDest);
                xformInUse = false;
                vScaleX = vScaleY = 1.0;
                vShearX = vShearY = vTransX = vTransY = 0.0;
            }
        } else {
            double nScaleX = xform.getScaleX();
            double nScaleY = xform.getScaleY();
            double nShearX = xform.getShearX();
            double nShearY = xform.getShearY();
            double nTransX = xform.getTranslateX();
            double nTransY = xform.getTranslateY();

            if (nTransX != vTransX || nTransY != vTransY ||
                nScaleX != vScaleX || nScaleY != vScaleY ||
                nShearX != vShearX || nShearY != vShearY)
            {
                setTransform(nativeContext, pDest,
                             xform,
                             nScaleX, nShearY, nShearX, nScaleY,
                             nTransX, nTransY);
                vScaleX = nScaleX;
                vScaleY = nScaleY;
                vShearX = nShearX;
                vShearY = nShearY;
                vTransX = nTransY;
                vTransY = nTransY;
                xformInUse = true;
            }
        }

        // validate pixel
        if (pixel != validatedPixel) {
            validatedPixel = pixel;
            setColor(nativeContext, pixel, flags);
        }

        // save flags for later comparison
        validatedFlags = flags;

        // mark dstData dirty
        dstData.markDirty();
    }
}
TOP

Related Classes of sun.java2d.d3d.D3DContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.