Path: blob/master/src/java.desktop/share/classes/sun/java2d/loops/MaskBlit.java
41159 views
/*1* Copyright (c) 1999, 2021, 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.loops;2627import java.awt.Composite;28import java.lang.ref.WeakReference;2930import sun.java2d.SurfaceData;31import sun.java2d.pipe.Region;3233/**34* MaskBlit35* 1) copies rectangle of pixels from one surface to another36* 2) performs compositing of colors based upon a Composite37* parameter38* 3) blends result of composite with destination using an39* alpha coverage mask40* 4) the mask may be null in which case it should be treated41* as if it were an array of all opaque values (0xff)42*43* precise behavior is undefined if the source surface44* and the destination surface are the same surface45* with overlapping regions of pixels46*/4748public class MaskBlit extends GraphicsPrimitive49{50public static final String methodSignature = "MaskBlit(...)".toString();5152public static final int primTypeID = makePrimTypeID();5354private static RenderCache blitcache = new RenderCache(20);5556public static MaskBlit locate(SurfaceType srctype,57CompositeType comptype,58SurfaceType dsttype)59{60return (MaskBlit)61GraphicsPrimitiveMgr.locate(primTypeID,62srctype, comptype, dsttype);63}6465public static MaskBlit getFromCache(SurfaceType src,66CompositeType comp,67SurfaceType dst)68{69Object o = blitcache.get(src, comp, dst);70if (o != null) {71return (MaskBlit) o;72}73MaskBlit blit = locate(src, comp, dst);74if (blit == null) {75System.out.println("mask blit loop not found for:");76System.out.println("src: "+src);77System.out.println("comp: "+comp);78System.out.println("dst: "+dst);79} else {80blitcache.put(src, comp, dst, blit);81}82return blit;83}8485protected MaskBlit(SurfaceType srctype,86CompositeType comptype,87SurfaceType dsttype)88{89super(methodSignature, primTypeID, srctype, comptype, dsttype);90}9192public MaskBlit(long pNativePrim,93SurfaceType srctype,94CompositeType comptype,95SurfaceType dsttype)96{97super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);98}99100/**101* All MaskBlit implementors must have this invoker method102*/103public native void MaskBlit(SurfaceData src, SurfaceData dst,104Composite comp, Region clip,105int srcx, int srcy,106int dstx, int dsty,107int width, int height,108byte[] mask, int maskoff, int maskscan);109110static {111GraphicsPrimitiveMgr.registerGeneral(new MaskBlit(null, null, null));112}113114protected GraphicsPrimitive makePrimitive(SurfaceType srctype,115CompositeType comptype,116SurfaceType dsttype)117{118/*119new Throwable().printStackTrace();120System.out.println("Constructing general maskblit for:");121System.out.println("src: "+srctype);122System.out.println("comp: "+comptype);123System.out.println("dst: "+dsttype);124*/125126if (CompositeType.Xor.equals(comptype)) {127throw new InternalError("Cannot construct MaskBlit for " +128"XOR mode");129}130131General ob = new General(srctype, comptype, dsttype);132setupGeneralBinaryOp(ob);133return ob;134}135136private static class General137extends MaskBlit138implements GeneralBinaryOp139{140Blit convertsrc;141Blit convertdst;142MaskBlit performop;143Blit convertresult;144145WeakReference<SurfaceData> srcTmp;146WeakReference<SurfaceData> dstTmp;147148public General(SurfaceType srctype,149CompositeType comptype,150SurfaceType dsttype)151{152super(srctype, comptype, dsttype);153}154155public void setPrimitives(Blit srcconverter,156Blit dstconverter,157GraphicsPrimitive genericop,158Blit resconverter)159{160this.convertsrc = srcconverter;161this.convertdst = dstconverter;162this.performop = (MaskBlit) genericop;163this.convertresult = resconverter;164}165166public synchronized void MaskBlit(SurfaceData srcData,167SurfaceData dstData,168Composite comp,169Region clip,170int srcx, int srcy,171int dstx, int dsty,172int width, int height,173byte[] mask, int offset, int scan)174{175SurfaceData src, dst;176Region opclip;177int sx, sy, dx, dy;178179if (convertsrc == null) {180src = srcData;181sx = srcx;182sy = srcy;183} else {184SurfaceData cachedSrc = null;185if (srcTmp != null) {186cachedSrc = srcTmp.get();187}188src = convertFrom(convertsrc, srcData, srcx, srcy,189width, height, cachedSrc);190sx = 0;191sy = 0;192if (src != cachedSrc) {193srcTmp = new WeakReference<>(src);194}195}196197if (convertdst == null) {198dst = dstData;199dx = dstx;200dy = dsty;201opclip = clip;202} else {203// assert: convertresult != null204SurfaceData cachedDst = null;205if (dstTmp != null) {206cachedDst = dstTmp.get();207}208dst = convertFrom(convertdst, dstData, dstx, dsty,209width, height, cachedDst);210dx = 0;211dy = 0;212opclip = null;213if (dst != cachedDst) {214dstTmp = new WeakReference<>(dst);215}216}217218performop.MaskBlit(src, dst, comp, opclip,219sx, sy, dx, dy, width, height,220mask, offset, scan);221222if (convertresult != null) {223// assert: convertdst != null224convertTo(convertresult, dst, dstData, clip,225dstx, dsty, width, height);226}227}228}229230public GraphicsPrimitive traceWrap() {231return new TraceMaskBlit(this);232}233234private static class TraceMaskBlit extends MaskBlit {235MaskBlit target;236237public TraceMaskBlit(MaskBlit target) {238// We need to have the same NativePrim as our239// target in case we are used with a TransformHelper240super(target.getNativePrim(),241target.getSourceType(),242target.getCompositeType(),243target.getDestType());244this.target = target;245}246247public GraphicsPrimitive traceWrap() {248return this;249}250251public void MaskBlit(SurfaceData src, SurfaceData dst,252Composite comp, Region clip,253int srcx, int srcy, int dstx, int dsty,254int width, int height,255byte[] mask, int maskoff, int maskscan)256{257tracePrimitive(target);258target.MaskBlit(src, dst, comp, clip,259srcx, srcy, dstx, dsty, width, height,260mask, maskoff, maskscan);261}262}263}264265266