Package sun.java2d.d3d

Source Code of sun.java2d.d3d.D3DSurfaceData

/*
* Copyright (c) 2005, 2007, 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.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import sun.awt.SunHints;
import sun.awt.Win32GraphicsConfig;
import sun.awt.Win32GraphicsDevice;
import sun.awt.image.SurfaceManager;
import sun.java2d.InvalidPipeException;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.java2d.SurfaceDataProxy;
import sun.java2d.loops.GraphicsPrimitive;
import sun.java2d.loops.SurfaceType;
import sun.java2d.pipe.PixelToShapeConverter;
import sun.java2d.pipe.TextPipe;
import sun.java2d.windows.Win32OffScreenSurfaceData;
import sun.java2d.windows.Win32SurfaceData;
import sun.java2d.windows.WinVolatileSurfaceManager;
import sun.java2d.windows.WindowsFlags;

import static sun.java2d.windows.Win32SurfaceData.*;

public class D3DSurfaceData extends Win32OffScreenSurfaceData {

    // properties of a surface
    /**
     * This property is used for a back-buffer surface
     */
    public static final int D3D_ATTACHED_SURFACE = (1 << 15);
    /**
     * A surface with this property can be used as a Direct3D rendering
     * destination.
     */
    public static final int D3D_RENDER_TARGET    = (1 << 16);

    public static final int
        D3D_INVALID_SURFACE    = 0;
    /**
     * Surface is a Direct3D plain surface (not a texture).
     * Plain surface can be used as render target.
     * VolatileImages typically use plain surfaces as their hardware
     * accelerated surfaces.
     */
    public static final int
        D3D_PLAIN_SURFACE      = (1 << 0) | D3D_RENDER_TARGET;
    /**
     * Direct3D texture. Mostly used for cached accelerated surfaces.
     * Surfaces of this type can be copied from using hardware acceleration
     * by using texture mapping.
     */
    public static final int
        D3D_TEXTURE_SURFACE    = (1 << 1);
    /**
     * Direct3D Backbuffer surface - an attached surface. Used for
     * multibuffered BufferStrategies.
     */
    public static final int
        D3D_BACKBUFFER_SURFACE = D3D_PLAIN_SURFACE | D3D_ATTACHED_SURFACE;
    /**
     * Render-to-texture. A texture which can also be a render target.
     * Combines the benefits of textures (fast copies-from) and
     * backbuffers or plain surfaces (hw-accelerated rendering to the surface)
     */
    public static final int
        D3D_RTT_SURFACE        = D3D_TEXTURE_SURFACE | D3D_RENDER_TARGET;

    // supported texture pixel formats
    public static final int PF_INVALID         =  0;
    public static final int PF_INT_ARGB        =  1;
    public static final int PF_INT_RGB         =  2;
    public static final int PF_INT_RGBX        =  3;
    public static final int PF_INT_BGR         =  4;
    public static final int PF_USHORT_565_RGB  =  5;
    public static final int PF_USHORT_555_RGB  =  6;
    public static final int PF_USHORT_555_RGBX =  7;
    public static final int PF_INT_ARGB_PRE    =  8;
    public static final int PF_USHORT_4444_ARGB=  9;

    public static final String
        DESC_INT_ARGB_D3D         = "Integer ARGB D3D with translucency";
    public static final String
        DESC_USHORT_4444_ARGB_D3D = "UShort 4444 ARGB D3D with translucency";

    /**
     * Surface type for texture destination.  We cannot render textures to
     * the screen because Direct3D is not clipped by the window's clip list,
     * so we only enable the texture blit loops for copies to offscreen
     * accelerated surfaces.
     */
    public static final String
        DESC_DEST_D3D           = "D3D render target";

    public static final SurfaceType D3DSurface =
        SurfaceType.Any.deriveSubType("Direct3D Surface");
    public static final SurfaceType D3DTexture =
        D3DSurface.deriveSubType("Direct3D Texture");

    /**
     * D3D destination surface types (derive from offscreen dd surfaces).
     * Note that all of these surfaces have the same surface description;
     * we do not care about the depth of the surface since texture ops
     * support multiple depths.
     */
    public static final SurfaceType IntRgbD3D =
        IntRgbDD.deriveSubType(DESC_DEST_D3D);

    public static final SurfaceType IntRgbxD3D =
        IntRgbxDD.deriveSubType(DESC_DEST_D3D);

    public static final SurfaceType Ushort565RgbD3D =
        Ushort565RgbDD.deriveSubType(DESC_DEST_D3D);

    public static final SurfaceType Ushort555RgbxD3D =
        Ushort555RgbxDD.deriveSubType(DESC_DEST_D3D);

    public static final SurfaceType Ushort555RgbD3D =
        Ushort555RgbDD.deriveSubType(DESC_DEST_D3D);

    // REMIND: Is it possible to have d3d accelerated on this type of surface?
    public static final SurfaceType ThreeByteBgrD3D =
        ThreeByteBgrDD.deriveSubType(DESC_DEST_D3D);

    public static final SurfaceType IntArgbD3D =
        SurfaceType.IntArgb.deriveSubType(DESC_INT_ARGB_D3D);

    public static final SurfaceType Ushort4444ArgbD3D =
        SurfaceType.Ushort4444Argb.deriveSubType(DESC_USHORT_4444_ARGB_D3D);

    // Textures we can render to using d3d
    public static final SurfaceType IntRgbD3D_RTT =
        IntRgbD3D.deriveSubType(DESC_DEST_D3D);

    public static final SurfaceType IntRgbxD3D_RTT =
        IntRgbxD3D.deriveSubType(DESC_DEST_D3D);

    public static final SurfaceType Ushort565RgbD3D_RTT =
        Ushort565RgbD3D.deriveSubType(DESC_DEST_D3D);

    public static final SurfaceType Ushort555RgbxD3D_RTT =
        Ushort555RgbxD3D.deriveSubType(DESC_DEST_D3D);

    public static final SurfaceType Ushort555RgbD3D_RTT =
        Ushort555RgbD3D.deriveSubType(DESC_DEST_D3D);

    public static final SurfaceType Ushort4444ArgbD3D_RTT =
        Ushort4444ArgbD3D.deriveSubType(DESC_DEST_D3D);

    public static final SurfaceType IntArgbD3D_RTT =
        IntArgbD3D.deriveSubType(DESC_DEST_D3D);

    public static final SurfaceType ThreeByteBgrD3D_RTT =
        ThreeByteBgrD3D.deriveSubType(DESC_DEST_D3D);

    // the type of this surface - texture, plain, back-buffer
    protected int type;
    protected int pixelFormat;

    private D3DContext d3dContext;

    protected static D3DRenderer d3dPipe;
    protected static PixelToShapeConverter d3dTxPipe;
    protected static D3DTextRenderer d3dTextPipe;
    protected static D3DDrawImage d3dDrawImagePipe;

    private native void initOps(int depth, int transparency);

    static {
        if (WindowsFlags.isD3DEnabled()) {
            D3DBlitLoops.register();
            D3DMaskFill.register();
        }

        d3dPipe = new D3DRenderer();
        d3dTxPipe = new PixelToShapeConverter(d3dPipe);
        d3dTextPipe = new D3DTextRenderer();
        d3dDrawImagePipe = new D3DDrawImage();

        if (GraphicsPrimitive.tracingEnabled()) {
            d3dPipe = d3dPipe.traceWrapD3D();
            d3dTextPipe = d3dTextPipe.traceWrap();
        }
    }

    @Override
    public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
        //D3D may be eliminated soon so no Proxy was created for it...
        //return D3DSurfaceDataProxy.createProxy(srcData, graphicsConfig);
        return SurfaceDataProxy.UNCACHED;
    }

    /**
     * Non-public constructor.  Use createData() to create an object.
     *
     * This constructor is used to house the common construction
     * code shared between the creation of D3DSurfaceData objects
     * and subclasses of D3DSurfaceData (such as D3DBackBufferSD).
     *
     * It calls the common constructor in the parent, and then
     * initializes other shared D3D data.
     */
    protected D3DSurfaceData(int width, int height,
                             int d3dSurfaceType,
                             SurfaceType sType, ColorModel cm,
                             GraphicsConfiguration gc,
                             Image image, int transparency)
    {
        super(width, height, sType, cm, gc, image, transparency);
        this.type = d3dSurfaceType;
    }

    /**
     * Private constructor.  Use createData() to create an object.
     *
     * This constructor calls the common constructor above and then
     * performs the specific initialization of the D3DSurface.
     */
    private D3DSurfaceData(int width, int height,
                           int d3dSurfaceType,
                           SurfaceType sType, ColorModel cm,
                           GraphicsConfiguration gc,
                           Image image, int transparency,
                           int screen)
    {
        this(width, height, d3dSurfaceType, sType, cm, gc, image, transparency);
        pixelFormat = initSurface(width, height, screen,
                                  null /*parent SurfaceData*/);
    }

    public static D3DSurfaceData createData(int width, int height,
                                            int d3dSurfaceType,
                                            ColorModel cm,
                                            GraphicsConfiguration gc,
                                            Image image)
    {
        Win32GraphicsDevice gd = (Win32GraphicsDevice)gc.getDevice();
        // After a display change ddInstance may not be
        // recreated yet, and in this case isD3DEnabledOnDevice will
        // return false, until someone attempted to recreate the
        // primary.
        if (!gd.isD3DEnabledOnDevice()) {
            return null;
        }

        return new D3DSurfaceData(width, height,
                                  d3dSurfaceType,
                                  getSurfaceType(gc, cm, d3dSurfaceType),
                                  cm, gc, image,
                                  cm.getTransparency(), gd.getScreen());
    }

    int getPixelFormat() {
        return pixelFormat;
    }

    static SurfaceType getSurfaceType(GraphicsConfiguration gc,
                                      ColorModel cm,
                                      int d3dSurfaceType)
    {
        if (d3dSurfaceType == D3D_TEXTURE_SURFACE) {
            // for non-rtt textures we have only one surface type
            return D3DTexture;
        } else {
            int pixelSize = cm.getPixelSize();
            Win32GraphicsDevice gd = (Win32GraphicsDevice)gc.getDevice();
            int transparency = cm.getTransparency();

            // We'll attempt to use render-to-texture if render target is
            // requested, but it's not a back-buffer and we support RTT
            // for this configuration.
            boolean useRTT =
                ((d3dSurfaceType & D3D_RENDER_TARGET) != 0) &&
                ((d3dSurfaceType & D3D_BACKBUFFER_SURFACE) == 0) &&
                gd.getD3DContext().isRTTSupported();

            // if there's no RTT available, we can't accelerate non-opaque
            // surfaces, so we return null.
            if (transparency == Transparency.TRANSLUCENT ||
                transparency == Transparency.BITMASK)
            {
                if (pixelSize == 16) {
                    return useRTT ? Ushort4444ArgbD3D_RTT :
                        null/*Ushort4444ArgbD3D*/;
                } else {
                    return useRTT ? IntArgbD3D_RTT : null/*IntArgbD3D*/;
                }
            } else {
                // it's an opaque surface, either a VI or a back-buffer
                switch (pixelSize) {
                case 32:
                case 24:
                    if (cm instanceof DirectColorModel) {
                        if (((DirectColorModel)cm).getRedMask() == 0xff0000) {
                            return useRTT ? IntRgbD3D_RTT : IntRgbD3D;
                        } else {
                            return useRTT ? IntRgbxD3D_RTT : IntRgbxD3D;
                        }
                    } else {
                        return useRTT ? ThreeByteBgrD3D_RTT : ThreeByteBgrD3D;
                    }
                case 15:
                    return useRTT ? Ushort555RgbD3D_RTT : Ushort555RgbD3D;
                case 16:
                    if ((cm instanceof DirectColorModel) &&
                        (((DirectColorModel)cm).getBlueMask() == 0x3e))
                    {
                        return useRTT ? Ushort555RgbxD3D_RTT : Ushort555RgbxD3D;
                    } else {
                        return useRTT ? Ushort565RgbD3D_RTT : Ushort565RgbD3D;
                    }
                case 8: // not supported
                default:
                    throw new sun.java2d.InvalidPipeException("Unsupported bit " +
                                                              "depth: " +
                                                              cm.getPixelSize());
                }
            }
        }
    }

    private native int initOffScreenSurface(long pCtx,
                                            long pData, long parentPdata,
                                            int width, int height,
                                            int type, int screen);

    protected int initSurface(int width, int height, int screen,
                              Win32SurfaceData parentData)
    {
        int pFormat = PF_INVALID;

        synchronized (D3DContext.LOCK) {
            long pData = getNativeOps();
            long pDataParent = 0L;
            if (parentData != null) {
                pDataParent = parentData.getNativeOps();
            }
            D3DContext d3dContext = getContext();
            long pCtx = d3dContext.getNativeContext();
            // native context could be 0 if the context is currently invalid,
            // so attempt to revalidate
            if (pCtx == 0) {
                d3dContext.reinitNativeContext();
                pCtx = d3dContext.getNativeContext();
            }
            if (pData != 0 && pCtx != 0) {
                pFormat = initOffScreenSurface(pCtx,
                                               pData, pDataParent,
                                               width, height, type, screen);
            } else {
                // if the context can't be restored, give up for now.
                throw new InvalidPipeException("D3DSD.initSurface: pData " +
                                               "or pCtx is null");
            }
        }
        return pFormat;
    }

    @Override
    public void validatePipe(SunGraphics2D sg2d) {
        // we don't support COMP_XOR yet..
        if (sg2d.compositeState < sg2d.COMP_XOR) {
            TextPipe textpipe;
            boolean validated = false;

            if (((sg2d.compositeState <= sg2d.COMP_ISCOPY &&
                  sg2d.paintState <= sg2d.PAINT_ALPHACOLOR) ||
                 (sg2d.compositeState == sg2d.COMP_ALPHA &&
                  sg2d.paintState <= sg2d.PAINT_ALPHACOLOR &&
                  (((AlphaComposite)sg2d.composite).getRule() ==
                   AlphaComposite.SRC_OVER))) &&
                sg2d.textAntialiasHint <= SunHints.INTVAL_TEXT_ANTIALIAS_GASP)
            {
                // D3DTextRenderer handles both AA and non-AA text, but
                // only works if composite is SrcNoEa or SrcOver
                textpipe = d3dTextPipe;
            } else {
                // do this to initialize textpipe correctly; we will attempt
                // to override the non-text pipes below
                super.validatePipe(sg2d);
                textpipe = sg2d.textpipe;
                validated = true;
            }

            if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON &&
                sg2d.paintState <= sg2d.PAINT_ALPHACOLOR)
            {
                sg2d.drawpipe =
                    sg2d.strokeState == sg2d.STROKE_THIN ? d3dPipe : d3dTxPipe;
                sg2d.fillpipe = d3dPipe;
                sg2d.shapepipe = d3dPipe;
            } else if (!validated) {
                super.validatePipe(sg2d);
            }
            // install the text pipe based on our earlier decision
            sg2d.textpipe = textpipe;
        } else {
            super.validatePipe(sg2d);
        }

        // always override the image pipe with the specialized D3D pipe
        sg2d.imagepipe = d3dDrawImagePipe;
    }

    /**
     * Disables D3D acceleration on the surface manager of this surfaceData
     * object. This can happen when we encounter a hard error in rendering a D3D
     * primitive (for example, if we were unable to set a surface as D3D target
     * surface).
     * Upon next validation the SurfaceManager will create a non-D3D surface.
     */
    public void disableD3D() {
        markSurfaceLost();
        SurfaceManager sMgr = SurfaceManager.getManager(image);
        if (sMgr instanceof WinVolatileSurfaceManager) {
            ((WinVolatileSurfaceManager)sMgr).setD3DAccelerationEnabled(false);
        }
    }

    @Override
    public boolean surfacePunted() {
        // Punting is disabled for D3D surfaces
        return false;
    }

    D3DContext getContext() {
        return ((Win32GraphicsDevice)graphicsConfig.getDevice()).getD3DContext();
    }
}
TOP

Related Classes of sun.java2d.d3d.D3DSurfaceData

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.