Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/classes/sun/java2d/d3d/D3DPaints.java
32288 views
/*1* Copyright (c) 2007, 2013, 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.LinearGradientPaint;28import java.awt.MultipleGradientPaint;29import java.awt.MultipleGradientPaint.ColorSpaceType;30import java.awt.MultipleGradientPaint.CycleMethod;31import java.awt.TexturePaint;32import java.awt.image.BufferedImage;33import java.util.HashMap;34import java.util.Map;35import java.lang.annotation.Native;36import sun.java2d.SunGraphics2D;37import sun.java2d.SurfaceData;38import sun.java2d.loops.CompositeType;39import static sun.java2d.d3d.D3DContext.D3DContextCaps.*;4041abstract class D3DPaints {4243/**44* Holds all registered implementations, using the corresponding45* SunGraphics2D.PAINT_* constant as the hash key.46*/47private static Map<Integer, D3DPaints> impls =48new HashMap<Integer, D3DPaints>(4, 1.0f);4950static {51impls.put(SunGraphics2D.PAINT_GRADIENT, new Gradient());52impls.put(SunGraphics2D.PAINT_LIN_GRADIENT, new LinearGradient());53impls.put(SunGraphics2D.PAINT_RAD_GRADIENT, new RadialGradient());54impls.put(SunGraphics2D.PAINT_TEXTURE, new Texture());55}5657/**58* Attempts to locate an implementation corresponding to the paint state59* of the provided SunGraphics2D object. If no implementation can be60* found, or if the paint cannot be accelerated under the conditions61* of the SunGraphics2D, this method returns false; otherwise, returns62* true.63*/64static boolean isValid(SunGraphics2D sg2d) {65D3DPaints impl = impls.get(sg2d.paintState);66return (impl != null && impl.isPaintValid(sg2d));67}6869/**70* Returns true if this implementation is able to accelerate the71* Paint object associated with, and under the conditions of, the72* provided SunGraphics2D instance; otherwise returns false.73*/74abstract boolean isPaintValid(SunGraphics2D sg2d);7576/************************* GradientPaint support ****************************/7778private static class Gradient extends D3DPaints {79private Gradient() {}8081/**82* Returns true if the given GradientPaint instance can be83* used by the accelerated D3DPaints.Gradient implementation.84* A GradientPaint is considered valid only if the destination85* has support for fragment shaders.86*/87@Override88boolean isPaintValid(SunGraphics2D sg2d) {89D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;90D3DGraphicsDevice gd = (D3DGraphicsDevice)91dstData.getDeviceConfiguration().getDevice();92return gd.isCapPresent(CAPS_LCD_SHADER);93}94}9596/************************** TexturePaint support ****************************/9798private static class Texture extends D3DPaints {99private Texture() {}100101/**102* Returns true if the given TexturePaint instance can be used by the103* accelerated BufferedPaints.Texture implementation.104*105* A TexturePaint is considered valid if the following conditions106* are met:107* - the texture image dimensions are power-of-two108* - the texture image can be (or is already) cached in a D3D109* texture object110*/111@Override112public boolean isPaintValid(SunGraphics2D sg2d) {113TexturePaint paint = (TexturePaint)sg2d.paint;114D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;115BufferedImage bi = paint.getImage();116117// verify that the texture image dimensions are pow2118D3DGraphicsDevice gd =119(D3DGraphicsDevice)dstData.getDeviceConfiguration().getDevice();120int imgw = bi.getWidth();121int imgh = bi.getHeight();122if (!gd.isCapPresent(CAPS_TEXNONPOW2)) {123if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {124return false;125}126}127// verify that the texture image is square if it has to be128if (!gd.isCapPresent(CAPS_TEXNONSQUARE) && imgw != imgh)129{130return false;131}132133SurfaceData srcData =134dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,135CompositeType.SrcOver, null);136if (!(srcData instanceof D3DSurfaceData)) {137// REMIND: this is a hack that attempts to cache the system138// memory image from the TexturePaint instance into a139// D3D texture...140srcData =141dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,142CompositeType.SrcOver, null);143if (!(srcData instanceof D3DSurfaceData)) {144return false;145}146}147148// verify that the source surface is actually a texture149D3DSurfaceData d3dData = (D3DSurfaceData)srcData;150if (d3dData.getType() != D3DSurfaceData.TEXTURE) {151return false;152}153154return true;155}156}157158/****************** Shared MultipleGradientPaint support ********************/159160private static abstract class MultiGradient extends D3DPaints {161162/**163* Note that this number is lower than the MULTI_MAX_FRACTIONS164* defined in the superclass. The D3D pipeline now uses a165* slightly more complicated shader (to avoid the gradient banding166* issues), which has a higher instruction count. To ensure that167* all versions of the shader can be compiled for PS 2.0 hardware,168* we need to cap this maximum value at 8.169*/170@Native public static final int MULTI_MAX_FRACTIONS_D3D = 8;171172protected MultiGradient() {}173174/**175* Returns true if the given MultipleGradientPaint instance can be176* used by the accelerated D3DPaints.MultiGradient implementation.177* A MultipleGradientPaint is considered valid if the following178* conditions are met:179* - the number of gradient "stops" is <= MAX_FRACTIONS180* - the destination has support for fragment shaders181*/182@Override183boolean isPaintValid(SunGraphics2D sg2d) {184MultipleGradientPaint paint = (MultipleGradientPaint)sg2d.paint;185// REMIND: ugh, this creates garbage; would be nicer if186// we had a MultipleGradientPaint.getNumStops() method...187if (paint.getFractions().length > MULTI_MAX_FRACTIONS_D3D) {188return false;189}190191D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;192D3DGraphicsDevice gd = (D3DGraphicsDevice)193dstData.getDeviceConfiguration().getDevice();194if (!gd.isCapPresent(CAPS_LCD_SHADER)) {195return false;196}197return true;198}199}200201/********************** LinearGradientPaint support *************************/202203private static class LinearGradient extends MultiGradient {204private LinearGradient() {}205206@Override207boolean isPaintValid(SunGraphics2D sg2d) {208LinearGradientPaint paint = (LinearGradientPaint)sg2d.paint;209210if (paint.getFractions().length == 2 &&211paint.getCycleMethod() != CycleMethod.REPEAT &&212paint.getColorSpace() != ColorSpaceType.LINEAR_RGB)213{214D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;215D3DGraphicsDevice gd = (D3DGraphicsDevice)216dstData.getDeviceConfiguration().getDevice();217if (gd.isCapPresent(CAPS_LCD_SHADER)) {218// we can delegate to the optimized two-color gradient219// codepath, which should be faster220return true;221}222}223224return super.isPaintValid(sg2d);225}226}227228/********************** RadialGradientPaint support *************************/229230private static class RadialGradient extends MultiGradient {231private RadialGradient() {}232}233}234235236