src/java.desktop/macosx/classes/sun/java2d/metal/MetalBlitLoops.java
branchmetal-prototype-branch
changeset 57243 8c3a74033daf
equal deleted inserted replaced
57234:e1e5386479c4 57243:8c3a74033daf
       
     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 }*/