1 /* 2 * Copyright (c) 2019, 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.metal; 27 28 import java.awt.AlphaComposite; 29 import java.awt.Composite; 30 import java.awt.Transparency; 31 import java.awt.geom.AffineTransform; 32 import java.awt.image.AffineTransformOp; 33 import java.awt.image.BufferedImage; 34 import java.awt.image.BufferedImageOp; 35 import java.lang.ref.WeakReference; 36 import sun.java2d.SurfaceData; 37 import sun.java2d.loops.Blit; 38 import sun.java2d.loops.CompositeType; 39 import sun.java2d.loops.GraphicsPrimitive; 40 import sun.java2d.loops.GraphicsPrimitiveMgr; 41 import sun.java2d.loops.ScaledBlit; 42 import sun.java2d.loops.SurfaceType; 43 import sun.java2d.loops.TransformBlit; 44 import sun.java2d.pipe.Region; 45 import sun.java2d.pipe.RenderBuffer; 46 import sun.java2d.pipe.RenderQueue; 47 import static sun.java2d.pipe.BufferedOpCodes.*; 48 import java.lang.annotation.Native; 49 50 final class MetalBlitLoops { 51 52 static void register() { 53 /*Blit blitIntArgbPreToSurface = 54 new OGLSwToSurfaceBlit(SurfaceType.IntArgbPre, 55 OGLSurfaceData.PF_INT_ARGB_PRE); 56 Blit blitIntArgbPreToTexture = 57 new OGLSwToTextureBlit(SurfaceType.IntArgbPre, 58 OGLSurfaceData.PF_INT_ARGB_PRE); 59 TransformBlit transformBlitIntArgbPreToSurface = 60 new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre, 61 OGLSurfaceData.PF_INT_ARGB_PRE); 62 OGLSurfaceToSwBlit blitSurfaceToIntArgbPre = 63 new OGLSurfaceToSwBlit(SurfaceType.IntArgbPre, 64 OGLSurfaceData.PF_INT_ARGB_PRE);*/ 65 66 GraphicsPrimitive[] primitives = { 67 // surface->surface ops 68 new MetalSurfaceToSurfaceBlit(), 69 /*new OGLSurfaceToSurfaceBlit(), 70 new OGLSurfaceToSurfaceScale(), 71 new OGLSurfaceToSurfaceTransform(), 72 73 // render-to-texture surface->surface ops 74 new OGLRTTSurfaceToSurfaceBlit(), 75 new OGLRTTSurfaceToSurfaceScale(), 76 new OGLRTTSurfaceToSurfaceTransform(), 77 78 // surface->sw ops 79 new OGLSurfaceToSwBlit(SurfaceType.IntArgb, 80 OGLSurfaceData.PF_INT_ARGB), 81 blitSurfaceToIntArgbPre, 82 83 // sw->surface ops 84 blitIntArgbPreToSurface, 85 new OGLSwToSurfaceBlit(SurfaceType.IntRgb, 86 OGLSurfaceData.PF_INT_RGB), 87 new OGLSwToSurfaceBlit(SurfaceType.IntRgbx, 88 OGLSurfaceData.PF_INT_RGBX), 89 new OGLSwToSurfaceBlit(SurfaceType.IntBgr, 90 OGLSurfaceData.PF_INT_BGR), 91 new OGLSwToSurfaceBlit(SurfaceType.IntBgrx, 92 OGLSurfaceData.PF_INT_BGRX), 93 new OGLSwToSurfaceBlit(SurfaceType.ThreeByteBgr, 94 OGLSurfaceData.PF_3BYTE_BGR), 95 new OGLSwToSurfaceBlit(SurfaceType.Ushort565Rgb, 96 OGLSurfaceData.PF_USHORT_565_RGB), 97 new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgb, 98 OGLSurfaceData.PF_USHORT_555_RGB), 99 new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgbx, 100 OGLSurfaceData.PF_USHORT_555_RGBX), 101 new OGLSwToSurfaceBlit(SurfaceType.ByteGray, 102 OGLSurfaceData.PF_BYTE_GRAY), 103 new OGLSwToSurfaceBlit(SurfaceType.UshortGray, 104 OGLSurfaceData.PF_USHORT_GRAY), 105 new OGLGeneralBlit(OGLSurfaceData.OpenGLSurface, 106 CompositeType.AnyAlpha, 107 blitIntArgbPreToSurface), 108 109 new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLSurface, 110 blitSurfaceToIntArgbPre, 111 blitSurfaceToIntArgbPre, 112 blitIntArgbPreToSurface), 113 new OGLAnyCompositeBlit(SurfaceType.Any, 114 null, 115 blitSurfaceToIntArgbPre, 116 blitIntArgbPreToSurface), 117 118 new OGLSwToSurfaceScale(SurfaceType.IntRgb, 119 OGLSurfaceData.PF_INT_RGB), 120 new OGLSwToSurfaceScale(SurfaceType.IntRgbx, 121 OGLSurfaceData.PF_INT_RGBX), 122 new OGLSwToSurfaceScale(SurfaceType.IntBgr, 123 OGLSurfaceData.PF_INT_BGR), 124 new OGLSwToSurfaceScale(SurfaceType.IntBgrx, 125 OGLSurfaceData.PF_INT_BGRX), 126 new OGLSwToSurfaceScale(SurfaceType.ThreeByteBgr, 127 OGLSurfaceData.PF_3BYTE_BGR), 128 new OGLSwToSurfaceScale(SurfaceType.Ushort565Rgb, 129 OGLSurfaceData.PF_USHORT_565_RGB), 130 new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgb, 131 OGLSurfaceData.PF_USHORT_555_RGB), 132 new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgbx, 133 OGLSurfaceData.PF_USHORT_555_RGBX), 134 new OGLSwToSurfaceScale(SurfaceType.ByteGray, 135 OGLSurfaceData.PF_BYTE_GRAY), 136 new OGLSwToSurfaceScale(SurfaceType.UshortGray, 137 OGLSurfaceData.PF_USHORT_GRAY), 138 new OGLSwToSurfaceScale(SurfaceType.IntArgbPre, 139 OGLSurfaceData.PF_INT_ARGB_PRE), 140 141 new OGLSwToSurfaceTransform(SurfaceType.IntRgb, 142 OGLSurfaceData.PF_INT_RGB), 143 new OGLSwToSurfaceTransform(SurfaceType.IntRgbx, 144 OGLSurfaceData.PF_INT_RGBX), 145 new OGLSwToSurfaceTransform(SurfaceType.IntBgr, 146 OGLSurfaceData.PF_INT_BGR), 147 new OGLSwToSurfaceTransform(SurfaceType.IntBgrx, 148 OGLSurfaceData.PF_INT_BGRX), 149 new OGLSwToSurfaceTransform(SurfaceType.ThreeByteBgr, 150 OGLSurfaceData.PF_3BYTE_BGR), 151 new OGLSwToSurfaceTransform(SurfaceType.Ushort565Rgb, 152 OGLSurfaceData.PF_USHORT_565_RGB), 153 new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgb, 154 OGLSurfaceData.PF_USHORT_555_RGB), 155 new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgbx, 156 OGLSurfaceData.PF_USHORT_555_RGBX), 157 new OGLSwToSurfaceTransform(SurfaceType.ByteGray, 158 OGLSurfaceData.PF_BYTE_GRAY), 159 new OGLSwToSurfaceTransform(SurfaceType.UshortGray, 160 OGLSurfaceData.PF_USHORT_GRAY), 161 transformBlitIntArgbPreToSurface, 162 163 new OGLGeneralTransformedBlit(transformBlitIntArgbPreToSurface), 164 165 // texture->surface ops 166 new OGLTextureToSurfaceBlit(), 167 new OGLTextureToSurfaceScale(), 168 new OGLTextureToSurfaceTransform(), 169 170 // sw->texture ops 171 blitIntArgbPreToTexture, 172 new OGLSwToTextureBlit(SurfaceType.IntRgb, 173 OGLSurfaceData.PF_INT_RGB), 174 new OGLSwToTextureBlit(SurfaceType.IntRgbx, 175 OGLSurfaceData.PF_INT_RGBX), 176 new OGLSwToTextureBlit(SurfaceType.IntBgr, 177 OGLSurfaceData.PF_INT_BGR), 178 new OGLSwToTextureBlit(SurfaceType.IntBgrx, 179 OGLSurfaceData.PF_INT_BGRX), 180 new OGLSwToTextureBlit(SurfaceType.ThreeByteBgr, 181 OGLSurfaceData.PF_3BYTE_BGR), 182 new OGLSwToTextureBlit(SurfaceType.Ushort565Rgb, 183 OGLSurfaceData.PF_USHORT_565_RGB), 184 new OGLSwToTextureBlit(SurfaceType.Ushort555Rgb, 185 OGLSurfaceData.PF_USHORT_555_RGB), 186 new OGLSwToTextureBlit(SurfaceType.Ushort555Rgbx, 187 OGLSurfaceData.PF_USHORT_555_RGBX), 188 new OGLSwToTextureBlit(SurfaceType.ByteGray, 189 OGLSurfaceData.PF_BYTE_GRAY), 190 new OGLSwToTextureBlit(SurfaceType.UshortGray, 191 OGLSurfaceData.PF_USHORT_GRAY), 192 new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture, 193 CompositeType.SrcNoEa, 194 blitIntArgbPreToTexture),*/ 195 }; 196 GraphicsPrimitiveMgr.register(primitives); 197 } 198 199 /** 200 * The following offsets are used to pack the parameters in 201 * createPackedParams(). (They are also used at the native level when 202 * unpacking the params.) 203 */ 204 @Native private static final int OFFSET_SRCTYPE = 16; 205 @Native private static final int OFFSET_HINT = 8; 206 @Native private static final int OFFSET_TEXTURE = 3; 207 @Native private static final int OFFSET_RTT = 2; 208 @Native private static final int OFFSET_XFORM = 1; 209 @Native private static final int OFFSET_ISOBLIT = 0; 210 211 /** 212 * Packs the given parameters into a single int value in order to save 213 * space on the rendering queue. 214 */ 215 private static int createPackedParams(boolean isoblit, boolean texture, 216 boolean rtt, boolean xform, 217 int hint, int srctype) 218 { 219 return 220 ((srctype << OFFSET_SRCTYPE) | 221 (hint << OFFSET_HINT ) | 222 ((texture ? 1 : 0) << OFFSET_TEXTURE) | 223 ((rtt ? 1 : 0) << OFFSET_RTT ) | 224 ((xform ? 1 : 0) << OFFSET_XFORM ) | 225 ((isoblit ? 1 : 0) << OFFSET_ISOBLIT)); 226 } 227 228 /** 229 * Enqueues a BLIT operation with the given parameters. Note that the 230 * RenderQueue lock must be held before calling this method. 231 */ 232 private static void enqueueBlit(RenderQueue rq, 233 SurfaceData src, SurfaceData dst, 234 int packedParams, 235 int sx1, int sy1, 236 int sx2, int sy2, 237 double dx1, double dy1, 238 double dx2, double dy2) 239 { 240 // assert rq.lock.isHeldByCurrentThread(); 241 RenderBuffer buf = rq.getBuffer(); 242 rq.ensureCapacityAndAlignment(72, 24); 243 buf.putInt(BLIT); 244 buf.putInt(packedParams); 245 buf.putInt(sx1).putInt(sy1); 246 buf.putInt(sx2).putInt(sy2); 247 buf.putDouble(dx1).putDouble(dy1); 248 buf.putDouble(dx2).putDouble(dy2); 249 buf.putLong(src.getNativeOps()); 250 buf.putLong(dst.getNativeOps()); 251 } 252 253 /*static void Blit(SurfaceData srcData, SurfaceData dstData, 254 Composite comp, Region clip, 255 AffineTransform xform, int hint, 256 int sx1, int sy1, 257 int sx2, int sy2, 258 double dx1, double dy1, 259 double dx2, double dy2, 260 int srctype, boolean texture) 261 { 262 int ctxflags = 0; 263 if (srcData.getTransparency() == Transparency.OPAQUE) { 264 ctxflags |= OGLContext.SRC_IS_OPAQUE; 265 } 266 267 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 268 rq.lock(); 269 try { 270 // make sure the RenderQueue keeps a hard reference to the 271 // source (sysmem) SurfaceData to prevent it from being 272 // disposed while the operation is processed on the QFT 273 rq.addReference(srcData); 274 275 OGLSurfaceData oglDst = (OGLSurfaceData)dstData; 276 if (texture) { 277 // make sure we have a current context before uploading 278 // the sysmem data to the texture object 279 OGLGraphicsConfig gc = oglDst.getOGLGraphicsConfig(); 280 OGLContext.setScratchSurface(gc); 281 } else { 282 OGLContext.validateContext(oglDst, oglDst, 283 clip, comp, xform, null, null, 284 ctxflags); 285 } 286 287 int packedParams = createPackedParams(false, texture, 288 false, xform != null, 289 hint, srctype); 290 enqueueBlit(rq, srcData, dstData, 291 packedParams, 292 sx1, sy1, sx2, sy2, 293 dx1, dy1, dx2, dy2); 294 295 // always flush immediately, since we (currently) have no means 296 // of tracking changes to the system memory surface 297 rq.flushNow(); 298 } finally { 299 rq.unlock(); 300 } 301 }*/ 302 303 /** 304 * Note: The srcImg and biop parameters are only used when invoked 305 * from the OGLBufImgOps.renderImageWithOp() method; in all other cases, 306 * this method can be called with null values for those two parameters, 307 * and they will be effectively ignored. 308 */ 309 static void IsoBlit(SurfaceData srcData, SurfaceData dstData, 310 BufferedImage srcImg, BufferedImageOp biop, 311 Composite comp, Region clip, 312 AffineTransform xform, int hint, 313 int sx1, int sy1, 314 int sx2, int sy2, 315 double dx1, double dy1, 316 double dx2, double dy2, 317 boolean texture) 318 { 319 /*int ctxflags = 0; 320 if (srcData.getTransparency() == Transparency.OPAQUE) { 321 ctxflags |= OGLContext.SRC_IS_OPAQUE; 322 }*/ 323 324 MetalRenderQueue rq = MetalRenderQueue.getInstance(); 325 rq.lock(); 326 try { 327 MetalSurfaceData metalSrc = (MetalSurfaceData)srcData; 328 MetalSurfaceData metalDst = (MetalSurfaceData)dstData; 329 int srctype = metalSrc.getType(); 330 /*boolean rtt; 331 OGLSurfaceData srcCtxData; 332 if (srctype == OGLSurfaceData.TEXTURE) { 333 // the source is a regular texture object; we substitute 334 // the destination surface for the purposes of making a 335 // context current 336 rtt = false; 337 srcCtxData = oglDst; 338 } else { 339 // the source is a pbuffer, backbuffer, or render-to-texture 340 // surface; we set rtt to true to differentiate this kind 341 // of surface from a regular texture object 342 rtt = true; 343 if (srctype == OGLSurfaceData.FBOBJECT) { 344 srcCtxData = oglDst; 345 } else { 346 srcCtxData = oglSrc; 347 } 348 } 349 350 OGLContext.validateContext(srcCtxData, oglDst, 351 clip, comp, xform, null, null, 352 ctxflags); 353 354 if (biop != null) { 355 OGLBufImgOps.enableBufImgOp(rq, oglSrc, srcImg, biop); 356 }*/ 357 358 int packedParams = createPackedParams(true, texture, 359 false, xform != null, 360 hint, 0 /*unused*/); 361 enqueueBlit(rq, srcData, dstData, 362 packedParams, 363 sx1, sy1, sx2, sy2, 364 dx1, dy1, dx2, dy2); 365 366 /*if (biop != null) { 367 OGLBufImgOps.disableBufImgOp(rq, biop); 368 } 369 370 if (rtt && oglDst.isOnScreen()) { 371 // we only have to flush immediately when copying from a 372 // (non-texture) surface to the screen; otherwise Swing apps 373 // might appear unresponsive until the auto-flush completes 374 rq.flushNow(); 375 }*/ 376 } finally { 377 rq.unlock(); 378 } 379 } 380 } 381 382 /*class OGLSurfaceToSurfaceBlit extends Blit { 383 384 OGLSurfaceToSurfaceBlit() { 385 super(OGLSurfaceData.OpenGLSurface, 386 CompositeType.AnyAlpha, 387 OGLSurfaceData.OpenGLSurface); 388 } 389 390 public void Blit(SurfaceData src, SurfaceData dst, 391 Composite comp, Region clip, 392 int sx, int sy, int dx, int dy, int w, int h) 393 { 394 OGLBlitLoops.IsoBlit(src, dst, 395 null, null, 396 comp, clip, null, 397 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 398 sx, sy, sx+w, sy+h, 399 dx, dy, dx+w, dy+h, 400 false); 401 } 402 } 403 404 class OGLSurfaceToSurfaceScale extends ScaledBlit { 405 406 OGLSurfaceToSurfaceScale() { 407 super(OGLSurfaceData.OpenGLSurface, 408 CompositeType.AnyAlpha, 409 OGLSurfaceData.OpenGLSurface); 410 } 411 412 public void Scale(SurfaceData src, SurfaceData dst, 413 Composite comp, Region clip, 414 int sx1, int sy1, 415 int sx2, int sy2, 416 double dx1, double dy1, 417 double dx2, double dy2) 418 { 419 OGLBlitLoops.IsoBlit(src, dst, 420 null, null, 421 comp, clip, null, 422 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 423 sx1, sy1, sx2, sy2, 424 dx1, dy1, dx2, dy2, 425 false); 426 } 427 } 428 429 class OGLSurfaceToSurfaceTransform extends TransformBlit { 430 431 OGLSurfaceToSurfaceTransform() { 432 super(OGLSurfaceData.OpenGLSurface, 433 CompositeType.AnyAlpha, 434 OGLSurfaceData.OpenGLSurface); 435 } 436 437 public void Transform(SurfaceData src, SurfaceData dst, 438 Composite comp, Region clip, 439 AffineTransform at, int hint, 440 int sx, int sy, int dx, int dy, 441 int w, int h) 442 { 443 OGLBlitLoops.IsoBlit(src, dst, 444 null, null, 445 comp, clip, at, hint, 446 sx, sy, sx+w, sy+h, 447 dx, dy, dx+w, dy+h, 448 false); 449 } 450 }*/ 451 452 class MetalSurfaceToSurfaceBlit extends Blit { 453 454 MetalSurfaceToSurfaceBlit() { 455 super(MetalSurfaceData.MetalSurface, 456 CompositeType.AnyAlpha, 457 MetalSurfaceData.MetalSurface); 458 } 459 460 public void Blit(SurfaceData src, SurfaceData dst, 461 Composite comp, Region clip, 462 int sx, int sy, int dx, int dy, int w, int h) 463 { 464 // TODO : Eventhough we push IsoBlit logic into queue, 465 // in renderer we have not yet implemented blit. 466 MetalBlitLoops.IsoBlit(src, dst, 467 null, null, 468 comp, clip, null, 469 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 470 sx, sy, sx+w, sy+h, 471 dx, dy, dx+w, dy+h, 472 true); 473 } 474 } 475 476 /*class OGLRTTSurfaceToSurfaceScale extends ScaledBlit { 477 478 OGLRTTSurfaceToSurfaceScale() { 479 super(OGLSurfaceData.OpenGLSurfaceRTT, 480 CompositeType.AnyAlpha, 481 OGLSurfaceData.OpenGLSurface); 482 } 483 484 public void Scale(SurfaceData src, SurfaceData dst, 485 Composite comp, Region clip, 486 int sx1, int sy1, 487 int sx2, int sy2, 488 double dx1, double dy1, 489 double dx2, double dy2) 490 { 491 OGLBlitLoops.IsoBlit(src, dst, 492 null, null, 493 comp, clip, null, 494 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 495 sx1, sy1, sx2, sy2, 496 dx1, dy1, dx2, dy2, 497 true); 498 } 499 } 500 501 class OGLRTTSurfaceToSurfaceTransform extends TransformBlit { 502 503 OGLRTTSurfaceToSurfaceTransform() { 504 super(OGLSurfaceData.OpenGLSurfaceRTT, 505 CompositeType.AnyAlpha, 506 OGLSurfaceData.OpenGLSurface); 507 } 508 509 public void Transform(SurfaceData src, SurfaceData dst, 510 Composite comp, Region clip, 511 AffineTransform at, int hint, 512 int sx, int sy, int dx, int dy, int w, int h) 513 { 514 OGLBlitLoops.IsoBlit(src, dst, 515 null, null, 516 comp, clip, at, hint, 517 sx, sy, sx+w, sy+h, 518 dx, dy, dx+w, dy+h, 519 true); 520 } 521 } 522 523 final class OGLSurfaceToSwBlit extends Blit { 524 525 private final int typeval; 526 private WeakReference<SurfaceData> srcTmp; 527 528 // destination will actually be ArgbPre or Argb 529 OGLSurfaceToSwBlit(final SurfaceType dstType,final int typeval) { 530 super(OGLSurfaceData.OpenGLSurface, 531 CompositeType.SrcNoEa, 532 dstType); 533 this.typeval = typeval; 534 } 535 536 private synchronized void complexClipBlit(SurfaceData src, SurfaceData dst, 537 Composite comp, Region clip, 538 int sx, int sy, int dx, int dy, 539 int w, int h) { 540 SurfaceData cachedSrc = null; 541 if (srcTmp != null) { 542 // use cached intermediate surface, if available 543 cachedSrc = srcTmp.get(); 544 } 545 546 // We can convert argb_pre data from OpenGL surface in two places: 547 // - During OpenGL surface -> SW blit 548 // - During SW -> SW blit 549 // The first one is faster when we use opaque OGL surface, because in 550 // this case we simply skip conversion and use color components as is. 551 // Because of this we align intermediate buffer type with type of 552 // destination not source. 553 final int type = typeval == OGLSurfaceData.PF_INT_ARGB_PRE ? 554 BufferedImage.TYPE_INT_ARGB_PRE : 555 BufferedImage.TYPE_INT_ARGB; 556 557 src = convertFrom(this, src, sx, sy, w, h, cachedSrc, type); 558 559 // copy intermediate SW to destination SW using complex clip 560 final Blit performop = Blit.getFromCache(src.getSurfaceType(), 561 CompositeType.SrcNoEa, 562 dst.getSurfaceType()); 563 performop.Blit(src, dst, comp, clip, 0, 0, dx, dy, w, h); 564 565 if (src != cachedSrc) { 566 // cache the intermediate surface 567 srcTmp = new WeakReference<>(src); 568 } 569 } 570 571 public void Blit(SurfaceData src, SurfaceData dst, 572 Composite comp, Region clip, 573 int sx, int sy, int dx, int dy, 574 int w, int h) 575 { 576 if (clip != null) { 577 clip = clip.getIntersectionXYWH(dx, dy, w, h); 578 // At the end this method will flush the RenderQueue, we should exit 579 // from it as soon as possible. 580 if (clip.isEmpty()) { 581 return; 582 } 583 sx += clip.getLoX() - dx; 584 sy += clip.getLoY() - dy; 585 dx = clip.getLoX(); 586 dy = clip.getLoY(); 587 w = clip.getWidth(); 588 h = clip.getHeight(); 589 590 if (!clip.isRectangular()) { 591 complexClipBlit(src, dst, comp, clip, sx, sy, dx, dy, w, h); 592 return; 593 } 594 } 595 596 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 597 rq.lock(); 598 try { 599 // make sure the RenderQueue keeps a hard reference to the 600 // destination (sysmem) SurfaceData to prevent it from being 601 // disposed while the operation is processed on the QFT 602 rq.addReference(dst); 603 604 RenderBuffer buf = rq.getBuffer(); 605 OGLContext.validateContext((OGLSurfaceData)src); 606 607 rq.ensureCapacityAndAlignment(48, 32); 608 buf.putInt(SURFACE_TO_SW_BLIT); 609 buf.putInt(sx).putInt(sy); 610 buf.putInt(dx).putInt(dy); 611 buf.putInt(w).putInt(h); 612 buf.putInt(typeval); 613 buf.putLong(src.getNativeOps()); 614 buf.putLong(dst.getNativeOps()); 615 616 // always flush immediately 617 rq.flushNow(); 618 } finally { 619 rq.unlock(); 620 } 621 } 622 } 623 624 class OGLSwToSurfaceBlit extends Blit { 625 626 private int typeval; 627 628 OGLSwToSurfaceBlit(SurfaceType srcType, int typeval) { 629 super(srcType, 630 CompositeType.AnyAlpha, 631 OGLSurfaceData.OpenGLSurface); 632 this.typeval = typeval; 633 } 634 635 public void Blit(SurfaceData src, SurfaceData dst, 636 Composite comp, Region clip, 637 int sx, int sy, int dx, int dy, int w, int h) 638 { 639 OGLBlitLoops.Blit(src, dst, 640 comp, clip, null, 641 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 642 sx, sy, sx+w, sy+h, 643 dx, dy, dx+w, dy+h, 644 typeval, false); 645 } 646 } 647 648 class OGLSwToSurfaceScale extends ScaledBlit { 649 650 private int typeval; 651 652 OGLSwToSurfaceScale(SurfaceType srcType, int typeval) { 653 super(srcType, 654 CompositeType.AnyAlpha, 655 OGLSurfaceData.OpenGLSurface); 656 this.typeval = typeval; 657 } 658 659 public void Scale(SurfaceData src, SurfaceData dst, 660 Composite comp, Region clip, 661 int sx1, int sy1, 662 int sx2, int sy2, 663 double dx1, double dy1, 664 double dx2, double dy2) 665 { 666 OGLBlitLoops.Blit(src, dst, 667 comp, clip, null, 668 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 669 sx1, sy1, sx2, sy2, 670 dx1, dy1, dx2, dy2, 671 typeval, false); 672 } 673 } 674 675 class OGLSwToSurfaceTransform extends TransformBlit { 676 677 private int typeval; 678 679 OGLSwToSurfaceTransform(SurfaceType srcType, int typeval) { 680 super(srcType, 681 CompositeType.AnyAlpha, 682 OGLSurfaceData.OpenGLSurface); 683 this.typeval = typeval; 684 } 685 686 public void Transform(SurfaceData src, SurfaceData dst, 687 Composite comp, Region clip, 688 AffineTransform at, int hint, 689 int sx, int sy, int dx, int dy, int w, int h) 690 { 691 OGLBlitLoops.Blit(src, dst, 692 comp, clip, at, hint, 693 sx, sy, sx+w, sy+h, 694 dx, dy, dx+w, dy+h, 695 typeval, false); 696 } 697 } 698 699 class OGLSwToTextureBlit extends Blit { 700 701 private int typeval; 702 703 OGLSwToTextureBlit(SurfaceType srcType, int typeval) { 704 super(srcType, 705 CompositeType.SrcNoEa, 706 OGLSurfaceData.OpenGLTexture); 707 this.typeval = typeval; 708 } 709 710 public void Blit(SurfaceData src, SurfaceData dst, 711 Composite comp, Region clip, 712 int sx, int sy, int dx, int dy, int w, int h) 713 { 714 OGLBlitLoops.Blit(src, dst, 715 comp, clip, null, 716 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 717 sx, sy, sx+w, sy+h, 718 dx, dy, dx+w, dy+h, 719 typeval, true); 720 } 721 } 722 723 class OGLTextureToSurfaceBlit extends Blit { 724 725 OGLTextureToSurfaceBlit() { 726 super(OGLSurfaceData.OpenGLTexture, 727 CompositeType.AnyAlpha, 728 OGLSurfaceData.OpenGLSurface); 729 } 730 731 public void Blit(SurfaceData src, SurfaceData dst, 732 Composite comp, Region clip, 733 int sx, int sy, int dx, int dy, int w, int h) 734 { 735 OGLBlitLoops.IsoBlit(src, dst, 736 null, null, 737 comp, clip, null, 738 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 739 sx, sy, sx+w, sy+h, 740 dx, dy, dx+w, dy+h, 741 true); 742 } 743 } 744 745 class OGLTextureToSurfaceScale extends ScaledBlit { 746 747 OGLTextureToSurfaceScale() { 748 super(OGLSurfaceData.OpenGLTexture, 749 CompositeType.AnyAlpha, 750 OGLSurfaceData.OpenGLSurface); 751 } 752 753 public void Scale(SurfaceData src, SurfaceData dst, 754 Composite comp, Region clip, 755 int sx1, int sy1, 756 int sx2, int sy2, 757 double dx1, double dy1, 758 double dx2, double dy2) 759 { 760 OGLBlitLoops.IsoBlit(src, dst, 761 null, null, 762 comp, clip, null, 763 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 764 sx1, sy1, sx2, sy2, 765 dx1, dy1, dx2, dy2, 766 true); 767 } 768 } 769 770 class OGLTextureToSurfaceTransform extends TransformBlit { 771 772 OGLTextureToSurfaceTransform() { 773 super(OGLSurfaceData.OpenGLTexture, 774 CompositeType.AnyAlpha, 775 OGLSurfaceData.OpenGLSurface); 776 } 777 778 public void Transform(SurfaceData src, SurfaceData dst, 779 Composite comp, Region clip, 780 AffineTransform at, int hint, 781 int sx, int sy, int dx, int dy, 782 int w, int h) 783 { 784 OGLBlitLoops.IsoBlit(src, dst, 785 null, null, 786 comp, clip, at, hint, 787 sx, sy, sx+w, sy+h, 788 dx, dy, dx+w, dy+h, 789 true); 790 } 791 }*/ 792 793 /** 794 * This general Blit implementation converts any source surface to an 795 * intermediate IntArgbPre surface, and then uses the more specific 796 * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate 797 * (premultiplied) surface down to OpenGL using simple blit. 798 */ 799 /*class OGLGeneralBlit extends Blit { 800 801 private final Blit performop; 802 private WeakReference<SurfaceData> srcTmp; 803 804 OGLGeneralBlit(SurfaceType dstType, 805 CompositeType compType, 806 Blit performop) 807 { 808 super(SurfaceType.Any, compType, dstType); 809 this.performop = performop; 810 } 811 812 public synchronized void Blit(SurfaceData src, SurfaceData dst, 813 Composite comp, Region clip, 814 int sx, int sy, int dx, int dy, 815 int w, int h) 816 { 817 Blit convertsrc = Blit.getFromCache(src.getSurfaceType(), 818 CompositeType.SrcNoEa, 819 SurfaceType.IntArgbPre); 820 821 SurfaceData cachedSrc = null; 822 if (srcTmp != null) { 823 // use cached intermediate surface, if available 824 cachedSrc = srcTmp.get(); 825 } 826 827 // convert source to IntArgbPre 828 src = convertFrom(convertsrc, src, sx, sy, w, h, 829 cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE); 830 831 // copy IntArgbPre intermediate surface to OpenGL surface 832 performop.Blit(src, dst, comp, clip, 833 0, 0, dx, dy, w, h); 834 835 if (src != cachedSrc) { 836 // cache the intermediate surface 837 srcTmp = new WeakReference<>(src); 838 } 839 } 840 }*/ 841 842 /** 843 * This general TransformedBlit implementation converts any source surface to an 844 * intermediate IntArgbPre surface, and then uses the more specific 845 * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate 846 * (premultiplied) surface down to OpenGL using simple transformBlit. 847 */ 848 /*final class OGLGeneralTransformedBlit extends TransformBlit { 849 850 private final TransformBlit performop; 851 private WeakReference<SurfaceData> srcTmp; 852 853 OGLGeneralTransformedBlit(final TransformBlit performop) { 854 super(SurfaceType.Any, CompositeType.AnyAlpha, 855 OGLSurfaceData.OpenGLSurface); 856 this.performop = performop; 857 } 858 859 @Override 860 public synchronized void Transform(SurfaceData src, SurfaceData dst, 861 Composite comp, Region clip, 862 AffineTransform at, int hint, int srcx, 863 int srcy, int dstx, int dsty, int width, 864 int height){ 865 Blit convertsrc = Blit.getFromCache(src.getSurfaceType(), 866 CompositeType.SrcNoEa, 867 SurfaceType.IntArgbPre); 868 // use cached intermediate surface, if available 869 final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null; 870 // convert source to IntArgbPre 871 src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc, 872 BufferedImage.TYPE_INT_ARGB_PRE); 873 874 // transform IntArgbPre intermediate surface to OpenGL surface 875 performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty, 876 width, height); 877 878 if (src != cachedSrc) { 879 // cache the intermediate surface 880 srcTmp = new WeakReference<>(src); 881 } 882 } 883 }*/ 884 885 /** 886 * This general OGLAnyCompositeBlit implementation can convert any source/target 887 * surface to an intermediate surface using convertsrc/convertdst loops, applies 888 * necessary composite operation, and then uses convertresult loop to get the 889 * intermediate surface down to OpenGL. 890 */ 891 /*final class OGLAnyCompositeBlit extends Blit { 892 893 private WeakReference<SurfaceData> dstTmp; 894 private WeakReference<SurfaceData> srcTmp; 895 private final Blit convertsrc; 896 private final Blit convertdst; 897 private final Blit convertresult; 898 899 OGLAnyCompositeBlit(SurfaceType srctype, Blit convertsrc, Blit convertdst, 900 Blit convertresult) { 901 super(srctype, CompositeType.Any, OGLSurfaceData.OpenGLSurface); 902 this.convertsrc = convertsrc; 903 this.convertdst = convertdst; 904 this.convertresult = convertresult; 905 } 906 907 public synchronized void Blit(SurfaceData src, SurfaceData dst, 908 Composite comp, Region clip, 909 int sx, int sy, int dx, int dy, 910 int w, int h) 911 { 912 if (convertsrc != null) { 913 SurfaceData cachedSrc = null; 914 if (srcTmp != null) { 915 // use cached intermediate surface, if available 916 cachedSrc = srcTmp.get(); 917 } 918 // convert source to IntArgbPre 919 src = convertFrom(convertsrc, src, sx, sy, w, h, cachedSrc, 920 BufferedImage.TYPE_INT_ARGB_PRE); 921 if (src != cachedSrc) { 922 // cache the intermediate surface 923 srcTmp = new WeakReference<>(src); 924 } 925 } 926 927 SurfaceData cachedDst = null; 928 929 if (dstTmp != null) { 930 // use cached intermediate surface, if available 931 cachedDst = dstTmp.get(); 932 } 933 934 // convert destination to IntArgbPre 935 SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h, 936 cachedDst, BufferedImage.TYPE_INT_ARGB_PRE); 937 Region bufferClip = 938 clip == null ? null : clip.getTranslatedRegion(-dx, -dy); 939 940 Blit performop = Blit.getFromCache(src.getSurfaceType(), 941 CompositeType.Any, dstBuffer.getSurfaceType()); 942 performop.Blit(src, dstBuffer, comp, bufferClip, sx, sy, 0, 0, w, h); 943 944 if (dstBuffer != cachedDst) { 945 // cache the intermediate surface 946 dstTmp = new WeakReference<>(dstBuffer); 947 } 948 // now blit the buffer back to the destination 949 convertresult.Blit(dstBuffer, dst, AlphaComposite.Src, clip, 0, 0, dx, 950 dy, w, h); 951 } 952 }*/