1 /* 2 * Copyright (c) 2003, 2007, 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.opengl; 27 28 import java.awt.Composite; 29 import java.awt.Transparency; 30 import java.awt.geom.AffineTransform; 31 import java.awt.image.AffineTransformOp; 32 import java.awt.image.BufferedImage; 33 import java.awt.image.BufferedImageOp; 34 import java.lang.ref.WeakReference; 35 import sun.java2d.SurfaceData; 36 import sun.java2d.loops.Blit; 37 import sun.java2d.loops.CompositeType; 38 import sun.java2d.loops.GraphicsPrimitive; 39 import sun.java2d.loops.GraphicsPrimitiveMgr; 40 import sun.java2d.loops.ScaledBlit; 41 import sun.java2d.loops.SurfaceType; 42 import sun.java2d.loops.TransformBlit; 43 import sun.java2d.pipe.Region; 44 import sun.java2d.pipe.RenderBuffer; 45 import sun.java2d.pipe.RenderQueue; 46 import static sun.java2d.pipe.BufferedOpCodes.*; 47 import javax.tools.annotation.GenerateNativeHeader; 48 49 /* No native methods here, but the constants are needed in the supporting JNI code */ 50 @GenerateNativeHeader 51 class OGLBlitLoops { 52 53 static void register() { 54 Blit blitIntArgbPreToSurface = 55 new OGLSwToSurfaceBlit(SurfaceType.IntArgbPre, 56 OGLSurfaceData.PF_INT_ARGB_PRE); 57 Blit blitIntArgbPreToTexture = 58 new OGLSwToTextureBlit(SurfaceType.IntArgbPre, 59 OGLSurfaceData.PF_INT_ARGB_PRE); 60 61 GraphicsPrimitive[] primitives = { 62 // surface->surface ops 63 new OGLSurfaceToSurfaceBlit(), 64 new OGLSurfaceToSurfaceScale(), 65 new OGLSurfaceToSurfaceTransform(), 66 67 // render-to-texture surface->surface ops 68 new OGLRTTSurfaceToSurfaceBlit(), 69 new OGLRTTSurfaceToSurfaceScale(), 70 new OGLRTTSurfaceToSurfaceTransform(), 71 72 // surface->sw ops 73 new OGLSurfaceToSwBlit(SurfaceType.IntArgb, 74 OGLSurfaceData.PF_INT_ARGB), 75 76 // sw->surface ops 77 blitIntArgbPreToSurface, 78 new OGLSwToSurfaceBlit(SurfaceType.IntRgb, 79 OGLSurfaceData.PF_INT_RGB), 80 new OGLSwToSurfaceBlit(SurfaceType.IntRgbx, 81 OGLSurfaceData.PF_INT_RGBX), 82 new OGLSwToSurfaceBlit(SurfaceType.IntBgr, 83 OGLSurfaceData.PF_INT_BGR), 84 new OGLSwToSurfaceBlit(SurfaceType.IntBgrx, 85 OGLSurfaceData.PF_INT_BGRX), 86 new OGLSwToSurfaceBlit(SurfaceType.ThreeByteBgr, 87 OGLSurfaceData.PF_3BYTE_BGR), 88 new OGLSwToSurfaceBlit(SurfaceType.Ushort565Rgb, 89 OGLSurfaceData.PF_USHORT_565_RGB), 90 new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgb, 91 OGLSurfaceData.PF_USHORT_555_RGB), 92 new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgbx, 93 OGLSurfaceData.PF_USHORT_555_RGBX), 94 new OGLSwToSurfaceBlit(SurfaceType.ByteGray, 95 OGLSurfaceData.PF_BYTE_GRAY), 96 new OGLSwToSurfaceBlit(SurfaceType.UshortGray, 97 OGLSurfaceData.PF_USHORT_GRAY), 98 new OGLGeneralBlit(OGLSurfaceData.OpenGLSurface, 99 CompositeType.AnyAlpha, 100 blitIntArgbPreToSurface), 101 102 new OGLSwToSurfaceScale(SurfaceType.IntRgb, 103 OGLSurfaceData.PF_INT_RGB), 104 new OGLSwToSurfaceScale(SurfaceType.IntRgbx, 105 OGLSurfaceData.PF_INT_RGBX), 106 new OGLSwToSurfaceScale(SurfaceType.IntBgr, 107 OGLSurfaceData.PF_INT_BGR), 108 new OGLSwToSurfaceScale(SurfaceType.IntBgrx, 109 OGLSurfaceData.PF_INT_BGRX), 110 new OGLSwToSurfaceScale(SurfaceType.ThreeByteBgr, 111 OGLSurfaceData.PF_3BYTE_BGR), 112 new OGLSwToSurfaceScale(SurfaceType.Ushort565Rgb, 113 OGLSurfaceData.PF_USHORT_565_RGB), 114 new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgb, 115 OGLSurfaceData.PF_USHORT_555_RGB), 116 new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgbx, 117 OGLSurfaceData.PF_USHORT_555_RGBX), 118 new OGLSwToSurfaceScale(SurfaceType.ByteGray, 119 OGLSurfaceData.PF_BYTE_GRAY), 120 new OGLSwToSurfaceScale(SurfaceType.UshortGray, 121 OGLSurfaceData.PF_USHORT_GRAY), 122 new OGLSwToSurfaceScale(SurfaceType.IntArgbPre, 123 OGLSurfaceData.PF_INT_ARGB_PRE), 124 125 new OGLSwToSurfaceTransform(SurfaceType.IntRgb, 126 OGLSurfaceData.PF_INT_RGB), 127 new OGLSwToSurfaceTransform(SurfaceType.IntRgbx, 128 OGLSurfaceData.PF_INT_RGBX), 129 new OGLSwToSurfaceTransform(SurfaceType.IntBgr, 130 OGLSurfaceData.PF_INT_BGR), 131 new OGLSwToSurfaceTransform(SurfaceType.IntBgrx, 132 OGLSurfaceData.PF_INT_BGRX), 133 new OGLSwToSurfaceTransform(SurfaceType.ThreeByteBgr, 134 OGLSurfaceData.PF_3BYTE_BGR), 135 new OGLSwToSurfaceTransform(SurfaceType.Ushort565Rgb, 136 OGLSurfaceData.PF_USHORT_565_RGB), 137 new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgb, 138 OGLSurfaceData.PF_USHORT_555_RGB), 139 new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgbx, 140 OGLSurfaceData.PF_USHORT_555_RGBX), 141 new OGLSwToSurfaceTransform(SurfaceType.ByteGray, 142 OGLSurfaceData.PF_BYTE_GRAY), 143 new OGLSwToSurfaceTransform(SurfaceType.UshortGray, 144 OGLSurfaceData.PF_USHORT_GRAY), 145 new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre, 146 OGLSurfaceData.PF_INT_ARGB_PRE), 147 148 // texture->surface ops 149 new OGLTextureToSurfaceBlit(), 150 new OGLTextureToSurfaceScale(), 151 new OGLTextureToSurfaceTransform(), 152 153 // sw->texture ops 154 blitIntArgbPreToTexture, 155 new OGLSwToTextureBlit(SurfaceType.IntRgb, 156 OGLSurfaceData.PF_INT_RGB), 157 new OGLSwToTextureBlit(SurfaceType.IntRgbx, 158 OGLSurfaceData.PF_INT_RGBX), 159 new OGLSwToTextureBlit(SurfaceType.IntBgr, 160 OGLSurfaceData.PF_INT_BGR), 161 new OGLSwToTextureBlit(SurfaceType.IntBgrx, 162 OGLSurfaceData.PF_INT_BGRX), 163 new OGLSwToTextureBlit(SurfaceType.ThreeByteBgr, 164 OGLSurfaceData.PF_3BYTE_BGR), 165 new OGLSwToTextureBlit(SurfaceType.Ushort565Rgb, 166 OGLSurfaceData.PF_USHORT_565_RGB), 167 new OGLSwToTextureBlit(SurfaceType.Ushort555Rgb, 168 OGLSurfaceData.PF_USHORT_555_RGB), 169 new OGLSwToTextureBlit(SurfaceType.Ushort555Rgbx, 170 OGLSurfaceData.PF_USHORT_555_RGBX), 171 new OGLSwToTextureBlit(SurfaceType.ByteGray, 172 OGLSurfaceData.PF_BYTE_GRAY), 173 new OGLSwToTextureBlit(SurfaceType.UshortGray, 174 OGLSurfaceData.PF_USHORT_GRAY), 175 new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture, 176 CompositeType.SrcNoEa, 177 blitIntArgbPreToTexture), 178 }; 179 GraphicsPrimitiveMgr.register(primitives); 180 } 181 182 /** 183 * The following offsets are used to pack the parameters in 184 * createPackedParams(). (They are also used at the native level when 185 * unpacking the params.) 186 */ 187 private static final int OFFSET_SRCTYPE = 16; 188 private static final int OFFSET_HINT = 8; 189 private static final int OFFSET_TEXTURE = 3; 190 private static final int OFFSET_RTT = 2; 191 private static final int OFFSET_XFORM = 1; 192 private static final int OFFSET_ISOBLIT = 0; 193 194 /** 195 * Packs the given parameters into a single int value in order to save 196 * space on the rendering queue. 197 */ 198 private static int createPackedParams(boolean isoblit, boolean texture, 199 boolean rtt, boolean xform, 200 int hint, int srctype) 201 { 202 return 203 ((srctype << OFFSET_SRCTYPE) | 204 (hint << OFFSET_HINT ) | 205 ((texture ? 1 : 0) << OFFSET_TEXTURE) | 206 ((rtt ? 1 : 0) << OFFSET_RTT ) | 207 ((xform ? 1 : 0) << OFFSET_XFORM ) | 208 ((isoblit ? 1 : 0) << OFFSET_ISOBLIT)); 209 } 210 211 /** 212 * Enqueues a BLIT operation with the given parameters. Note that the 213 * RenderQueue lock must be held before calling this method. 214 */ 215 private static void enqueueBlit(RenderQueue rq, 216 SurfaceData src, SurfaceData dst, 217 int packedParams, 218 int sx1, int sy1, 219 int sx2, int sy2, 220 double dx1, double dy1, 221 double dx2, double dy2) 222 { 223 // assert rq.lock.isHeldByCurrentThread(); 224 RenderBuffer buf = rq.getBuffer(); 225 rq.ensureCapacityAndAlignment(72, 24); 226 buf.putInt(BLIT); 227 buf.putInt(packedParams); 228 buf.putInt(sx1).putInt(sy1); 229 buf.putInt(sx2).putInt(sy2); 230 buf.putDouble(dx1).putDouble(dy1); 231 buf.putDouble(dx2).putDouble(dy2); 232 buf.putLong(src.getNativeOps()); 233 buf.putLong(dst.getNativeOps()); 234 } 235 236 static void Blit(SurfaceData srcData, SurfaceData dstData, 237 Composite comp, Region clip, 238 AffineTransform xform, int hint, 239 int sx1, int sy1, 240 int sx2, int sy2, 241 double dx1, double dy1, 242 double dx2, double dy2, 243 int srctype, boolean texture) 244 { 245 int ctxflags = 0; 246 if (srcData.getTransparency() == Transparency.OPAQUE) { 247 ctxflags |= OGLContext.SRC_IS_OPAQUE; 248 } 249 250 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 251 rq.lock(); 252 try { 253 // make sure the RenderQueue keeps a hard reference to the 254 // source (sysmem) SurfaceData to prevent it from being 255 // disposed while the operation is processed on the QFT 256 rq.addReference(srcData); 257 258 OGLSurfaceData oglDst = (OGLSurfaceData)dstData; 259 if (texture) { 260 // make sure we have a current context before uploading 261 // the sysmem data to the texture object 262 OGLGraphicsConfig gc = oglDst.getOGLGraphicsConfig(); 263 OGLContext.setScratchSurface(gc); 264 } else { 265 OGLContext.validateContext(oglDst, oglDst, 266 clip, comp, xform, null, null, 267 ctxflags); 268 } 269 270 int packedParams = createPackedParams(false, texture, 271 false, xform != null, 272 hint, srctype); 273 enqueueBlit(rq, srcData, dstData, 274 packedParams, 275 sx1, sy1, sx2, sy2, 276 dx1, dy1, dx2, dy2); 277 278 // always flush immediately, since we (currently) have no means 279 // of tracking changes to the system memory surface 280 rq.flushNow(); 281 } finally { 282 rq.unlock(); 283 } 284 } 285 286 /** 287 * Note: The srcImg and biop parameters are only used when invoked 288 * from the OGLBufImgOps.renderImageWithOp() method; in all other cases, 289 * this method can be called with null values for those two parameters, 290 * and they will be effectively ignored. 291 */ 292 static void IsoBlit(SurfaceData srcData, SurfaceData dstData, 293 BufferedImage srcImg, BufferedImageOp biop, 294 Composite comp, Region clip, 295 AffineTransform xform, int hint, 296 int sx1, int sy1, 297 int sx2, int sy2, 298 double dx1, double dy1, 299 double dx2, double dy2, 300 boolean texture) 301 { 302 int ctxflags = 0; 303 if (srcData.getTransparency() == Transparency.OPAQUE) { 304 ctxflags |= OGLContext.SRC_IS_OPAQUE; 305 } 306 307 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 308 rq.lock(); 309 try { 310 OGLSurfaceData oglSrc = (OGLSurfaceData)srcData; 311 OGLSurfaceData oglDst = (OGLSurfaceData)dstData; 312 int srctype = oglSrc.getType(); 313 boolean rtt; 314 OGLSurfaceData srcCtxData; 315 if (srctype == OGLSurfaceData.TEXTURE) { 316 // the source is a regular texture object; we substitute 317 // the destination surface for the purposes of making a 318 // context current 319 rtt = false; 320 srcCtxData = oglDst; 321 } else { 322 // the source is a pbuffer, backbuffer, or render-to-texture 323 // surface; we set rtt to true to differentiate this kind 324 // of surface from a regular texture object 325 rtt = true; 326 if (srctype == OGLSurfaceData.FBOBJECT) { 327 srcCtxData = oglDst; 328 } else { 329 srcCtxData = oglSrc; 330 } 331 } 332 333 OGLContext.validateContext(srcCtxData, oglDst, 334 clip, comp, xform, null, null, 335 ctxflags); 336 337 if (biop != null) { 338 OGLBufImgOps.enableBufImgOp(rq, oglSrc, srcImg, biop); 339 } 340 341 int packedParams = createPackedParams(true, texture, 342 rtt, xform != null, 343 hint, 0 /*unused*/); 344 enqueueBlit(rq, srcData, dstData, 345 packedParams, 346 sx1, sy1, sx2, sy2, 347 dx1, dy1, dx2, dy2); 348 349 if (biop != null) { 350 OGLBufImgOps.disableBufImgOp(rq, biop); 351 } 352 353 if (rtt && oglDst.isOnScreen()) { 354 // we only have to flush immediately when copying from a 355 // (non-texture) surface to the screen; otherwise Swing apps 356 // might appear unresponsive until the auto-flush completes 357 rq.flushNow(); 358 } 359 } finally { 360 rq.unlock(); 361 } 362 } 363 } 364 365 class OGLSurfaceToSurfaceBlit extends Blit { 366 367 OGLSurfaceToSurfaceBlit() { 368 super(OGLSurfaceData.OpenGLSurface, 369 CompositeType.AnyAlpha, 370 OGLSurfaceData.OpenGLSurface); 371 } 372 373 public void Blit(SurfaceData src, SurfaceData dst, 374 Composite comp, Region clip, 375 int sx, int sy, int dx, int dy, int w, int h) 376 { 377 OGLBlitLoops.IsoBlit(src, dst, 378 null, null, 379 comp, clip, null, 380 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 381 sx, sy, sx+w, sy+h, 382 dx, dy, dx+w, dy+h, 383 false); 384 } 385 } 386 387 class OGLSurfaceToSurfaceScale extends ScaledBlit { 388 389 OGLSurfaceToSurfaceScale() { 390 super(OGLSurfaceData.OpenGLSurface, 391 CompositeType.AnyAlpha, 392 OGLSurfaceData.OpenGLSurface); 393 } 394 395 public void Scale(SurfaceData src, SurfaceData dst, 396 Composite comp, Region clip, 397 int sx1, int sy1, 398 int sx2, int sy2, 399 double dx1, double dy1, 400 double dx2, double dy2) 401 { 402 OGLBlitLoops.IsoBlit(src, dst, 403 null, null, 404 comp, clip, null, 405 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 406 sx1, sy1, sx2, sy2, 407 dx1, dy1, dx2, dy2, 408 false); 409 } 410 } 411 412 class OGLSurfaceToSurfaceTransform extends TransformBlit { 413 414 OGLSurfaceToSurfaceTransform() { 415 super(OGLSurfaceData.OpenGLSurface, 416 CompositeType.AnyAlpha, 417 OGLSurfaceData.OpenGLSurface); 418 } 419 420 public void Transform(SurfaceData src, SurfaceData dst, 421 Composite comp, Region clip, 422 AffineTransform at, int hint, 423 int sx, int sy, int dx, int dy, 424 int w, int h) 425 { 426 OGLBlitLoops.IsoBlit(src, dst, 427 null, null, 428 comp, clip, at, hint, 429 sx, sy, sx+w, sy+h, 430 dx, dy, dx+w, dy+h, 431 false); 432 } 433 } 434 435 class OGLRTTSurfaceToSurfaceBlit extends Blit { 436 437 OGLRTTSurfaceToSurfaceBlit() { 438 super(OGLSurfaceData.OpenGLSurfaceRTT, 439 CompositeType.AnyAlpha, 440 OGLSurfaceData.OpenGLSurface); 441 } 442 443 public void Blit(SurfaceData src, SurfaceData dst, 444 Composite comp, Region clip, 445 int sx, int sy, int dx, int dy, int w, int h) 446 { 447 OGLBlitLoops.IsoBlit(src, dst, 448 null, null, 449 comp, clip, null, 450 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 451 sx, sy, sx+w, sy+h, 452 dx, dy, dx+w, dy+h, 453 true); 454 } 455 } 456 457 class OGLRTTSurfaceToSurfaceScale extends ScaledBlit { 458 459 OGLRTTSurfaceToSurfaceScale() { 460 super(OGLSurfaceData.OpenGLSurfaceRTT, 461 CompositeType.AnyAlpha, 462 OGLSurfaceData.OpenGLSurface); 463 } 464 465 public void Scale(SurfaceData src, SurfaceData dst, 466 Composite comp, Region clip, 467 int sx1, int sy1, 468 int sx2, int sy2, 469 double dx1, double dy1, 470 double dx2, double dy2) 471 { 472 OGLBlitLoops.IsoBlit(src, dst, 473 null, null, 474 comp, clip, null, 475 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 476 sx1, sy1, sx2, sy2, 477 dx1, dy1, dx2, dy2, 478 true); 479 } 480 } 481 482 class OGLRTTSurfaceToSurfaceTransform extends TransformBlit { 483 484 OGLRTTSurfaceToSurfaceTransform() { 485 super(OGLSurfaceData.OpenGLSurfaceRTT, 486 CompositeType.AnyAlpha, 487 OGLSurfaceData.OpenGLSurface); 488 } 489 490 public void Transform(SurfaceData src, SurfaceData dst, 491 Composite comp, Region clip, 492 AffineTransform at, int hint, 493 int sx, int sy, int dx, int dy, int w, int h) 494 { 495 OGLBlitLoops.IsoBlit(src, dst, 496 null, null, 497 comp, clip, at, hint, 498 sx, sy, sx+w, sy+h, 499 dx, dy, dx+w, dy+h, 500 true); 501 } 502 } 503 504 class OGLSurfaceToSwBlit extends Blit { 505 506 private int typeval; 507 508 // REMIND: destination will actually be opaque/premultiplied... 509 OGLSurfaceToSwBlit(SurfaceType dstType, int typeval) { 510 super(OGLSurfaceData.OpenGLSurface, 511 CompositeType.SrcNoEa, 512 dstType); 513 this.typeval = typeval; 514 } 515 516 public void Blit(SurfaceData src, SurfaceData dst, 517 Composite comp, Region clip, 518 int sx, int sy, int dx, int dy, 519 int w, int h) 520 { 521 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 522 rq.lock(); 523 try { 524 // make sure the RenderQueue keeps a hard reference to the 525 // destination (sysmem) SurfaceData to prevent it from being 526 // disposed while the operation is processed on the QFT 527 rq.addReference(dst); 528 529 RenderBuffer buf = rq.getBuffer(); 530 OGLContext.validateContext((OGLSurfaceData)src); 531 532 rq.ensureCapacityAndAlignment(48, 32); 533 buf.putInt(SURFACE_TO_SW_BLIT); 534 buf.putInt(sx).putInt(sy); 535 buf.putInt(dx).putInt(dy); 536 buf.putInt(w).putInt(h); 537 buf.putInt(typeval); 538 buf.putLong(src.getNativeOps()); 539 buf.putLong(dst.getNativeOps()); 540 541 // always flush immediately 542 rq.flushNow(); 543 } finally { 544 rq.unlock(); 545 } 546 } 547 } 548 549 class OGLSwToSurfaceBlit extends Blit { 550 551 private int typeval; 552 553 OGLSwToSurfaceBlit(SurfaceType srcType, int typeval) { 554 super(srcType, 555 CompositeType.AnyAlpha, 556 OGLSurfaceData.OpenGLSurface); 557 this.typeval = typeval; 558 } 559 560 public void Blit(SurfaceData src, SurfaceData dst, 561 Composite comp, Region clip, 562 int sx, int sy, int dx, int dy, int w, int h) 563 { 564 OGLBlitLoops.Blit(src, dst, 565 comp, clip, null, 566 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 567 sx, sy, sx+w, sy+h, 568 dx, dy, dx+w, dy+h, 569 typeval, false); 570 } 571 } 572 573 class OGLSwToSurfaceScale extends ScaledBlit { 574 575 private int typeval; 576 577 OGLSwToSurfaceScale(SurfaceType srcType, int typeval) { 578 super(srcType, 579 CompositeType.AnyAlpha, 580 OGLSurfaceData.OpenGLSurface); 581 this.typeval = typeval; 582 } 583 584 public void Scale(SurfaceData src, SurfaceData dst, 585 Composite comp, Region clip, 586 int sx1, int sy1, 587 int sx2, int sy2, 588 double dx1, double dy1, 589 double dx2, double dy2) 590 { 591 OGLBlitLoops.Blit(src, dst, 592 comp, clip, null, 593 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 594 sx1, sy1, sx2, sy2, 595 dx1, dy1, dx2, dy2, 596 typeval, false); 597 } 598 } 599 600 class OGLSwToSurfaceTransform extends TransformBlit { 601 602 private int typeval; 603 604 OGLSwToSurfaceTransform(SurfaceType srcType, int typeval) { 605 super(srcType, 606 CompositeType.AnyAlpha, 607 OGLSurfaceData.OpenGLSurface); 608 this.typeval = typeval; 609 } 610 611 public void Transform(SurfaceData src, SurfaceData dst, 612 Composite comp, Region clip, 613 AffineTransform at, int hint, 614 int sx, int sy, int dx, int dy, int w, int h) 615 { 616 OGLBlitLoops.Blit(src, dst, 617 comp, clip, at, hint, 618 sx, sy, sx+w, sy+h, 619 dx, dy, dx+w, dy+h, 620 typeval, false); 621 } 622 } 623 624 class OGLSwToTextureBlit extends Blit { 625 626 private int typeval; 627 628 OGLSwToTextureBlit(SurfaceType srcType, int typeval) { 629 super(srcType, 630 CompositeType.SrcNoEa, 631 OGLSurfaceData.OpenGLTexture); 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, true); 645 } 646 } 647 648 class OGLTextureToSurfaceBlit extends Blit { 649 650 OGLTextureToSurfaceBlit() { 651 super(OGLSurfaceData.OpenGLTexture, 652 CompositeType.AnyAlpha, 653 OGLSurfaceData.OpenGLSurface); 654 } 655 656 public void Blit(SurfaceData src, SurfaceData dst, 657 Composite comp, Region clip, 658 int sx, int sy, int dx, int dy, int w, int h) 659 { 660 OGLBlitLoops.IsoBlit(src, dst, 661 null, null, 662 comp, clip, null, 663 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 664 sx, sy, sx+w, sy+h, 665 dx, dy, dx+w, dy+h, 666 true); 667 } 668 } 669 670 class OGLTextureToSurfaceScale extends ScaledBlit { 671 672 OGLTextureToSurfaceScale() { 673 super(OGLSurfaceData.OpenGLTexture, 674 CompositeType.AnyAlpha, 675 OGLSurfaceData.OpenGLSurface); 676 } 677 678 public void Scale(SurfaceData src, SurfaceData dst, 679 Composite comp, Region clip, 680 int sx1, int sy1, 681 int sx2, int sy2, 682 double dx1, double dy1, 683 double dx2, double dy2) 684 { 685 OGLBlitLoops.IsoBlit(src, dst, 686 null, null, 687 comp, clip, null, 688 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 689 sx1, sy1, sx2, sy2, 690 dx1, dy1, dx2, dy2, 691 true); 692 } 693 } 694 695 class OGLTextureToSurfaceTransform extends TransformBlit { 696 697 OGLTextureToSurfaceTransform() { 698 super(OGLSurfaceData.OpenGLTexture, 699 CompositeType.AnyAlpha, 700 OGLSurfaceData.OpenGLSurface); 701 } 702 703 public void Transform(SurfaceData src, SurfaceData dst, 704 Composite comp, Region clip, 705 AffineTransform at, int hint, 706 int sx, int sy, int dx, int dy, 707 int w, int h) 708 { 709 OGLBlitLoops.IsoBlit(src, dst, 710 null, null, 711 comp, clip, at, hint, 712 sx, sy, sx+w, sy+h, 713 dx, dy, dx+w, dy+h, 714 true); 715 } 716 } 717 718 /** 719 * This general Blit implemenation converts any source surface to an 720 * intermediate IntArgbPre surface, and then uses the more specific 721 * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate 722 * (premultiplied) surface down to OpenGL. 723 */ 724 class OGLGeneralBlit extends Blit { 725 726 private Blit performop; 727 private WeakReference srcTmp; 728 729 OGLGeneralBlit(SurfaceType dstType, 730 CompositeType compType, 731 Blit performop) 732 { 733 super(SurfaceType.Any, compType, dstType); 734 this.performop = performop; 735 } 736 737 public synchronized void Blit(SurfaceData src, SurfaceData dst, 738 Composite comp, Region clip, 739 int sx, int sy, int dx, int dy, 740 int w, int h) 741 { 742 Blit convertsrc = Blit.getFromCache(src.getSurfaceType(), 743 CompositeType.SrcNoEa, 744 SurfaceType.IntArgbPre); 745 746 SurfaceData cachedSrc = null; 747 if (srcTmp != null) { 748 // use cached intermediate surface, if available 749 cachedSrc = (SurfaceData)srcTmp.get(); 750 } 751 752 // convert source to IntArgbPre 753 src = convertFrom(convertsrc, src, sx, sy, w, h, 754 cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE); 755 756 // copy IntArgbPre intermediate surface to OpenGL surface 757 performop.Blit(src, dst, comp, clip, 758 0, 0, dx, dy, w, h); 759 760 if (src != cachedSrc) { 761 // cache the intermediate surface 762 srcTmp = new WeakReference(src); 763 } 764 } 765 }