001: /*
002: * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.java2d.opengl;
027:
028: import java.awt.AlphaComposite;
029: import java.awt.Color;
030: import java.awt.Composite;
031: import java.awt.Transparency;
032: import java.awt.geom.AffineTransform;
033: import java.awt.image.AffineTransformOp;
034: import java.awt.image.BufferedImage;
035: import java.awt.image.BufferedImageOp;
036: import java.awt.image.ColorModel;
037: import java.lang.ref.WeakReference;
038: import sun.awt.image.BufImgSurfaceData;
039: import sun.java2d.SurfaceData;
040: import sun.java2d.loops.Blit;
041: import sun.java2d.loops.CompositeType;
042: import sun.java2d.loops.GraphicsPrimitive;
043: import sun.java2d.loops.GraphicsPrimitiveMgr;
044: import sun.java2d.loops.ScaledBlit;
045: import sun.java2d.loops.SurfaceType;
046: import sun.java2d.loops.TransformBlit;
047: import sun.java2d.pipe.Region;
048: import sun.java2d.pipe.RenderBuffer;
049: import sun.java2d.pipe.RenderQueue;
050: import static sun.java2d.pipe.BufferedOpCodes.*;
051:
052: class OGLBlitLoops {
053:
054: static void register() {
055: Blit blitIntArgbPreToSurface = new OGLSwToSurfaceBlit(
056: SurfaceType.IntArgbPre, OGLSurfaceData.PF_INT_ARGB_PRE);
057: Blit blitIntArgbPreToTexture = new OGLSwToTextureBlit(
058: SurfaceType.IntArgbPre, OGLSurfaceData.PF_INT_ARGB_PRE);
059:
060: GraphicsPrimitive[] primitives = {
061: // surface->surface ops
062: new OGLSurfaceToSurfaceBlit(),
063: new OGLSurfaceToSurfaceScale(),
064: new OGLSurfaceToSurfaceTransform(),
065:
066: // render-to-texture surface->surface ops
067: new OGLRTTSurfaceToSurfaceBlit(),
068: new OGLRTTSurfaceToSurfaceScale(),
069: new OGLRTTSurfaceToSurfaceTransform(),
070:
071: // surface->sw ops
072: new OGLSurfaceToSwBlit(SurfaceType.IntArgb,
073: OGLSurfaceData.PF_INT_ARGB),
074:
075: // sw->surface ops
076: blitIntArgbPreToSurface,
077: new OGLSwToSurfaceBlit(SurfaceType.IntRgb,
078: OGLSurfaceData.PF_INT_RGB),
079: new OGLSwToSurfaceBlit(SurfaceType.IntRgbx,
080: OGLSurfaceData.PF_INT_RGBX),
081: new OGLSwToSurfaceBlit(SurfaceType.IntBgr,
082: OGLSurfaceData.PF_INT_BGR),
083: new OGLSwToSurfaceBlit(SurfaceType.IntBgrx,
084: OGLSurfaceData.PF_INT_BGRX),
085: new OGLSwToSurfaceBlit(SurfaceType.Ushort565Rgb,
086: OGLSurfaceData.PF_USHORT_565_RGB),
087: new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgb,
088: OGLSurfaceData.PF_USHORT_555_RGB),
089: new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgbx,
090: OGLSurfaceData.PF_USHORT_555_RGBX),
091: new OGLSwToSurfaceBlit(SurfaceType.ByteGray,
092: OGLSurfaceData.PF_BYTE_GRAY),
093: new OGLSwToSurfaceBlit(SurfaceType.UshortGray,
094: OGLSurfaceData.PF_USHORT_GRAY),
095: new OGLGeneralBlit(OGLSurfaceData.OpenGLSurface,
096: CompositeType.AnyAlpha, blitIntArgbPreToSurface),
097:
098: new OGLSwToSurfaceScale(SurfaceType.IntRgb,
099: OGLSurfaceData.PF_INT_RGB),
100: new OGLSwToSurfaceScale(SurfaceType.IntRgbx,
101: OGLSurfaceData.PF_INT_RGBX),
102: new OGLSwToSurfaceScale(SurfaceType.IntBgr,
103: OGLSurfaceData.PF_INT_BGR),
104: new OGLSwToSurfaceScale(SurfaceType.IntBgrx,
105: OGLSurfaceData.PF_INT_BGRX),
106: new OGLSwToSurfaceScale(SurfaceType.Ushort565Rgb,
107: OGLSurfaceData.PF_USHORT_565_RGB),
108: new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgb,
109: OGLSurfaceData.PF_USHORT_555_RGB),
110: new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgbx,
111: OGLSurfaceData.PF_USHORT_555_RGBX),
112: new OGLSwToSurfaceScale(SurfaceType.ByteGray,
113: OGLSurfaceData.PF_BYTE_GRAY),
114: new OGLSwToSurfaceScale(SurfaceType.UshortGray,
115: OGLSurfaceData.PF_USHORT_GRAY),
116: new OGLSwToSurfaceScale(SurfaceType.IntArgbPre,
117: OGLSurfaceData.PF_INT_ARGB_PRE),
118:
119: new OGLSwToSurfaceTransform(SurfaceType.IntRgb,
120: OGLSurfaceData.PF_INT_RGB),
121: new OGLSwToSurfaceTransform(SurfaceType.IntRgbx,
122: OGLSurfaceData.PF_INT_RGBX),
123: new OGLSwToSurfaceTransform(SurfaceType.IntBgr,
124: OGLSurfaceData.PF_INT_BGR),
125: new OGLSwToSurfaceTransform(SurfaceType.IntBgrx,
126: OGLSurfaceData.PF_INT_BGRX),
127: new OGLSwToSurfaceTransform(SurfaceType.Ushort565Rgb,
128: OGLSurfaceData.PF_USHORT_565_RGB),
129: new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgb,
130: OGLSurfaceData.PF_USHORT_555_RGB),
131: new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgbx,
132: OGLSurfaceData.PF_USHORT_555_RGBX),
133: new OGLSwToSurfaceTransform(SurfaceType.ByteGray,
134: OGLSurfaceData.PF_BYTE_GRAY),
135: new OGLSwToSurfaceTransform(SurfaceType.UshortGray,
136: OGLSurfaceData.PF_USHORT_GRAY),
137: new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre,
138: OGLSurfaceData.PF_INT_ARGB_PRE),
139:
140: // texture->surface ops
141: new OGLTextureToSurfaceBlit(),
142: new OGLTextureToSurfaceScale(),
143: new OGLTextureToSurfaceTransform(),
144:
145: // sw->texture ops
146: blitIntArgbPreToTexture,
147: new OGLSwToTextureBlit(SurfaceType.IntRgb,
148: OGLSurfaceData.PF_INT_RGB),
149: new OGLSwToTextureBlit(SurfaceType.IntRgbx,
150: OGLSurfaceData.PF_INT_RGBX),
151: new OGLSwToTextureBlit(SurfaceType.IntBgr,
152: OGLSurfaceData.PF_INT_BGR),
153: new OGLSwToTextureBlit(SurfaceType.IntBgrx,
154: OGLSurfaceData.PF_INT_BGRX),
155: new OGLSwToTextureBlit(SurfaceType.Ushort565Rgb,
156: OGLSurfaceData.PF_USHORT_565_RGB),
157: new OGLSwToTextureBlit(SurfaceType.Ushort555Rgb,
158: OGLSurfaceData.PF_USHORT_555_RGB),
159: new OGLSwToTextureBlit(SurfaceType.Ushort555Rgbx,
160: OGLSurfaceData.PF_USHORT_555_RGBX),
161: new OGLSwToTextureBlit(SurfaceType.ByteGray,
162: OGLSurfaceData.PF_BYTE_GRAY),
163: new OGLSwToTextureBlit(SurfaceType.UshortGray,
164: OGLSurfaceData.PF_USHORT_GRAY),
165: new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture,
166: CompositeType.SrcNoEa, blitIntArgbPreToTexture), };
167: GraphicsPrimitiveMgr.register(primitives);
168: }
169:
170: /**
171: * The following offsets are used to pack the parameters in
172: * createPackedParams(). (They are also used at the native level when
173: * unpacking the params.)
174: */
175: private static final int OFFSET_SRCTYPE = 16;
176: private static final int OFFSET_HINT = 8;
177: private static final int OFFSET_TEXTURE = 3;
178: private static final int OFFSET_RTT = 2;
179: private static final int OFFSET_XFORM = 1;
180: private static final int OFFSET_ISOBLIT = 0;
181:
182: /**
183: * Packs the given parameters into a single int value in order to save
184: * space on the rendering queue.
185: */
186: private static int createPackedParams(boolean isoblit,
187: boolean texture, boolean rtt, boolean xform, int hint,
188: int srctype) {
189: return ((srctype << OFFSET_SRCTYPE) | (hint << OFFSET_HINT)
190: | ((texture ? 1 : 0) << OFFSET_TEXTURE)
191: | ((rtt ? 1 : 0) << OFFSET_RTT)
192: | ((xform ? 1 : 0) << OFFSET_XFORM) | ((isoblit ? 1 : 0) << OFFSET_ISOBLIT));
193: }
194:
195: /**
196: * Enqueues a BLIT operation with the given parameters. Note that the
197: * RenderQueue lock must be held before calling this method.
198: */
199: private static void enqueueBlit(RenderQueue rq, SurfaceData src,
200: SurfaceData dst, int packedParams, int sx1, int sy1,
201: int sx2, int sy2, double dx1, double dy1, double dx2,
202: double dy2) {
203: // assert rq.lock.isHeldByCurrentThread();
204: RenderBuffer buf = rq.getBuffer();
205: rq.ensureCapacityAndAlignment(72, 24);
206: buf.putInt(BLIT);
207: buf.putInt(packedParams);
208: buf.putInt(sx1).putInt(sy1);
209: buf.putInt(sx2).putInt(sy2);
210: buf.putDouble(dx1).putDouble(dy1);
211: buf.putDouble(dx2).putDouble(dy2);
212: buf.putLong(src.getNativeOps());
213: buf.putLong(dst.getNativeOps());
214: }
215:
216: static void Blit(SurfaceData srcData, SurfaceData dstData,
217: Composite comp, Region clip, AffineTransform xform,
218: int hint, int sx1, int sy1, int sx2, int sy2, double dx1,
219: double dy1, double dx2, double dy2, int srctype,
220: boolean texture) {
221: int ctxflags = 0;
222: if (srcData.getTransparency() == Transparency.OPAQUE) {
223: ctxflags |= OGLContext.SRC_IS_OPAQUE;
224: }
225:
226: OGLRenderQueue rq = OGLRenderQueue.getInstance();
227: rq.lock();
228: try {
229: // make sure the RenderQueue keeps a hard reference to the
230: // source (sysmem) SurfaceData to prevent it from being
231: // disposed while the operation is processed on the QFT
232: rq.addReference(srcData);
233:
234: OGLSurfaceData oglDst = (OGLSurfaceData) dstData;
235: if (texture) {
236: // make sure we have a current context before uploading
237: // the sysmem data to the texture object
238: OGLGraphicsConfig gc = oglDst.getOGLGraphicsConfig();
239: OGLContext.setScratchSurface(gc);
240: } else {
241: OGLContext.validateContext(oglDst, oglDst, clip, comp,
242: xform, null, null, ctxflags);
243: }
244:
245: int packedParams = createPackedParams(false, texture,
246: false, xform != null, hint, srctype);
247: enqueueBlit(rq, srcData, dstData, packedParams, sx1, sy1,
248: sx2, sy2, dx1, dy1, dx2, dy2);
249:
250: // always flush immediately, since we (currently) have no means
251: // of tracking changes to the system memory surface
252: rq.flushNow();
253: } finally {
254: rq.unlock();
255: }
256: }
257:
258: /**
259: * Note: The srcImg and biop parameters are only used when invoked
260: * from the OGLBufImgOps.renderImageWithOp() method; in all other cases,
261: * this method can be called with null values for those two parameters,
262: * and they will be effectively ignored.
263: */
264: static void IsoBlit(SurfaceData srcData, SurfaceData dstData,
265: BufferedImage srcImg, BufferedImageOp biop, Composite comp,
266: Region clip, AffineTransform xform, int hint, int sx1,
267: int sy1, int sx2, int sy2, double dx1, double dy1,
268: double dx2, double dy2, boolean texture) {
269: int ctxflags = 0;
270: if (srcData.getTransparency() == Transparency.OPAQUE) {
271: ctxflags |= OGLContext.SRC_IS_OPAQUE;
272: }
273:
274: OGLRenderQueue rq = OGLRenderQueue.getInstance();
275: rq.lock();
276: try {
277: OGLSurfaceData oglSrc = (OGLSurfaceData) srcData;
278: OGLSurfaceData oglDst = (OGLSurfaceData) dstData;
279: int srctype = oglSrc.getType();
280: boolean rtt;
281: OGLSurfaceData srcCtxData;
282: if (srctype == OGLSurfaceData.TEXTURE) {
283: // the source is a regular texture object; we substitute
284: // the destination surface for the purposes of making a
285: // context current
286: rtt = false;
287: srcCtxData = oglDst;
288: } else {
289: // the source is a pbuffer, backbuffer, or render-to-texture
290: // surface; we set rtt to true to differentiate this kind
291: // of surface from a regular texture object
292: rtt = true;
293: if (srctype == OGLSurfaceData.FBOBJECT) {
294: srcCtxData = oglDst;
295: } else {
296: srcCtxData = oglSrc;
297: }
298: }
299:
300: OGLContext.validateContext(srcCtxData, oglDst, clip, comp,
301: xform, null, null, ctxflags);
302:
303: if (biop != null) {
304: OGLBufImgOps.enableBufImgOp(rq, oglSrc, srcImg, biop);
305: }
306:
307: int packedParams = createPackedParams(true, texture, rtt,
308: xform != null, hint, 0 /*unused*/);
309: enqueueBlit(rq, srcData, dstData, packedParams, sx1, sy1,
310: sx2, sy2, dx1, dy1, dx2, dy2);
311:
312: if (biop != null) {
313: OGLBufImgOps.disableBufImgOp(rq, biop);
314: }
315:
316: if (rtt && (oglDst.getType() == OGLSurfaceData.WINDOW)) {
317: // we only have to flush immediately when copying from a
318: // (non-texture) surface to the screen; otherwise Swing apps
319: // might appear unresponsive until the auto-flush completes
320: rq.flushNow();
321: }
322: } finally {
323: rq.unlock();
324: }
325: }
326: }
327:
328: class OGLSurfaceToSurfaceBlit extends Blit {
329:
330: OGLSurfaceToSurfaceBlit() {
331: super (OGLSurfaceData.OpenGLSurface, CompositeType.AnyAlpha,
332: OGLSurfaceData.OpenGLSurface);
333: }
334:
335: public void Blit(SurfaceData src, SurfaceData dst, Composite comp,
336: Region clip, int sx, int sy, int dx, int dy, int w, int h) {
337: OGLBlitLoops.IsoBlit(src, dst, null, null, comp, clip, null,
338: AffineTransformOp.TYPE_NEAREST_NEIGHBOR, sx, sy,
339: sx + w, sy + h, dx, dy, dx + w, dy + h, false);
340: }
341: }
342:
343: class OGLSurfaceToSurfaceScale extends ScaledBlit {
344:
345: OGLSurfaceToSurfaceScale() {
346: super (OGLSurfaceData.OpenGLSurface, CompositeType.AnyAlpha,
347: OGLSurfaceData.OpenGLSurface);
348: }
349:
350: public void Scale(SurfaceData src, SurfaceData dst, Composite comp,
351: Region clip, int sx1, int sy1, int sx2, int sy2,
352: double dx1, double dy1, double dx2, double dy2) {
353: OGLBlitLoops.IsoBlit(src, dst, null, null, comp, clip, null,
354: AffineTransformOp.TYPE_NEAREST_NEIGHBOR, sx1, sy1, sx2,
355: sy2, dx1, dy1, dx2, dy2, false);
356: }
357: }
358:
359: class OGLSurfaceToSurfaceTransform extends TransformBlit {
360:
361: OGLSurfaceToSurfaceTransform() {
362: super (OGLSurfaceData.OpenGLSurface, CompositeType.AnyAlpha,
363: OGLSurfaceData.OpenGLSurface);
364: }
365:
366: public void Transform(SurfaceData src, SurfaceData dst,
367: Composite comp, Region clip, AffineTransform at, int hint,
368: int sx, int sy, int dx, int dy, int w, int h) {
369: OGLBlitLoops.IsoBlit(src, dst, null, null, comp, clip, at,
370: hint, sx, sy, sx + w, sy + h, dx, dy, dx + w, dy + h,
371: false);
372: }
373: }
374:
375: class OGLRTTSurfaceToSurfaceBlit extends Blit {
376:
377: OGLRTTSurfaceToSurfaceBlit() {
378: super (OGLSurfaceData.OpenGLSurfaceRTT, CompositeType.AnyAlpha,
379: OGLSurfaceData.OpenGLSurface);
380: }
381:
382: public void Blit(SurfaceData src, SurfaceData dst, Composite comp,
383: Region clip, int sx, int sy, int dx, int dy, int w, int h) {
384: OGLBlitLoops.IsoBlit(src, dst, null, null, comp, clip, null,
385: AffineTransformOp.TYPE_NEAREST_NEIGHBOR, sx, sy,
386: sx + w, sy + h, dx, dy, dx + w, dy + h, true);
387: }
388: }
389:
390: class OGLRTTSurfaceToSurfaceScale extends ScaledBlit {
391:
392: OGLRTTSurfaceToSurfaceScale() {
393: super (OGLSurfaceData.OpenGLSurfaceRTT, CompositeType.AnyAlpha,
394: OGLSurfaceData.OpenGLSurface);
395: }
396:
397: public void Scale(SurfaceData src, SurfaceData dst, Composite comp,
398: Region clip, int sx1, int sy1, int sx2, int sy2,
399: double dx1, double dy1, double dx2, double dy2) {
400: OGLBlitLoops.IsoBlit(src, dst, null, null, comp, clip, null,
401: AffineTransformOp.TYPE_NEAREST_NEIGHBOR, sx1, sy1, sx2,
402: sy2, dx1, dy1, dx2, dy2, true);
403: }
404: }
405:
406: class OGLRTTSurfaceToSurfaceTransform extends TransformBlit {
407:
408: OGLRTTSurfaceToSurfaceTransform() {
409: super (OGLSurfaceData.OpenGLSurfaceRTT, CompositeType.AnyAlpha,
410: OGLSurfaceData.OpenGLSurface);
411: }
412:
413: public void Transform(SurfaceData src, SurfaceData dst,
414: Composite comp, Region clip, AffineTransform at, int hint,
415: int sx, int sy, int dx, int dy, int w, int h) {
416: OGLBlitLoops.IsoBlit(src, dst, null, null, comp, clip, at,
417: hint, sx, sy, sx + w, sy + h, dx, dy, dx + w, dy + h,
418: true);
419: }
420: }
421:
422: class OGLSurfaceToSwBlit extends Blit {
423:
424: private int typeval;
425:
426: // REMIND: destination will actually be opaque/premultiplied...
427: OGLSurfaceToSwBlit(SurfaceType dstType, int typeval) {
428: super (OGLSurfaceData.OpenGLSurface, CompositeType.SrcNoEa,
429: dstType);
430: this .typeval = typeval;
431: }
432:
433: public void Blit(SurfaceData src, SurfaceData dst, Composite comp,
434: Region clip, int sx, int sy, int dx, int dy, int w, int h) {
435: OGLRenderQueue rq = OGLRenderQueue.getInstance();
436: rq.lock();
437: try {
438: // make sure the RenderQueue keeps a hard reference to the
439: // destination (sysmem) SurfaceData to prevent it from being
440: // disposed while the operation is processed on the QFT
441: rq.addReference(dst);
442:
443: RenderBuffer buf = rq.getBuffer();
444: OGLContext.validateContext((OGLSurfaceData) src);
445:
446: rq.ensureCapacityAndAlignment(48, 32);
447: buf.putInt(SURFACE_TO_SW_BLIT);
448: buf.putInt(sx).putInt(sy);
449: buf.putInt(dx).putInt(dy);
450: buf.putInt(w).putInt(h);
451: buf.putInt(typeval);
452: buf.putLong(src.getNativeOps());
453: buf.putLong(dst.getNativeOps());
454:
455: // always flush immediately
456: rq.flushNow();
457: } finally {
458: rq.unlock();
459: }
460: }
461: }
462:
463: class OGLSwToSurfaceBlit extends Blit {
464:
465: private int typeval;
466:
467: OGLSwToSurfaceBlit(SurfaceType srcType, int typeval) {
468: super (srcType, CompositeType.AnyAlpha,
469: OGLSurfaceData.OpenGLSurface);
470: this .typeval = typeval;
471: }
472:
473: public void Blit(SurfaceData src, SurfaceData dst, Composite comp,
474: Region clip, int sx, int sy, int dx, int dy, int w, int h) {
475: OGLBlitLoops.Blit(src, dst, comp, clip, null,
476: AffineTransformOp.TYPE_NEAREST_NEIGHBOR, sx, sy,
477: sx + w, sy + h, dx, dy, dx + w, dy + h, typeval, false);
478: }
479: }
480:
481: class OGLSwToSurfaceScale extends ScaledBlit {
482:
483: private int typeval;
484:
485: OGLSwToSurfaceScale(SurfaceType srcType, int typeval) {
486: super (srcType, CompositeType.AnyAlpha,
487: OGLSurfaceData.OpenGLSurface);
488: this .typeval = typeval;
489: }
490:
491: public void Scale(SurfaceData src, SurfaceData dst, Composite comp,
492: Region clip, int sx1, int sy1, int sx2, int sy2,
493: double dx1, double dy1, double dx2, double dy2) {
494: OGLBlitLoops.Blit(src, dst, comp, clip, null,
495: AffineTransformOp.TYPE_NEAREST_NEIGHBOR, sx1, sy1, sx2,
496: sy2, dx1, dy1, dx2, dy2, typeval, false);
497: }
498: }
499:
500: class OGLSwToSurfaceTransform extends TransformBlit {
501:
502: private int typeval;
503:
504: OGLSwToSurfaceTransform(SurfaceType srcType, int typeval) {
505: super (srcType, CompositeType.AnyAlpha,
506: OGLSurfaceData.OpenGLSurface);
507: this .typeval = typeval;
508: }
509:
510: public void Transform(SurfaceData src, SurfaceData dst,
511: Composite comp, Region clip, AffineTransform at, int hint,
512: int sx, int sy, int dx, int dy, int w, int h) {
513: OGLBlitLoops.Blit(src, dst, comp, clip, at, hint, sx, sy, sx
514: + w, sy + h, dx, dy, dx + w, dy + h, typeval, false);
515: }
516: }
517:
518: class OGLSwToTextureBlit extends Blit {
519:
520: private int typeval;
521:
522: OGLSwToTextureBlit(SurfaceType srcType, int typeval) {
523: super (srcType, CompositeType.SrcNoEa,
524: OGLSurfaceData.OpenGLTexture);
525: this .typeval = typeval;
526: }
527:
528: public void Blit(SurfaceData src, SurfaceData dst, Composite comp,
529: Region clip, int sx, int sy, int dx, int dy, int w, int h) {
530: OGLBlitLoops.Blit(src, dst, comp, clip, null,
531: AffineTransformOp.TYPE_NEAREST_NEIGHBOR, sx, sy,
532: sx + w, sy + h, dx, dy, dx + w, dy + h, typeval, true);
533: }
534: }
535:
536: class OGLTextureToSurfaceBlit extends Blit {
537:
538: OGLTextureToSurfaceBlit() {
539: super (OGLSurfaceData.OpenGLTexture, CompositeType.AnyAlpha,
540: OGLSurfaceData.OpenGLSurface);
541: }
542:
543: public void Blit(SurfaceData src, SurfaceData dst, Composite comp,
544: Region clip, int sx, int sy, int dx, int dy, int w, int h) {
545: OGLBlitLoops.IsoBlit(src, dst, null, null, comp, clip, null,
546: AffineTransformOp.TYPE_NEAREST_NEIGHBOR, sx, sy,
547: sx + w, sy + h, dx, dy, dx + w, dy + h, true);
548: }
549: }
550:
551: class OGLTextureToSurfaceScale extends ScaledBlit {
552:
553: OGLTextureToSurfaceScale() {
554: super (OGLSurfaceData.OpenGLTexture, CompositeType.AnyAlpha,
555: OGLSurfaceData.OpenGLSurface);
556: }
557:
558: public void Scale(SurfaceData src, SurfaceData dst, Composite comp,
559: Region clip, int sx1, int sy1, int sx2, int sy2,
560: double dx1, double dy1, double dx2, double dy2) {
561: OGLBlitLoops.IsoBlit(src, dst, null, null, comp, clip, null,
562: AffineTransformOp.TYPE_NEAREST_NEIGHBOR, sx1, sy1, sx2,
563: sy2, dx1, dy1, dx2, dy2, true);
564: }
565: }
566:
567: class OGLTextureToSurfaceTransform extends TransformBlit {
568:
569: OGLTextureToSurfaceTransform() {
570: super (OGLSurfaceData.OpenGLTexture, CompositeType.AnyAlpha,
571: OGLSurfaceData.OpenGLSurface);
572: }
573:
574: public void Transform(SurfaceData src, SurfaceData dst,
575: Composite comp, Region clip, AffineTransform at, int hint,
576: int sx, int sy, int dx, int dy, int w, int h) {
577: OGLBlitLoops.IsoBlit(src, dst, null, null, comp, clip, at,
578: hint, sx, sy, sx + w, sy + h, dx, dy, dx + w, dy + h,
579: true);
580: }
581: }
582:
583: /**
584: * This general Blit implemenation converts any source surface to an
585: * intermediate IntArgbPre surface, and then uses the more specific
586: * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate
587: * (premultiplied) surface down to OpenGL.
588: */
589: class OGLGeneralBlit extends Blit {
590:
591: private Blit performop;
592: private WeakReference srcTmp;
593:
594: OGLGeneralBlit(SurfaceType dstType, CompositeType compType,
595: Blit performop) {
596: super (SurfaceType.Any, compType, dstType);
597: this .performop = performop;
598: }
599:
600: public synchronized void Blit(SurfaceData src, SurfaceData dst,
601: Composite comp, Region clip, int sx, int sy, int dx,
602: int dy, int w, int h) {
603: Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
604: CompositeType.SrcNoEa, SurfaceType.IntArgbPre);
605:
606: SurfaceData cachedSrc = null;
607: if (srcTmp != null) {
608: // use cached intermediate surface, if available
609: cachedSrc = (SurfaceData) srcTmp.get();
610: }
611:
612: // convert source to IntArgbPre
613: src = convertFrom(convertsrc, src, sx, sy, w, h, cachedSrc,
614: BufferedImage.TYPE_INT_ARGB_PRE);
615:
616: // copy IntArgbPre intermediate surface to OpenGL surface
617: performop.Blit(src, dst, comp, clip, 0, 0, dx, dy, w, h);
618:
619: if (src != cachedSrc) {
620: // cache the intermediate surface
621: srcTmp = new WeakReference(src);
622: }
623: }
624: }
|