Path: blob/master/src/java.desktop/share/classes/sun/java2d/opengl/OGLBlitLoops.java
41159 views
/*1* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.java2d.opengl;2627import java.awt.AlphaComposite;28import java.awt.Composite;29import java.awt.Transparency;30import java.awt.geom.AffineTransform;31import java.awt.image.AffineTransformOp;32import java.awt.image.BufferedImage;33import java.awt.image.BufferedImageOp;34import java.lang.ref.WeakReference;35import sun.java2d.SurfaceData;36import sun.java2d.loops.Blit;37import sun.java2d.loops.CompositeType;38import sun.java2d.loops.GraphicsPrimitive;39import sun.java2d.loops.GraphicsPrimitiveMgr;40import sun.java2d.loops.ScaledBlit;41import sun.java2d.loops.SurfaceType;42import sun.java2d.loops.TransformBlit;43import sun.java2d.pipe.Region;44import sun.java2d.pipe.RenderBuffer;45import sun.java2d.pipe.RenderQueue;46import static sun.java2d.pipe.BufferedOpCodes.*;47import java.lang.annotation.Native;4849final class OGLBlitLoops {5051static void register() {52Blit blitIntArgbPreToSurface =53new OGLSwToSurfaceBlit(SurfaceType.IntArgbPre,54OGLSurfaceData.PF_INT_ARGB_PRE);55Blit blitIntArgbPreToTexture =56new OGLSwToTextureBlit(SurfaceType.IntArgbPre,57OGLSurfaceData.PF_INT_ARGB_PRE);58TransformBlit transformBlitIntArgbPreToSurface =59new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre,60OGLSurfaceData.PF_INT_ARGB_PRE);61OGLSurfaceToSwBlit blitSurfaceToIntArgbPre =62new OGLSurfaceToSwBlit(SurfaceType.IntArgbPre,63OGLSurfaceData.PF_INT_ARGB_PRE);6465GraphicsPrimitive[] primitives = {66// surface->surface ops67new OGLSurfaceToSurfaceBlit(),68new OGLSurfaceToSurfaceScale(),69new OGLSurfaceToSurfaceTransform(),7071// render-to-texture surface->surface ops72new OGLRTTSurfaceToSurfaceBlit(),73new OGLRTTSurfaceToSurfaceScale(),74new OGLRTTSurfaceToSurfaceTransform(),7576// surface->sw ops77new OGLSurfaceToSwBlit(SurfaceType.IntArgb,78OGLSurfaceData.PF_INT_ARGB),79blitSurfaceToIntArgbPre,8081// sw->surface ops82blitIntArgbPreToSurface,83new OGLSwToSurfaceBlit(SurfaceType.IntRgb,84OGLSurfaceData.PF_INT_RGB),85new OGLSwToSurfaceBlit(SurfaceType.IntRgbx,86OGLSurfaceData.PF_INT_RGBX),87new OGLSwToSurfaceBlit(SurfaceType.IntBgr,88OGLSurfaceData.PF_INT_BGR),89new OGLSwToSurfaceBlit(SurfaceType.IntBgrx,90OGLSurfaceData.PF_INT_BGRX),91new OGLSwToSurfaceBlit(SurfaceType.ThreeByteBgr,92OGLSurfaceData.PF_3BYTE_BGR),93new OGLSwToSurfaceBlit(SurfaceType.Ushort565Rgb,94OGLSurfaceData.PF_USHORT_565_RGB),95new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgb,96OGLSurfaceData.PF_USHORT_555_RGB),97new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgbx,98OGLSurfaceData.PF_USHORT_555_RGBX),99new OGLSwToSurfaceBlit(SurfaceType.ByteGray,100OGLSurfaceData.PF_BYTE_GRAY),101new OGLSwToSurfaceBlit(SurfaceType.UshortGray,102OGLSurfaceData.PF_USHORT_GRAY),103new OGLGeneralBlit(OGLSurfaceData.OpenGLSurface,104CompositeType.AnyAlpha,105blitIntArgbPreToSurface),106107new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLSurface,108blitSurfaceToIntArgbPre,109blitSurfaceToIntArgbPre,110blitIntArgbPreToSurface),111new OGLAnyCompositeBlit(SurfaceType.Any,112null,113blitSurfaceToIntArgbPre,114blitIntArgbPreToSurface),115116new OGLSwToSurfaceScale(SurfaceType.IntRgb,117OGLSurfaceData.PF_INT_RGB),118new OGLSwToSurfaceScale(SurfaceType.IntRgbx,119OGLSurfaceData.PF_INT_RGBX),120new OGLSwToSurfaceScale(SurfaceType.IntBgr,121OGLSurfaceData.PF_INT_BGR),122new OGLSwToSurfaceScale(SurfaceType.IntBgrx,123OGLSurfaceData.PF_INT_BGRX),124new OGLSwToSurfaceScale(SurfaceType.ThreeByteBgr,125OGLSurfaceData.PF_3BYTE_BGR),126new OGLSwToSurfaceScale(SurfaceType.Ushort565Rgb,127OGLSurfaceData.PF_USHORT_565_RGB),128new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgb,129OGLSurfaceData.PF_USHORT_555_RGB),130new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgbx,131OGLSurfaceData.PF_USHORT_555_RGBX),132new OGLSwToSurfaceScale(SurfaceType.ByteGray,133OGLSurfaceData.PF_BYTE_GRAY),134new OGLSwToSurfaceScale(SurfaceType.UshortGray,135OGLSurfaceData.PF_USHORT_GRAY),136new OGLSwToSurfaceScale(SurfaceType.IntArgbPre,137OGLSurfaceData.PF_INT_ARGB_PRE),138139new OGLSwToSurfaceTransform(SurfaceType.IntRgb,140OGLSurfaceData.PF_INT_RGB),141new OGLSwToSurfaceTransform(SurfaceType.IntRgbx,142OGLSurfaceData.PF_INT_RGBX),143new OGLSwToSurfaceTransform(SurfaceType.IntBgr,144OGLSurfaceData.PF_INT_BGR),145new OGLSwToSurfaceTransform(SurfaceType.IntBgrx,146OGLSurfaceData.PF_INT_BGRX),147new OGLSwToSurfaceTransform(SurfaceType.ThreeByteBgr,148OGLSurfaceData.PF_3BYTE_BGR),149new OGLSwToSurfaceTransform(SurfaceType.Ushort565Rgb,150OGLSurfaceData.PF_USHORT_565_RGB),151new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgb,152OGLSurfaceData.PF_USHORT_555_RGB),153new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgbx,154OGLSurfaceData.PF_USHORT_555_RGBX),155new OGLSwToSurfaceTransform(SurfaceType.ByteGray,156OGLSurfaceData.PF_BYTE_GRAY),157new OGLSwToSurfaceTransform(SurfaceType.UshortGray,158OGLSurfaceData.PF_USHORT_GRAY),159transformBlitIntArgbPreToSurface,160161new OGLGeneralTransformedBlit(transformBlitIntArgbPreToSurface),162163// texture->surface ops164new OGLTextureToSurfaceBlit(),165new OGLTextureToSurfaceScale(),166new OGLTextureToSurfaceTransform(),167168// sw->texture ops169blitIntArgbPreToTexture,170new OGLSwToTextureBlit(SurfaceType.IntRgb,171OGLSurfaceData.PF_INT_RGB),172new OGLSwToTextureBlit(SurfaceType.IntRgbx,173OGLSurfaceData.PF_INT_RGBX),174new OGLSwToTextureBlit(SurfaceType.IntBgr,175OGLSurfaceData.PF_INT_BGR),176new OGLSwToTextureBlit(SurfaceType.IntBgrx,177OGLSurfaceData.PF_INT_BGRX),178new OGLSwToTextureBlit(SurfaceType.ThreeByteBgr,179OGLSurfaceData.PF_3BYTE_BGR),180new OGLSwToTextureBlit(SurfaceType.Ushort565Rgb,181OGLSurfaceData.PF_USHORT_565_RGB),182new OGLSwToTextureBlit(SurfaceType.Ushort555Rgb,183OGLSurfaceData.PF_USHORT_555_RGB),184new OGLSwToTextureBlit(SurfaceType.Ushort555Rgbx,185OGLSurfaceData.PF_USHORT_555_RGBX),186new OGLSwToTextureBlit(SurfaceType.ByteGray,187OGLSurfaceData.PF_BYTE_GRAY),188new OGLSwToTextureBlit(SurfaceType.UshortGray,189OGLSurfaceData.PF_USHORT_GRAY),190new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture,191CompositeType.SrcNoEa,192blitIntArgbPreToTexture),193};194GraphicsPrimitiveMgr.register(primitives);195}196197/**198* The following offsets are used to pack the parameters in199* createPackedParams(). (They are also used at the native level when200* unpacking the params.)201*/202@Native private static final int OFFSET_SRCTYPE = 16;203@Native private static final int OFFSET_HINT = 8;204@Native private static final int OFFSET_TEXTURE = 3;205@Native private static final int OFFSET_RTT = 2;206@Native private static final int OFFSET_XFORM = 1;207@Native private static final int OFFSET_ISOBLIT = 0;208209/**210* Packs the given parameters into a single int value in order to save211* space on the rendering queue.212*/213private static int createPackedParams(boolean isoblit, boolean texture,214boolean rtt, boolean xform,215int hint, int srctype)216{217return218((srctype << OFFSET_SRCTYPE) |219(hint << OFFSET_HINT ) |220((texture ? 1 : 0) << OFFSET_TEXTURE) |221((rtt ? 1 : 0) << OFFSET_RTT ) |222((xform ? 1 : 0) << OFFSET_XFORM ) |223((isoblit ? 1 : 0) << OFFSET_ISOBLIT));224}225226/**227* Enqueues a BLIT operation with the given parameters. Note that the228* RenderQueue lock must be held before calling this method.229*/230private static void enqueueBlit(RenderQueue rq,231SurfaceData src, SurfaceData dst,232int packedParams,233int sx1, int sy1,234int sx2, int sy2,235double dx1, double dy1,236double dx2, double dy2)237{238// assert rq.lock.isHeldByCurrentThread();239RenderBuffer buf = rq.getBuffer();240rq.ensureCapacityAndAlignment(72, 24);241buf.putInt(BLIT);242buf.putInt(packedParams);243buf.putInt(sx1).putInt(sy1);244buf.putInt(sx2).putInt(sy2);245buf.putDouble(dx1).putDouble(dy1);246buf.putDouble(dx2).putDouble(dy2);247buf.putLong(src.getNativeOps());248buf.putLong(dst.getNativeOps());249}250251static void Blit(SurfaceData srcData, SurfaceData dstData,252Composite comp, Region clip,253AffineTransform xform, int hint,254int sx1, int sy1,255int sx2, int sy2,256double dx1, double dy1,257double dx2, double dy2,258int srctype, boolean texture)259{260int ctxflags = 0;261if (srcData.getTransparency() == Transparency.OPAQUE) {262ctxflags |= OGLContext.SRC_IS_OPAQUE;263}264265OGLRenderQueue rq = OGLRenderQueue.getInstance();266rq.lock();267try {268// make sure the RenderQueue keeps a hard reference to the269// source (sysmem) SurfaceData to prevent it from being270// disposed while the operation is processed on the QFT271rq.addReference(srcData);272273OGLSurfaceData oglDst = (OGLSurfaceData)dstData;274if (texture) {275// make sure we have a current context before uploading276// the sysmem data to the texture object277OGLGraphicsConfig gc = oglDst.getOGLGraphicsConfig();278OGLContext.setScratchSurface(gc);279} else {280OGLContext.validateContext(oglDst, oglDst,281clip, comp, xform, null, null,282ctxflags);283}284285int packedParams = createPackedParams(false, texture,286false, xform != null,287hint, srctype);288enqueueBlit(rq, srcData, dstData,289packedParams,290sx1, sy1, sx2, sy2,291dx1, dy1, dx2, dy2);292293// always flush immediately, since we (currently) have no means294// of tracking changes to the system memory surface295rq.flushNow();296} finally {297rq.unlock();298}299}300301/**302* Note: The srcImg and biop parameters are only used when invoked303* from the OGLBufImgOps.renderImageWithOp() method; in all other cases,304* this method can be called with null values for those two parameters,305* and they will be effectively ignored.306*/307static void IsoBlit(SurfaceData srcData, SurfaceData dstData,308BufferedImage srcImg, BufferedImageOp biop,309Composite comp, Region clip,310AffineTransform xform, int hint,311int sx1, int sy1,312int sx2, int sy2,313double dx1, double dy1,314double dx2, double dy2,315boolean texture)316{317int ctxflags = 0;318if (srcData.getTransparency() == Transparency.OPAQUE) {319ctxflags |= OGLContext.SRC_IS_OPAQUE;320}321322OGLRenderQueue rq = OGLRenderQueue.getInstance();323rq.lock();324try {325OGLSurfaceData oglSrc = (OGLSurfaceData)srcData;326OGLSurfaceData oglDst = (OGLSurfaceData)dstData;327int srctype = oglSrc.getType();328boolean rtt;329OGLSurfaceData srcCtxData;330if (srctype == OGLSurfaceData.TEXTURE) {331// the source is a regular texture object; we substitute332// the destination surface for the purposes of making a333// context current334rtt = false;335srcCtxData = oglDst;336} else {337// the source is a pbuffer, backbuffer, or render-to-texture338// surface; we set rtt to true to differentiate this kind339// of surface from a regular texture object340rtt = true;341if (srctype == OGLSurfaceData.FBOBJECT) {342srcCtxData = oglDst;343} else {344srcCtxData = oglSrc;345}346}347348OGLContext.validateContext(srcCtxData, oglDst,349clip, comp, xform, null, null,350ctxflags);351352if (biop != null) {353OGLBufImgOps.enableBufImgOp(rq, oglSrc, srcImg, biop);354}355356int packedParams = createPackedParams(true, texture,357rtt, xform != null,358hint, 0 /*unused*/);359enqueueBlit(rq, srcData, dstData,360packedParams,361sx1, sy1, sx2, sy2,362dx1, dy1, dx2, dy2);363364if (biop != null) {365OGLBufImgOps.disableBufImgOp(rq, biop);366}367368if (rtt && oglDst.isOnScreen()) {369// we only have to flush immediately when copying from a370// (non-texture) surface to the screen; otherwise Swing apps371// might appear unresponsive until the auto-flush completes372rq.flushNow();373}374} finally {375rq.unlock();376}377}378}379380class OGLSurfaceToSurfaceBlit extends Blit {381382OGLSurfaceToSurfaceBlit() {383super(OGLSurfaceData.OpenGLSurface,384CompositeType.AnyAlpha,385OGLSurfaceData.OpenGLSurface);386}387388public void Blit(SurfaceData src, SurfaceData dst,389Composite comp, Region clip,390int sx, int sy, int dx, int dy, int w, int h)391{392OGLBlitLoops.IsoBlit(src, dst,393null, null,394comp, clip, null,395AffineTransformOp.TYPE_NEAREST_NEIGHBOR,396sx, sy, sx+w, sy+h,397dx, dy, dx+w, dy+h,398false);399}400}401402class OGLSurfaceToSurfaceScale extends ScaledBlit {403404OGLSurfaceToSurfaceScale() {405super(OGLSurfaceData.OpenGLSurface,406CompositeType.AnyAlpha,407OGLSurfaceData.OpenGLSurface);408}409410public void Scale(SurfaceData src, SurfaceData dst,411Composite comp, Region clip,412int sx1, int sy1,413int sx2, int sy2,414double dx1, double dy1,415double dx2, double dy2)416{417OGLBlitLoops.IsoBlit(src, dst,418null, null,419comp, clip, null,420AffineTransformOp.TYPE_NEAREST_NEIGHBOR,421sx1, sy1, sx2, sy2,422dx1, dy1, dx2, dy2,423false);424}425}426427class OGLSurfaceToSurfaceTransform extends TransformBlit {428429OGLSurfaceToSurfaceTransform() {430super(OGLSurfaceData.OpenGLSurface,431CompositeType.AnyAlpha,432OGLSurfaceData.OpenGLSurface);433}434435public void Transform(SurfaceData src, SurfaceData dst,436Composite comp, Region clip,437AffineTransform at, int hint,438int sx, int sy, int dx, int dy,439int w, int h)440{441OGLBlitLoops.IsoBlit(src, dst,442null, null,443comp, clip, at, hint,444sx, sy, sx+w, sy+h,445dx, dy, dx+w, dy+h,446false);447}448}449450class OGLRTTSurfaceToSurfaceBlit extends Blit {451452OGLRTTSurfaceToSurfaceBlit() {453super(OGLSurfaceData.OpenGLSurfaceRTT,454CompositeType.AnyAlpha,455OGLSurfaceData.OpenGLSurface);456}457458public void Blit(SurfaceData src, SurfaceData dst,459Composite comp, Region clip,460int sx, int sy, int dx, int dy, int w, int h)461{462OGLBlitLoops.IsoBlit(src, dst,463null, null,464comp, clip, null,465AffineTransformOp.TYPE_NEAREST_NEIGHBOR,466sx, sy, sx+w, sy+h,467dx, dy, dx+w, dy+h,468true);469}470}471472class OGLRTTSurfaceToSurfaceScale extends ScaledBlit {473474OGLRTTSurfaceToSurfaceScale() {475super(OGLSurfaceData.OpenGLSurfaceRTT,476CompositeType.AnyAlpha,477OGLSurfaceData.OpenGLSurface);478}479480public void Scale(SurfaceData src, SurfaceData dst,481Composite comp, Region clip,482int sx1, int sy1,483int sx2, int sy2,484double dx1, double dy1,485double dx2, double dy2)486{487OGLBlitLoops.IsoBlit(src, dst,488null, null,489comp, clip, null,490AffineTransformOp.TYPE_NEAREST_NEIGHBOR,491sx1, sy1, sx2, sy2,492dx1, dy1, dx2, dy2,493true);494}495}496497class OGLRTTSurfaceToSurfaceTransform extends TransformBlit {498499OGLRTTSurfaceToSurfaceTransform() {500super(OGLSurfaceData.OpenGLSurfaceRTT,501CompositeType.AnyAlpha,502OGLSurfaceData.OpenGLSurface);503}504505public void Transform(SurfaceData src, SurfaceData dst,506Composite comp, Region clip,507AffineTransform at, int hint,508int sx, int sy, int dx, int dy, int w, int h)509{510OGLBlitLoops.IsoBlit(src, dst,511null, null,512comp, clip, at, hint,513sx, sy, sx+w, sy+h,514dx, dy, dx+w, dy+h,515true);516}517}518519final class OGLSurfaceToSwBlit extends Blit {520521private final int typeval;522private WeakReference<SurfaceData> srcTmp;523524// destination will actually be ArgbPre or Argb525OGLSurfaceToSwBlit(final SurfaceType dstType,final int typeval) {526super(OGLSurfaceData.OpenGLSurface,527CompositeType.SrcNoEa,528dstType);529this.typeval = typeval;530}531532private synchronized void complexClipBlit(SurfaceData src, SurfaceData dst,533Composite comp, Region clip,534int sx, int sy, int dx, int dy,535int w, int h) {536SurfaceData cachedSrc = null;537if (srcTmp != null) {538// use cached intermediate surface, if available539cachedSrc = srcTmp.get();540}541542// We can convert argb_pre data from OpenGL surface in two places:543// - During OpenGL surface -> SW blit544// - During SW -> SW blit545// The first one is faster when we use opaque OGL surface, because in546// this case we simply skip conversion and use color components as is.547// Because of this we align intermediate buffer type with type of548// destination not source.549final int type = typeval == OGLSurfaceData.PF_INT_ARGB_PRE ?550BufferedImage.TYPE_INT_ARGB_PRE :551BufferedImage.TYPE_INT_ARGB;552553src = convertFrom(this, src, sx, sy, w, h, cachedSrc, type);554555// copy intermediate SW to destination SW using complex clip556final Blit performop = Blit.getFromCache(src.getSurfaceType(),557CompositeType.SrcNoEa,558dst.getSurfaceType());559performop.Blit(src, dst, comp, clip, 0, 0, dx, dy, w, h);560561if (src != cachedSrc) {562// cache the intermediate surface563srcTmp = new WeakReference<>(src);564}565}566567public void Blit(SurfaceData src, SurfaceData dst,568Composite comp, Region clip,569int sx, int sy, int dx, int dy,570int w, int h)571{572if (clip != null) {573clip = clip.getIntersectionXYWH(dx, dy, w, h);574// At the end this method will flush the RenderQueue, we should exit575// from it as soon as possible.576if (clip.isEmpty()) {577return;578}579sx += clip.getLoX() - dx;580sy += clip.getLoY() - dy;581dx = clip.getLoX();582dy = clip.getLoY();583w = clip.getWidth();584h = clip.getHeight();585586if (!clip.isRectangular()) {587complexClipBlit(src, dst, comp, clip, sx, sy, dx, dy, w, h);588return;589}590}591592OGLRenderQueue rq = OGLRenderQueue.getInstance();593rq.lock();594try {595// make sure the RenderQueue keeps a hard reference to the596// destination (sysmem) SurfaceData to prevent it from being597// disposed while the operation is processed on the QFT598rq.addReference(dst);599600RenderBuffer buf = rq.getBuffer();601OGLContext.validateContext((OGLSurfaceData)src);602603rq.ensureCapacityAndAlignment(48, 32);604buf.putInt(SURFACE_TO_SW_BLIT);605buf.putInt(sx).putInt(sy);606buf.putInt(dx).putInt(dy);607buf.putInt(w).putInt(h);608buf.putInt(typeval);609buf.putLong(src.getNativeOps());610buf.putLong(dst.getNativeOps());611612// always flush immediately613rq.flushNow();614} finally {615rq.unlock();616}617}618}619620class OGLSwToSurfaceBlit extends Blit {621622private int typeval;623624OGLSwToSurfaceBlit(SurfaceType srcType, int typeval) {625super(srcType,626CompositeType.AnyAlpha,627OGLSurfaceData.OpenGLSurface);628this.typeval = typeval;629}630631public void Blit(SurfaceData src, SurfaceData dst,632Composite comp, Region clip,633int sx, int sy, int dx, int dy, int w, int h)634{635OGLBlitLoops.Blit(src, dst,636comp, clip, null,637AffineTransformOp.TYPE_NEAREST_NEIGHBOR,638sx, sy, sx+w, sy+h,639dx, dy, dx+w, dy+h,640typeval, false);641}642}643644class OGLSwToSurfaceScale extends ScaledBlit {645646private int typeval;647648OGLSwToSurfaceScale(SurfaceType srcType, int typeval) {649super(srcType,650CompositeType.AnyAlpha,651OGLSurfaceData.OpenGLSurface);652this.typeval = typeval;653}654655public void Scale(SurfaceData src, SurfaceData dst,656Composite comp, Region clip,657int sx1, int sy1,658int sx2, int sy2,659double dx1, double dy1,660double dx2, double dy2)661{662OGLBlitLoops.Blit(src, dst,663comp, clip, null,664AffineTransformOp.TYPE_NEAREST_NEIGHBOR,665sx1, sy1, sx2, sy2,666dx1, dy1, dx2, dy2,667typeval, false);668}669}670671class OGLSwToSurfaceTransform extends TransformBlit {672673private int typeval;674675OGLSwToSurfaceTransform(SurfaceType srcType, int typeval) {676super(srcType,677CompositeType.AnyAlpha,678OGLSurfaceData.OpenGLSurface);679this.typeval = typeval;680}681682public void Transform(SurfaceData src, SurfaceData dst,683Composite comp, Region clip,684AffineTransform at, int hint,685int sx, int sy, int dx, int dy, int w, int h)686{687OGLBlitLoops.Blit(src, dst,688comp, clip, at, hint,689sx, sy, sx+w, sy+h,690dx, dy, dx+w, dy+h,691typeval, false);692}693}694695class OGLSwToTextureBlit extends Blit {696697private int typeval;698699OGLSwToTextureBlit(SurfaceType srcType, int typeval) {700super(srcType,701CompositeType.SrcNoEa,702OGLSurfaceData.OpenGLTexture);703this.typeval = typeval;704}705706public void Blit(SurfaceData src, SurfaceData dst,707Composite comp, Region clip,708int sx, int sy, int dx, int dy, int w, int h)709{710OGLBlitLoops.Blit(src, dst,711comp, clip, null,712AffineTransformOp.TYPE_NEAREST_NEIGHBOR,713sx, sy, sx+w, sy+h,714dx, dy, dx+w, dy+h,715typeval, true);716}717}718719class OGLTextureToSurfaceBlit extends Blit {720721OGLTextureToSurfaceBlit() {722super(OGLSurfaceData.OpenGLTexture,723CompositeType.AnyAlpha,724OGLSurfaceData.OpenGLSurface);725}726727public void Blit(SurfaceData src, SurfaceData dst,728Composite comp, Region clip,729int sx, int sy, int dx, int dy, int w, int h)730{731OGLBlitLoops.IsoBlit(src, dst,732null, null,733comp, clip, null,734AffineTransformOp.TYPE_NEAREST_NEIGHBOR,735sx, sy, sx+w, sy+h,736dx, dy, dx+w, dy+h,737true);738}739}740741class OGLTextureToSurfaceScale extends ScaledBlit {742743OGLTextureToSurfaceScale() {744super(OGLSurfaceData.OpenGLTexture,745CompositeType.AnyAlpha,746OGLSurfaceData.OpenGLSurface);747}748749public void Scale(SurfaceData src, SurfaceData dst,750Composite comp, Region clip,751int sx1, int sy1,752int sx2, int sy2,753double dx1, double dy1,754double dx2, double dy2)755{756OGLBlitLoops.IsoBlit(src, dst,757null, null,758comp, clip, null,759AffineTransformOp.TYPE_NEAREST_NEIGHBOR,760sx1, sy1, sx2, sy2,761dx1, dy1, dx2, dy2,762true);763}764}765766class OGLTextureToSurfaceTransform extends TransformBlit {767768OGLTextureToSurfaceTransform() {769super(OGLSurfaceData.OpenGLTexture,770CompositeType.AnyAlpha,771OGLSurfaceData.OpenGLSurface);772}773774public void Transform(SurfaceData src, SurfaceData dst,775Composite comp, Region clip,776AffineTransform at, int hint,777int sx, int sy, int dx, int dy,778int w, int h)779{780OGLBlitLoops.IsoBlit(src, dst,781null, null,782comp, clip, at, hint,783sx, sy, sx+w, sy+h,784dx, dy, dx+w, dy+h,785true);786}787}788789/**790* This general Blit implementation converts any source surface to an791* intermediate IntArgbPre surface, and then uses the more specific792* IntArgbPre->OpenGLSurface/Texture loop to get the intermediate793* (premultiplied) surface down to OpenGL using simple blit.794*/795class OGLGeneralBlit extends Blit {796797private final Blit performop;798private WeakReference<SurfaceData> srcTmp;799800OGLGeneralBlit(SurfaceType dstType,801CompositeType compType,802Blit performop)803{804super(SurfaceType.Any, compType, dstType);805this.performop = performop;806}807808public synchronized void Blit(SurfaceData src, SurfaceData dst,809Composite comp, Region clip,810int sx, int sy, int dx, int dy,811int w, int h)812{813Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),814CompositeType.SrcNoEa,815SurfaceType.IntArgbPre);816817SurfaceData cachedSrc = null;818if (srcTmp != null) {819// use cached intermediate surface, if available820cachedSrc = srcTmp.get();821}822823// convert source to IntArgbPre824src = convertFrom(convertsrc, src, sx, sy, w, h,825cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE);826827// copy IntArgbPre intermediate surface to OpenGL surface828performop.Blit(src, dst, comp, clip,8290, 0, dx, dy, w, h);830831if (src != cachedSrc) {832// cache the intermediate surface833srcTmp = new WeakReference<>(src);834}835}836}837838/**839* This general TransformedBlit implementation converts any source surface to an840* intermediate IntArgbPre surface, and then uses the more specific841* IntArgbPre->OpenGLSurface/Texture loop to get the intermediate842* (premultiplied) surface down to OpenGL using simple transformBlit.843*/844final class OGLGeneralTransformedBlit extends TransformBlit {845846private final TransformBlit performop;847private WeakReference<SurfaceData> srcTmp;848849OGLGeneralTransformedBlit(final TransformBlit performop) {850super(SurfaceType.Any, CompositeType.AnyAlpha,851OGLSurfaceData.OpenGLSurface);852this.performop = performop;853}854855@Override856public synchronized void Transform(SurfaceData src, SurfaceData dst,857Composite comp, Region clip,858AffineTransform at, int hint, int srcx,859int srcy, int dstx, int dsty, int width,860int height){861Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),862CompositeType.SrcNoEa,863SurfaceType.IntArgbPre);864// use cached intermediate surface, if available865final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null;866// convert source to IntArgbPre867src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc,868BufferedImage.TYPE_INT_ARGB_PRE);869870// transform IntArgbPre intermediate surface to OpenGL surface871performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty,872width, height);873874if (src != cachedSrc) {875// cache the intermediate surface876srcTmp = new WeakReference<>(src);877}878}879}880881/**882* This general OGLAnyCompositeBlit implementation can convert any source/target883* surface to an intermediate surface using convertsrc/convertdst loops, applies884* necessary composite operation, and then uses convertresult loop to get the885* intermediate surface down to OpenGL.886*/887final class OGLAnyCompositeBlit extends Blit {888889private WeakReference<SurfaceData> dstTmp;890private WeakReference<SurfaceData> srcTmp;891private final Blit convertsrc;892private final Blit convertdst;893private final Blit convertresult;894895OGLAnyCompositeBlit(SurfaceType srctype, Blit convertsrc, Blit convertdst,896Blit convertresult) {897super(srctype, CompositeType.Any, OGLSurfaceData.OpenGLSurface);898this.convertsrc = convertsrc;899this.convertdst = convertdst;900this.convertresult = convertresult;901}902903public synchronized void Blit(SurfaceData src, SurfaceData dst,904Composite comp, Region clip,905int sx, int sy, int dx, int dy,906int w, int h)907{908if (convertsrc != null) {909SurfaceData cachedSrc = null;910if (srcTmp != null) {911// use cached intermediate surface, if available912cachedSrc = srcTmp.get();913}914// convert source to IntArgbPre915src = convertFrom(convertsrc, src, sx, sy, w, h, cachedSrc,916BufferedImage.TYPE_INT_ARGB_PRE);917if (src != cachedSrc) {918// cache the intermediate surface919srcTmp = new WeakReference<>(src);920}921}922923SurfaceData cachedDst = null;924925if (dstTmp != null) {926// use cached intermediate surface, if available927cachedDst = dstTmp.get();928}929930// convert destination to IntArgbPre931SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h,932cachedDst, BufferedImage.TYPE_INT_ARGB_PRE);933Region bufferClip =934clip == null ? null : clip.getTranslatedRegion(-dx, -dy);935936Blit performop = Blit.getFromCache(src.getSurfaceType(),937CompositeType.Any, dstBuffer.getSurfaceType());938performop.Blit(src, dstBuffer, comp, bufferClip, sx, sy, 0, 0, w, h);939940if (dstBuffer != cachedDst) {941// cache the intermediate surface942dstTmp = new WeakReference<>(dstBuffer);943}944// now blit the buffer back to the destination945convertresult.Blit(dstBuffer, dst, AlphaComposite.Src, clip, 0, 0, dx,946dy, w, h);947}948}949950951