Path: blob/master/src/java.desktop/windows/classes/sun/java2d/d3d/D3DGraphicsConfig.java
41159 views
/*1* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.java2d.d3d;2627import java.awt.AWTException;28import java.awt.BufferCapabilities;29import java.awt.Component;30import java.awt.Graphics;31import java.awt.ImageCapabilities;32import java.awt.Transparency;33import java.awt.color.ColorSpace;34import java.awt.image.ColorModel;35import java.awt.image.DataBuffer;36import java.awt.image.DirectColorModel;37import java.awt.image.VolatileImage;38import sun.awt.Win32GraphicsConfig;39import sun.awt.image.SunVolatileImage;40import sun.awt.image.SurfaceManager;41import sun.awt.windows.WComponentPeer;42import sun.java2d.Surface;43import sun.java2d.SurfaceData;44import sun.java2d.pipe.hw.AccelTypedVolatileImage;45import sun.java2d.pipe.hw.AccelGraphicsConfig;46import sun.java2d.pipe.hw.AccelSurface;47import sun.java2d.pipe.hw.ContextCapabilities;48import static sun.java2d.pipe.hw.AccelSurface.*;49import static sun.java2d.d3d.D3DContext.D3DContextCaps.*;5051public final class D3DGraphicsConfig52extends Win32GraphicsConfig53implements AccelGraphicsConfig54{55private static ImageCapabilities imageCaps = new D3DImageCaps();5657private BufferCapabilities bufferCaps;58private final D3DGraphicsDevice device;5960@SuppressWarnings("deprecation")61protected D3DGraphicsConfig(D3DGraphicsDevice device) {62super(device, 0);63this.device = device;64}6566public SurfaceData createManagedSurface(int w, int h, int transparency) {67return D3DSurfaceData.createData(this, w, h,68getColorModel(transparency),69null,70D3DSurfaceData.TEXTURE);71}7273@Override74public synchronized void displayChanged() {75super.displayChanged();76// the context could hold a reference to a D3DSurfaceData, which in77// turn has a reference back to this D3DGraphicsConfig, so in order78// for this instance to be disposed we need to break the connection79D3DRenderQueue rq = D3DRenderQueue.getInstance();80rq.lock();81try {82D3DContext.invalidateCurrentContext();83} finally {84rq.unlock();85}86}8788@Override89public ColorModel getColorModel(int transparency) {90switch (transparency) {91case Transparency.OPAQUE:92// REMIND: once the ColorModel spec is changed, this should be93// an opaque premultiplied DCM...94return new DirectColorModel(24, 0xff0000, 0xff00, 0xff);95case Transparency.BITMASK:96return new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000);97case Transparency.TRANSLUCENT:98ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);99return new DirectColorModel(cs, 32,1000xff0000, 0xff00, 0xff, 0xff000000,101true, DataBuffer.TYPE_INT);102default:103return null;104}105}106107@Override108public String toString() {109return ("D3DGraphicsConfig[dev="+device+",pixfmt="+visual+"]");110}111112/**113* The following methods are invoked from WComponentPeer.java rather114* than having the Win32-dependent implementations hardcoded in that115* class. This way the appropriate actions are taken based on the peer's116* GraphicsConfig, whether it is a Win32GraphicsConfig or a117* D3DGraphicsConfig.118*/119120/**121* Creates a new SurfaceData that will be associated with the given122* WComponentPeer. D3D9 doesn't allow rendering to the screen,123* so a GDI surface will be returned.124*/125@Override126public SurfaceData createSurfaceData(WComponentPeer peer,127int numBackBuffers)128{129return super.createSurfaceData(peer, numBackBuffers);130}131132/**133* The following methods correspond to the multibuffering methods in134* WComponentPeer.java...135*/136137/**138* Checks that the requested configuration is natively supported; if not,139* an AWTException is thrown.140*/141@Override142public void assertOperationSupported(Component target,143int numBuffers,144BufferCapabilities caps)145throws AWTException146{147if (numBuffers < 2 || numBuffers > 4) {148throw new AWTException("Only 2-4 buffers supported");149}150if (caps.getFlipContents() == BufferCapabilities.FlipContents.COPIED &&151numBuffers != 2)152{153throw new AWTException("FlipContents.COPIED is only" +154"supported for 2 buffers");155}156}157158/**159* Creates a D3D-based backbuffer for the given peer and returns the160* image wrapper.161*/162@Override163public VolatileImage createBackBuffer(WComponentPeer peer) {164Component target = (Component)peer.getTarget();165// it is possible for the component to have size 0x0, adjust it to166// be at least 1x1 to avoid IAE167int w = Math.max(1, target.getWidth());168int h = Math.max(1, target.getHeight());169return new SunVolatileImage(target, w, h, Boolean.TRUE);170}171172/**173* Performs the native D3D flip operation for the given target Component.174*/175@Override176public void flip(WComponentPeer peer,177Component target, VolatileImage backBuffer,178int x1, int y1, int x2, int y2,179BufferCapabilities.FlipContents flipAction)180{181// REMIND: we should actually get a surface data for the182// backBuffer's VI183SurfaceManager d3dvsm =184SurfaceManager.getManager(backBuffer);185SurfaceData sd = d3dvsm.getPrimarySurfaceData();186if (sd instanceof D3DSurfaceData) {187D3DSurfaceData d3dsd = (D3DSurfaceData)sd;188double scaleX = sd.getDefaultScaleX();189double scaleY = sd.getDefaultScaleY();190if (scaleX > 1 || scaleY > 1) {191int sx1 = (int) Math.floor(x1 * scaleX);192int sy1 = (int) Math.floor(y1 * scaleY);193int sx2 = (int) Math.ceil(x2 * scaleX);194int sy2 = (int) Math.ceil(y2 * scaleY);195D3DSurfaceData.swapBuffers(d3dsd, sx1, sy1, sx2, sy2);196} else {197D3DSurfaceData.swapBuffers(d3dsd, x1, y1, x2, y2);198}199} else {200// the surface was likely lost could not have been restored201Graphics g = peer.getGraphics();202try {203g.drawImage(backBuffer,204x1, y1, x2, y2,205x1, y1, x2, y2,206null);207} finally {208g.dispose();209}210}211212if (flipAction == BufferCapabilities.FlipContents.BACKGROUND) {213Graphics g = backBuffer.getGraphics();214try {215g.setColor(target.getBackground());216g.fillRect(0, 0,217backBuffer.getWidth(),218backBuffer.getHeight());219} finally {220g.dispose();221}222}223}224225private static class D3DBufferCaps extends BufferCapabilities {226public D3DBufferCaps() {227// REMIND: should we indicate that the front-buffer228// (the on-screen rendering) is not accelerated?229super(imageCaps, imageCaps, FlipContents.UNDEFINED);230}231@Override232public boolean isMultiBufferAvailable() {233return true;234}235236}237238@Override239public BufferCapabilities getBufferCapabilities() {240if (bufferCaps == null) {241bufferCaps = new D3DBufferCaps();242}243return bufferCaps;244}245246private static class D3DImageCaps extends ImageCapabilities {247private D3DImageCaps() {248super(true);249}250@Override251public boolean isTrueVolatile() {252return true;253}254}255256@Override257public ImageCapabilities getImageCapabilities() {258return imageCaps;259}260261D3DGraphicsDevice getD3DDevice() {262return device;263}264265@Override266public D3DContext getContext() {267return device.getContext();268}269270@Override271public VolatileImage272createCompatibleVolatileImage(int width, int height,273int transparency, int type)274{275if (type == FLIP_BACKBUFFER || type == WINDOW || type == UNDEFINED ||276transparency == Transparency.BITMASK)277{278return null;279}280boolean isOpaque = transparency == Transparency.OPAQUE;281if (type == RT_TEXTURE) {282int cap = isOpaque ? CAPS_RT_TEXTURE_OPAQUE : CAPS_RT_TEXTURE_ALPHA;283if (!device.isCapPresent(cap)) {284return null;285}286} else if (type == RT_PLAIN) {287if (!isOpaque && !device.isCapPresent(CAPS_RT_PLAIN_ALPHA)) {288return null;289}290}291292SunVolatileImage vi = new AccelTypedVolatileImage(this, width, height,293transparency, type);294Surface sd = vi.getDestSurface();295if (!(sd instanceof AccelSurface) ||296((AccelSurface)sd).getType() != type)297{298vi.flush();299vi = null;300}301302return vi;303}304305@Override306public ContextCapabilities getContextCapabilities() {307return device.getContextCapabilities();308}309}310311312