1 /* 2 * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.java2d.loops; 27 28 import java.awt.Composite; 29 import java.awt.CompositeContext; 30 import java.awt.RenderingHints; 31 import java.awt.image.ColorModel; 32 import java.awt.image.Raster; 33 import java.awt.image.WritableRaster; 34 import java.lang.ref.WeakReference; 35 import sun.java2d.loops.GraphicsPrimitive; 36 import sun.java2d.SurfaceData; 37 import sun.java2d.pipe.Region; 38 import sun.java2d.pipe.SpanIterator; 39 40 /** 41 * Blit 42 * 1) copies rectangle of pixels from one surface to another 43 * 2) performs compositing of colors based upon a Composite 44 * parameter 45 * 46 * precise behavior is undefined if the source surface 47 * and the destination surface are the same surface 48 * with overlapping regions of pixels 49 */ 50 51 public class Blit extends GraphicsPrimitive 52 { 53 public static final String methodSignature = "Blit(...)".toString(); 54 55 public static final int primTypeID = makePrimTypeID(); 56 57 private static RenderCache blitcache = new RenderCache(20); 58 59 public static Blit locate(SurfaceType srctype, 60 CompositeType comptype, 61 SurfaceType dsttype) 62 { 63 return (Blit) 64 GraphicsPrimitiveMgr.locate(primTypeID, 65 srctype, comptype, dsttype); 66 } 67 68 public static Blit getFromCache(SurfaceType src, 69 CompositeType comp, 70 SurfaceType dst) 71 { 72 Object o = blitcache.get(src, comp, dst); 73 if (o != null) { 74 return (Blit) o; 75 } 76 77 Blit blit = locate(src, comp, dst); 78 if (blit == null) { 79 System.out.println("blit loop not found for:"); 80 System.out.println("src: "+src); 81 System.out.println("comp: "+comp); 82 System.out.println("dst: "+dst); 83 } else { 84 blitcache.put(src, comp, dst, blit); 85 } 86 return blit; 87 } 88 89 protected Blit(SurfaceType srctype, 90 CompositeType comptype, 91 SurfaceType dsttype) 92 { 93 super(methodSignature, primTypeID, srctype, comptype, dsttype); 94 } 95 96 public Blit(long pNativePrim, 97 SurfaceType srctype, 98 CompositeType comptype, 99 SurfaceType dsttype) 100 { 101 super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype); 102 } 103 104 /** 105 * All Blit implementors must have this invoker method 106 */ 107 public native void Blit(SurfaceData src, SurfaceData dst, 108 Composite comp, Region clip, 109 int srcx, int srcy, 110 int dstx, int dsty, 111 int width, int height); 112 113 static { 114 GraphicsPrimitiveMgr.registerGeneral(new Blit(null, null, null)); 115 } 116 117 public GraphicsPrimitive makePrimitive(SurfaceType srctype, 118 CompositeType comptype, 119 SurfaceType dsttype) 120 { 121 /* 122 System.out.println("Constructing general blit for:"); 123 System.out.println("src: "+srctype); 124 System.out.println("comp: "+comptype); 125 System.out.println("dst: "+dsttype); 126 */ 127 128 if (comptype.isDerivedFrom(CompositeType.Xor)) { 129 GeneralXorBlit gxb = new GeneralXorBlit(srctype, 130 comptype, 131 dsttype); 132 setupGeneralBinaryOp(gxb); 133 return gxb; 134 } else if (comptype.isDerivedFrom(CompositeType.AnyAlpha)) { 135 return new GeneralMaskBlit(srctype, comptype, dsttype); 136 } else { 137 return AnyBlit.instance; 138 } 139 } 140 141 private static class AnyBlit extends Blit { 142 public static AnyBlit instance = new AnyBlit(); 143 144 public AnyBlit() { 145 super(SurfaceType.Any, CompositeType.Any, SurfaceType.Any); 146 } 147 148 public void Blit(SurfaceData srcData, 149 SurfaceData dstData, 150 Composite comp, 151 Region clip, 152 int srcx, int srcy, 153 int dstx, int dsty, 154 int width, int height) 155 { 156 ColorModel srcCM = srcData.getColorModel(); 157 ColorModel dstCM = dstData.getColorModel(); 158 // REMIND: Should get RenderingHints from sg2d 159 CompositeContext ctx = comp.createContext(srcCM, dstCM, 160 new RenderingHints(null)); 161 Raster srcRas = srcData.getRaster(srcx, srcy, width, height); 162 WritableRaster dstRas = 163 (WritableRaster) dstData.getRaster(dstx, dsty, width, height); 164 165 if (clip == null) { 166 clip = Region.getInstanceXYWH(dstx, dsty, width, height); 167 } 168 int[] span = {dstx, dsty, dstx+width, dsty+height}; 169 SpanIterator si = clip.getSpanIterator(span); 170 srcx -= dstx; 171 srcy -= dsty; 172 while (si.nextSpan(span)) { 173 int w = span[2] - span[0]; 174 int h = span[3] - span[1]; 175 Raster tmpSrcRas = srcRas.createChild(srcx + span[0], srcy + span[1], 176 w, h, 0, 0, null); 177 WritableRaster tmpDstRas = dstRas.createWritableChild(span[0], span[1], 178 w, h, 0, 0, null); 179 ctx.compose(tmpSrcRas, tmpDstRas, tmpDstRas); 180 } 181 ctx.dispose(); 182 } 183 } 184 185 private static class GeneralMaskBlit extends Blit { 186 MaskBlit performop; 187 188 public GeneralMaskBlit(SurfaceType srctype, 189 CompositeType comptype, 190 SurfaceType dsttype) 191 { 192 super(srctype, comptype, dsttype); 193 performop = MaskBlit.locate(srctype, comptype, dsttype); 194 } 195 196 public void Blit(SurfaceData srcData, 197 SurfaceData dstData, 198 Composite comp, 199 Region clip, 200 int srcx, int srcy, 201 int dstx, int dsty, 202 int width, int height) 203 { 204 performop.MaskBlit(srcData, dstData, comp, clip, 205 srcx, srcy, dstx, dsty, 206 width, height, 207 null, 0, 0); 208 } 209 } 210 211 private static class GeneralXorBlit 212 extends Blit 213 implements GeneralBinaryOp 214 { 215 Blit convertsrc; 216 Blit convertdst; 217 Blit performop; 218 Blit convertresult; 219 220 WeakReference<SurfaceData> srcTmp; 221 WeakReference<SurfaceData> dstTmp; 222 223 public GeneralXorBlit(SurfaceType srctype, 224 CompositeType comptype, 225 SurfaceType dsttype) 226 { 227 super(srctype, comptype, dsttype); 228 } 229 230 public void setPrimitives(Blit srcconverter, 231 Blit dstconverter, 232 GraphicsPrimitive genericop, 233 Blit resconverter) 234 { 235 this.convertsrc = srcconverter; 236 this.convertdst = dstconverter; 237 this.performop = (Blit) genericop; 238 this.convertresult = resconverter; 239 } 240 241 public synchronized void Blit(SurfaceData srcData, 242 SurfaceData dstData, 243 Composite comp, 244 Region clip, 245 int srcx, int srcy, 246 int dstx, int dsty, 247 int width, int height) 248 { 249 SurfaceData src, dst; 250 Region opclip; 251 int sx, sy, dx, dy; 252 253 if (convertsrc == null) { 254 src = srcData; 255 sx = srcx; 256 sy = srcy; 257 } else { 258 SurfaceData cachedSrc = null; 259 if (srcTmp != null) { 260 cachedSrc = srcTmp.get(); 261 } 262 src = convertFrom(convertsrc, srcData, srcx, srcy, 263 width, height, cachedSrc); 264 sx = 0; 265 sy = 0; 266 if (src != cachedSrc) { 267 srcTmp = new WeakReference<>(src); 268 } 269 } 270 271 if (convertdst == null) { 272 dst = dstData; 273 dx = dstx; 274 dy = dsty; 275 opclip = clip; 276 } else { 277 // assert: convertresult != null 278 SurfaceData cachedDst = null; 279 if (dstTmp != null) { 280 cachedDst = dstTmp.get(); 281 } 282 dst = convertFrom(convertdst, dstData, dstx, dsty, 283 width, height, cachedDst); 284 dx = 0; 285 dy = 0; 286 opclip = null; 287 if (dst != cachedDst) { 288 dstTmp = new WeakReference<>(dst); 289 } 290 } 291 292 performop.Blit(src, dst, comp, opclip, 293 sx, sy, dx, dy, 294 width, height); 295 296 if (convertresult != null) { 297 // assert: convertdst != null 298 convertTo(convertresult, dst, dstData, clip, 299 dstx, dsty, width, height); 300 } 301 } 302 } 303 304 public GraphicsPrimitive traceWrap() { 305 return new TraceBlit(this); 306 } 307 308 private static class TraceBlit extends Blit { 309 Blit target; 310 311 public TraceBlit(Blit target) { 312 super(target.getSourceType(), 313 target.getCompositeType(), 314 target.getDestType()); 315 this.target = target; 316 } 317 318 public GraphicsPrimitive traceWrap() { 319 return this; 320 } 321 322 public void Blit(SurfaceData src, SurfaceData dst, 323 Composite comp, Region clip, 324 int srcx, int srcy, int dstx, int dsty, 325 int width, int height) 326 { 327 if ((traceflags & TRACEPTIME) == 0) { 328 tracePrimitive(target); 329 } 330 long time = System.nanoTime(); 331 target.Blit(src, dst, comp, clip, 332 srcx, srcy, dstx, dsty, width, height); 333 tracePrimitiveTime(target, System.nanoTime() - time); 334 } 335 } 336 }