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