001: /*
002: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License version
007: * 2 only, as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful, but
010: * WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * General Public License version 2 for more details (a copy is
013: * included at /legal/license.txt).
014: *
015: * You should have received a copy of the GNU General Public License
016: * version 2 along with this work; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
018: * 02110-1301 USA
019: *
020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
021: * Clara, CA 95054 or visit www.sun.com if you need additional
022: * information or have any questions.
023: */
024:
025: package javax.microedition.khronos.egl;
026:
027: import javax.microedition.khronos.opengles.*;
028: import com.sun.jsr239.*;
029: import com.sun.midp.lcdui.GameMap;
030:
031: import javax.microedition.lcdui.Graphics;
032:
033: import java.lang.ref.WeakReference;
034: import java.util.Enumeration;
035:
036: class EGL10Impl implements EGL10 {
037:
038: static EGL10Impl theInstance;
039:
040: static {
041: if (GLConfiguration.supportsEGL11) {
042: theInstance = new EGL11Impl();
043: } else {
044: theInstance = new EGL10Impl();
045: }
046: }
047:
048: static final boolean DEBUG = false;
049:
050: // eglCreateWindowSurface strategies
051: static final int STRATEGY_USE_WINDOW = 0;
052: static final int STRATEGY_USE_PIXMAP = 1;
053: static final int STRATEGY_USE_PBUFFER = 2;
054:
055: native int _eglGetError();
056:
057: native int _eglGetDisplay(int displayID);
058:
059: native int _eglInitialize(int display, int[] major_minor);
060:
061: native int _eglTerminate(int display);
062:
063: native String _eglQueryString(int display, int name);
064:
065: native int _eglGetConfigs(int display, int[] configs,
066: int config_size, int[] num_config);
067:
068: native int _eglChooseConfig(int display, int[] attrib_list,
069: int[] configs, int config_size, int[] num_config);
070:
071: native int _eglGetConfigAttrib(int display, int config,
072: int attribute, int[] value);
073:
074: native int _getWindowStrategy(Graphics winGraphics);
075:
076: native int _getWindowNativeID(Graphics winGraphics);
077:
078: native int _getWindowPixmap(int displayId, int configId,
079: Graphics winGraphics, int width, int height);
080:
081: native int _getImagePixmap(int displayId, int configId,
082: Graphics imageGraphics, int width, int height);
083:
084: native void _destroyPixmap(int pixmapPtr);
085:
086: native void _getWindowContents(Graphics winGraphics,
087: int deltaHeight, int pixmapPointer);
088:
089: native void _putWindowContents(Graphics target, int deltaHeight,
090: int pixmapPointer);
091:
092: native int _eglCreateWindowSurface(int display, int config,
093: int win, int[] attrib_list);
094:
095: native int _eglCreatePixmapSurface(int display, int config,
096: int pixmap, int[] attrib_list);
097:
098: native int _eglCreatePbufferSurface(int display, int config,
099: int[] attrib_list);
100:
101: native int _eglDestroySurface(int display, int surface);
102:
103: native int _eglQuerySurface(int display, int surface,
104: int attribute, int[] value);
105:
106: native int _eglCreateContext(int display, int config,
107: int share_context, int[] attrib_list);
108:
109: native int _eglDestroyContext(int display, int context);
110:
111: native int _eglMakeCurrent(int display, int draw, int read,
112: int context);
113:
114: native int _getCurrentContext();
115:
116: native int _getCurrentSurface(int readdraw);
117:
118: native int _getCurrentDisplay();
119:
120: native int _eglQueryContext(int display, int context,
121: int attribute, int[] value);
122:
123: native int _eglWaitGL();
124:
125: native int _eglWaitNative(int engine);
126:
127: native int _eglSwapBuffers(int display, int surface);
128:
129: native int _eglCopyBuffers(int display, int surface,
130: Graphics target, int width, int height, int deltaHeight);
131:
132: native int _eglSurfaceAttrib(int display, int surface,
133: int attribute, int value);
134:
135: native int _eglBindTexImage(int display, int surface, int buffer);
136:
137: native int _eglReleaseTexImage(int display, int surface, int buffer);
138:
139: native int _eglSwapInterval(int display, int interval);
140:
141: private native int _getFullDisplayWidth();
142:
143: private native int _getFullDisplayHeight();
144:
145: private native int _garbageCollect(boolean fullGC);
146:
147: public static EGL10Impl getInstance() {
148: return theInstance;
149: }
150:
151: void throwIAE(String message) {
152: throw new IllegalArgumentException(message);
153: }
154:
155: /**
156: * Utility method to determine if an attribute list consisting of
157: * (<token>, <value>) pairs is properly terminated by an EGL_NONE
158: * token.
159: */
160: boolean isTerminated(int[] attrib_list) {
161: if (attrib_list == null) {
162: return true; // Empty list is considered terminated
163: }
164:
165: int idx = 0;
166: while (idx < attrib_list.length) {
167: if (attrib_list[idx] == EGL_NONE) {
168: return true;
169: }
170: idx += 2;
171: }
172: return false;
173: }
174:
175: public synchronized EGLDisplay eglGetDisplay(Object displayID) {
176: int _displayId = -1;
177: if (displayID == EGL11.EGL_DEFAULT_DISPLAY) {
178: _displayId = 0;
179: } else {
180: throwIAE(Errors.EGL_DISPLAY_NOT_EGL_DEFAULT_DISPLAY);
181: }
182:
183: int display = _eglGetDisplay(_displayId);
184: return EGLDisplayImpl.getInstance(display);
185: }
186:
187: public synchronized boolean eglInitialize(EGLDisplay display,
188: int[] major_minor) {
189: if (display == null) {
190: throwIAE(Errors.EGL_DISPLAY_NULL);
191: }
192: if (major_minor != null && major_minor.length < 2) {
193: throwIAE(Errors.EGL_MAJOR_MINOR_SHORT);
194: }
195: boolean retval = EGL_TRUE == _eglInitialize(
196: ((EGLDisplayImpl) display).nativeId(), major_minor);
197:
198: // Workaround - the underlying engine is really 1.1 but we
199: // will only report 1.0 if the system.config file has
200: // "jsr239.supportsEGL11=false"
201: if ((!GLConfiguration.supportsEGL11) && (major_minor != null)) {
202: major_minor[0] = 1;
203: major_minor[1] = 0;
204: }
205:
206: return retval;
207: }
208:
209: public synchronized boolean eglTerminate(EGLDisplay display) {
210: if (display == null) {
211: throwIAE(Errors.EGL_DISPLAY_NULL);
212: }
213: boolean success = EGL_TRUE == _eglTerminate(((EGLDisplayImpl) display)
214: .nativeId());
215:
216: return success;
217: }
218:
219: public synchronized String eglQueryString(EGLDisplay display,
220: int name) {
221: if (display == null) {
222: throwIAE(Errors.EGL_DISPLAY_NULL);
223: }
224: String s = _eglQueryString(((EGLDisplayImpl) display)
225: .nativeId(), name);
226: return s;
227: }
228:
229: public synchronized boolean eglGetConfigs(EGLDisplay display,
230: EGLConfig[] configs, int config_size, int[] num_config) {
231: if (display == null) {
232: throwIAE(Errors.EGL_DISPLAY_NULL);
233: }
234: if ((configs != null) && (configs.length < config_size)) {
235: throwIAE(Errors.EGL_CONFIG_SHORT);
236: }
237: if (num_config != null && num_config.length < 1) {
238: throwIAE(Errors.EGL_NUM_CONFIG_SHORT);
239: }
240:
241: if (config_size < 0) {
242: config_size = 0;
243: }
244:
245: int[] iconfigs = (configs == null) ? null
246: : new int[config_size];
247: boolean success = EGL_TRUE == _eglGetConfigs(
248: ((EGLDisplayImpl) display).nativeId(), iconfigs,
249: config_size, num_config);
250: if (success && (configs != null)) {
251: for (int i = 0; i < num_config[0]; i++) {
252: configs[i] = EGLConfigImpl.getInstance(iconfigs[i]);
253: }
254: }
255:
256: return success;
257: }
258:
259: // Make a copy of an int array
260: int[] clone(int[] a) {
261: int len = a.length;
262: int[] clone = new int[len];
263: System.arraycopy(a, 0, clone, 0, len);
264: return clone;
265: }
266:
267: public synchronized boolean eglChooseConfig(EGLDisplay display,
268: int[] attrib_list, EGLConfig[] configs, int config_size,
269: int[] num_config) {
270: if (display == null) {
271: throwIAE(Errors.EGL_DISPLAY_NULL);
272: }
273: if ((configs != null) && (configs.length < config_size)) {
274: throwIAE(Errors.EGL_CONFIG_SHORT);
275: }
276:
277: // Clone the attribute list and check the clone for termination.
278: // This prevents another thread from altering the list between
279: // the time of the check and the time it is passed to the GL.
280: if (attrib_list != null) {
281: attrib_list = clone(attrib_list);
282: }
283: if (!isTerminated(attrib_list)) {
284: throwIAE(Errors.EGL_ATTRIBS_NOT_TERMINATED);
285: }
286: if (num_config != null && num_config.length < 1) {
287: throwIAE(Errors.EGL_NUM_CONFIG_SHORT);
288: }
289:
290: int[] iconfigs = (configs == null) ? null
291: : new int[config_size];
292: boolean success = EGL_TRUE == _eglChooseConfig(
293: ((EGLDisplayImpl) display).nativeId(), attrib_list,
294: iconfigs, config_size, num_config);
295: if (success && configs != null) {
296: for (int i = 0; i < config_size; i++) {
297: configs[i] = EGLConfigImpl.getInstance(iconfigs[i]);
298: }
299: }
300:
301: return success;
302: }
303:
304: public synchronized boolean eglGetConfigAttrib(EGLDisplay display,
305: EGLConfig config, int attribute, int[] value) {
306: if (display == null) {
307: throwIAE(Errors.EGL_DISPLAY_NULL);
308: }
309: if (config == null) {
310: throwIAE(Errors.EGL_CONFIG_NULL);
311: }
312: if (value == null || value.length < 1) {
313: throwIAE(Errors.EGL_VALUE_SHORT);
314: }
315:
316: int displayID = ((EGLDisplayImpl) display).nativeId();
317: int configID = ((EGLConfigImpl) config).nativeId();
318:
319: boolean retval = EGL_TRUE == _eglGetConfigAttrib(displayID,
320: configID, attribute, value);
321:
322: // Workaround for Gerbera bug, see CR 6349801
323: if (retval && (attribute == EGL10.EGL_BUFFER_SIZE)) {
324: int[] v = new int[1];
325: _eglGetConfigAttrib(displayID, configID, EGL_RED_SIZE, v);
326: value[0] = v[0];
327: _eglGetConfigAttrib(displayID, configID, EGL_GREEN_SIZE, v);
328: value[0] += v[0];
329: _eglGetConfigAttrib(displayID, configID, EGL_BLUE_SIZE, v);
330: value[0] += v[0];
331: _eglGetConfigAttrib(displayID, configID, EGL_ALPHA_SIZE, v);
332: value[0] += v[0];
333: }
334:
335: // Workaround for Gerbera bug, see CR 6401394
336: // Gerbera returns 0 whereas the value should be EGL_NONE,
337: // EGL_SLOW_CONFIG, or EGL_NON_CONFORMANT.
338: if (retval && (attribute == EGL10.EGL_CONFIG_CAVEAT)) {
339: value[0] = EGL10.EGL_NONE;
340: }
341:
342: return retval;
343: }
344:
345: private int createWindowPixmap(int displayId, int configId,
346: Graphics winGraphics, int width, int height) {
347: int pixmapPointer;
348:
349: // Duplicate mutable image contents
350: try {
351: pixmapPointer = _getWindowPixmap(displayId, configId,
352: winGraphics, width, height);
353:
354: } catch (OutOfMemoryError e) {
355: _garbageCollect(false);
356:
357: try {
358: pixmapPointer = _getWindowPixmap(displayId, configId,
359: winGraphics, width, height);
360: } catch (OutOfMemoryError e2) {
361: _garbageCollect(true);
362:
363: pixmapPointer = _getWindowPixmap(displayId, configId,
364: winGraphics, width, height);
365: }
366: }
367: return pixmapPointer;
368: }
369:
370: public synchronized EGLSurface eglCreateWindowSurface(
371: EGLDisplay display, EGLConfig config, Object win,
372: int[] attrib_list) {
373: if (display == null) {
374: throwIAE(Errors.EGL_DISPLAY_NULL);
375: }
376: if (config == null) {
377: throwIAE(Errors.EGL_CONFIG_NULL);
378: }
379: // Clone the attribute list and check the clone for termination.
380: // This prevents another thread from altering the list between
381: // the time of the check and the time it is passed to the GL.
382: if (attrib_list != null) {
383: attrib_list = clone(attrib_list);
384: }
385: if (!isTerminated(attrib_list)) {
386: throwIAE(Errors.EGL_ATTRIBS_NOT_TERMINATED);
387: }
388:
389: if (!(win instanceof Graphics)) {
390: throwIAE(Errors.EGL_BAD_WINDOW_SURFACE);
391: }
392:
393: Graphics winGraphics = (Graphics) win;
394:
395: int width = _getFullDisplayWidth();
396: int height = _getFullDisplayHeight();
397:
398: int displayId = ((EGLDisplayImpl) display).nativeId();
399: int configId = ((EGLConfigImpl) config).nativeId();
400:
401: EGLSurfaceImpl surface;
402: int strategy = _getWindowStrategy(winGraphics);
403: if (strategy == STRATEGY_USE_WINDOW) {
404: int winId = _getWindowNativeID(winGraphics);
405: int surf = _eglCreateWindowSurface(displayId, configId,
406: winId, attrib_list);
407: surface = EGLSurfaceImpl.getInstance(surf, width, height);
408: } else if (strategy == STRATEGY_USE_PIXMAP) {
409: int pixmapPointer = createWindowPixmap(displayId, configId,
410: winGraphics, width, height);
411: int surf = _eglCreatePixmapSurface(displayId, configId,
412: pixmapPointer, attrib_list);
413: surface = EGLSurfaceImpl.getInstance(surf, width, height);
414: surface.setPixmapPointer(pixmapPointer);
415: } else if (strategy == STRATEGY_USE_PBUFFER) {
416: int attrib_size = (attrib_list != null) ? attrib_list.length
417: : 0;
418: int[] new_attrib_list = new int[attrib_size + 5];
419:
420: int sidx = 0;
421: int didx = 0;
422: while (sidx < attrib_size - 1) {
423: if (attrib_list[sidx] == EGL_WIDTH
424: || attrib_list[sidx] == EGL_HEIGHT) {
425: sidx += 2;
426: continue;
427: } else if (attrib_list[sidx] == EGL_NONE) {
428: break;
429: }
430:
431: new_attrib_list[didx++] = attrib_list[sidx++];
432: new_attrib_list[didx++] = attrib_list[sidx++];
433: }
434: new_attrib_list[didx++] = EGL_WIDTH;
435: new_attrib_list[didx++] = width;
436: new_attrib_list[didx++] = EGL_HEIGHT;
437: new_attrib_list[didx++] = height;
438: new_attrib_list[didx] = EGL_NONE;
439:
440: int surf = _eglCreatePbufferSurface(displayId, configId,
441: new_attrib_list);
442: surface = EGLSurfaceImpl.getInstance(surf, width, height);
443: } else {
444: // This should never happen
445: throw new RuntimeException(Errors.EGL_CANT_HAPPEN);
446: }
447:
448: surface.setTarget(winGraphics);
449: return surface;
450: }
451:
452: private int createImagePixmap(int displayId, int configId,
453: Graphics imageGraphics, int width, int height) {
454: int pixmapPointer;
455:
456: // Duplicate mutable image contents
457: try {
458: pixmapPointer = _getImagePixmap(displayId, configId,
459: imageGraphics, width, height);
460:
461: } catch (OutOfMemoryError e) {
462: _garbageCollect(false);
463:
464: try {
465: pixmapPointer = _getImagePixmap(displayId, configId,
466: imageGraphics, width, height);
467: } catch (OutOfMemoryError e2) {
468: _garbageCollect(true);
469:
470: pixmapPointer = _getImagePixmap(displayId, configId,
471: imageGraphics, width, height);
472: }
473: }
474: return pixmapPointer;
475: }
476:
477: public synchronized EGLSurface eglCreatePixmapSurface(
478: EGLDisplay display, EGLConfig config, Object pixmap,
479: int[] attrib_list) {
480: if (display == null) {
481: throwIAE(Errors.EGL_DISPLAY_NULL);
482: }
483: if (config == null) {
484: throwIAE(Errors.EGL_CONFIG_NULL);
485: }
486: if (pixmap == null) {
487: throwIAE(Errors.EGL_PIXMAP_NULL);
488: }
489: if (!(pixmap instanceof Graphics)) {
490: throwIAE(Errors.EGL_BAD_PIXMAP);
491: }
492:
493: Graphics imageGraphics = (Graphics) pixmap;
494: int width = GameMap.getGraphicsAccess().getGraphicsWidth(
495: imageGraphics);
496: int height = GameMap.getGraphicsAccess().getGraphicsHeight(
497: imageGraphics);
498:
499: int displayId = ((EGLDisplayImpl) display).nativeId();
500: int configId = ((EGLConfigImpl) config).nativeId();
501:
502: // Clone the attribute list and check the clone for termination.
503: // This prevents another thread from altering the list between
504: // the time of the check and the time it is passed to the GL.
505: if (attrib_list != null) {
506: attrib_list = clone(attrib_list);
507: }
508: if (!isTerminated(attrib_list)) {
509: throwIAE(Errors.EGL_ATTRIBS_NOT_TERMINATED);
510: }
511:
512: int pixmapPointer = createImagePixmap(displayId, configId,
513: imageGraphics, width, height);
514:
515: int surf = _eglCreatePixmapSurface(displayId, configId,
516: pixmapPointer, attrib_list);
517: EGLSurfaceImpl surface = EGLSurfaceImpl.getInstance(surf,
518: width, height);
519: surface.setPixmapPointer(pixmapPointer);
520: surface.setTarget(imageGraphics);
521:
522: return surface;
523: }
524:
525: public synchronized EGLSurface eglCreatePbufferSurface(
526: EGLDisplay display, EGLConfig config, int[] attrib_list) {
527: if (display == null) {
528: throwIAE(Errors.EGL_DISPLAY_NULL);
529: }
530: if (config == null) {
531: throwIAE(Errors.EGL_CONFIG_NULL);
532: }
533: // Clone the attribute list and check the clone for termination.
534: // This prevents another thread from altering the list between
535: // the time of the check and the time it is passed to the GL.
536: if (attrib_list != null) {
537: attrib_list = clone(attrib_list);
538: }
539: if (!isTerminated(attrib_list)) {
540: throwIAE(Errors.EGL_ATTRIBS_NOT_TERMINATED);
541: }
542:
543: int surf = _eglCreatePbufferSurface(((EGLDisplayImpl) display)
544: .nativeId(), ((EGLConfigImpl) config).nativeId(),
545: attrib_list);
546:
547: if (surf != 0) {
548: int[] val = new int[1];
549: int width, height;
550:
551: _eglQuerySurface(((EGLDisplayImpl) display).nativeId(),
552: surf, EGL10.EGL_WIDTH, val);
553: width = val[0];
554:
555: _eglQuerySurface(((EGLDisplayImpl) display).nativeId(),
556: surf, EGL10.EGL_HEIGHT, val);
557: height = val[0];
558:
559: EGLSurfaceImpl surface = EGLSurfaceImpl.getInstance(surf,
560: width, height);
561:
562: return surface;
563: } else {
564: return EGL_NO_SURFACE;
565: }
566: }
567:
568: public synchronized boolean eglDestroySurface(EGLDisplay display,
569: EGLSurface surface) {
570: if (display == null) {
571: throwIAE(Errors.EGL_DISPLAY_NULL);
572: }
573: if (surface == null) {
574: throwIAE(Errors.EGL_SURFACE_NULL);
575: }
576:
577: EGLDisplayImpl disp = (EGLDisplayImpl) display;
578: EGLSurfaceImpl surf = (EGLSurfaceImpl) surface;
579:
580: boolean success = EGL_TRUE == _eglDestroySurface(disp
581: .nativeId(), surf.nativeId());
582:
583: if (success) {
584: int pixmapPtr = surf.getPixmapPointer();
585: if (pixmapPtr != 0) {
586: _destroyPixmap(pixmapPtr);
587: surf.setPixmapPointer(0);
588: }
589:
590: surf.dispose();
591: }
592:
593: return success;
594: }
595:
596: public synchronized boolean eglQuerySurface(EGLDisplay display,
597: EGLSurface surface, int attribute, int[] value) {
598: if (display == null) {
599: throwIAE(Errors.EGL_DISPLAY_NULL);
600: }
601: if (surface == null) {
602: throwIAE(Errors.EGL_SURFACE_NULL);
603: }
604: if (value == null || value.length < 1) {
605: throwIAE(Errors.EGL_VALUE_SHORT);
606: }
607: return EGL_TRUE == _eglQuerySurface(((EGLDisplayImpl) display)
608: .nativeId(), ((EGLSurfaceImpl) surface).nativeId(),
609: attribute, value);
610: }
611:
612: public synchronized int eglGetError() {
613: GL10Impl.grabContext();
614: int retval = _eglGetError();
615: return retval;
616: }
617:
618: public synchronized EGLContext eglCreateContext(EGLDisplay display,
619: EGLConfig config, EGLContext share_context,
620: int[] attrib_list) {
621: if (display == null) {
622: throwIAE(Errors.EGL_DISPLAY_NULL);
623: }
624: if (config == null) {
625: throwIAE(Errors.EGL_CONFIG_NULL);
626: }
627: if (share_context == null) {
628: throwIAE(Errors.EGL_SHARE_CONTEXT_NULL);
629: }
630: // Clone the attribute list and check the clone for termination.
631: // This prevents another thread from altering the list between
632: // the time of the check and the time it is passed to the GL.
633: if (attrib_list != null) {
634: attrib_list = clone(attrib_list);
635: }
636: if (!isTerminated(attrib_list)) {
637: throwIAE(Errors.EGL_ATTRIBS_NOT_TERMINATED);
638: }
639:
640: int contextID = _eglCreateContext(((EGLDisplayImpl) display)
641: .nativeId(), ((EGLConfigImpl) config).nativeId(),
642: ((EGLContextImpl) share_context).nativeId(),
643: attrib_list);
644:
645: if (contextID != 0) { // EGL_NO_CONTEXT
646: EGLContextImpl context = EGLContextImpl
647: .getInstance(contextID);
648:
649: return context;
650: } else {
651: return EGL_NO_CONTEXT;
652: }
653: }
654:
655: // If the context is current on some thread, flag it for
656: // destruction whenever another context (or EGL_NO_CONTEXT)
657: // replaces it. If it is not current on any thread, just delete
658: // it outright.
659: public synchronized boolean eglDestroyContext(EGLDisplay display,
660: EGLContext context) {
661: if (display == null) {
662: throwIAE(Errors.EGL_DISPLAY_NULL);
663: }
664: if (context == null) {
665: throwIAE(Errors.EGL_CONTEXT_NULL);
666: }
667:
668: boolean success = true;
669: if (GLConfiguration.singleThreaded
670: && GL10Impl.contextsByThread.containsKey(context)) {
671: // Mark the context as 'to be destroyed'. We may need to
672: // make an internal call to release the context and
673: // restore it later in order to run pending commands; we
674: // can only truly destroy it when an application-level
675: // call to 'eglMakeCurrent' causes it to be released.
676:
677: ((EGLContextImpl) context).setDestroyed(true);
678:
679: // Return success even though nothing has happened.
680: } else {
681: GL10Impl.grabContext();
682: success = EGL_TRUE == _eglDestroyContext(
683: ((EGLDisplayImpl) display).nativeId(),
684: ((EGLContextImpl) context).nativeId());
685: if (success) {
686: ((EGLContextImpl) context).dispose();
687: }
688: }
689:
690: return success;
691: }
692:
693: public synchronized boolean eglMakeCurrent(EGLDisplay display,
694: EGLSurface draw, EGLSurface read, EGLContext context) {
695: if (display == null) {
696: throwIAE(Errors.EGL_DISPLAY_NULL);
697: }
698: if (draw == null) {
699: // Note: null is _not_ a synonym for EGL_NO_SURFACE
700: throwIAE(Errors.EGL_DRAW_NULL);
701: }
702: if (read == null) {
703: // Note: null is _not_ a synonym for EGL_NO_SURFACE
704: throwIAE(Errors.EGL_READ_NULL);
705: }
706: if (context == null) {
707: // Note: null is _not_ a synonym for EGL_NO_CONTEXT
708: throwIAE(Errors.EGL_CONTEXT_NULL);
709: }
710:
711: int displayId = ((EGLDisplayImpl) display).nativeId();
712:
713: int retVal = _eglMakeCurrent(displayId, ((EGLSurfaceImpl) draw)
714: .nativeId(), ((EGLSurfaceImpl) read).nativeId(),
715: ((EGLContextImpl) context).nativeId());
716:
717: if (retVal == EGL_TRUE) {
718: Thread currentThread = Thread.currentThread();
719: GL10Impl.currentContext = context;
720:
721: // Update thread-to-context mapping and context state
722: if (context == EGL_NO_CONTEXT) {
723: // Locate the old context for the current thread
724: Object oldContext = GL10Impl.contextsByThread
725: .get(currentThread);
726: if (oldContext != null) {
727: EGLContextImpl ocimpl = (EGLContextImpl) oldContext;
728:
729: // If the old context was previously destroyed by the
730: // application, perform the actual destruction now.
731: if (ocimpl.isDestroyed()) {
732: eglDestroyContext(ocimpl.getDisplay(), ocimpl);
733: }
734:
735: // Clear the associated thread and surfaces in the
736: // context object.
737: ocimpl.setBoundThread(null);
738: ocimpl.setDisplay(null);
739: ocimpl.setDrawSurface(null);
740: ocimpl.setReadSurface(null);
741:
742: // Remove the old context from the thread map
743: GL10Impl.contextsByThread.remove(currentThread);
744: }
745: } else {
746: // Cache the associated thread and surfaces in the
747: // context object.
748: EGLContextImpl cimpl = (EGLContextImpl) context;
749: cimpl.setBoundThread(currentThread);
750: cimpl.setDisplay((EGLDisplayImpl) display);
751: cimpl.setDrawSurface((EGLSurfaceImpl) draw);
752: cimpl.setReadSurface((EGLSurfaceImpl) read);
753:
754: // Add the new context to the thread map
755: GL10Impl.contextsByThread.put(currentThread, context);
756: }
757: }
758:
759: return retVal == EGL_TRUE;
760: }
761:
762: public synchronized EGLContext eglGetCurrentContext() {
763: Thread currentThread = Thread.currentThread();
764: EGLContext context = (EGLContext) GL10Impl.contextsByThread
765: .get(currentThread);
766: return (context == null) ? EGL_NO_CONTEXT : context;
767: }
768:
769: public synchronized EGLSurface eglGetCurrentSurface(int readdraw) {
770: if (readdraw != EGL_READ && readdraw != EGL_DRAW) {
771: throwIAE(Errors.EGL_READDRAW_BAD);
772: }
773:
774: EGLContextImpl cimpl = (EGLContextImpl) eglGetCurrentContext();
775: if (cimpl != EGL_NO_CONTEXT) {
776: if (readdraw == EGL_READ) {
777: return cimpl.getReadSurface();
778: } else {
779: return cimpl.getDrawSurface();
780: }
781: } else {
782: return EGL_NO_SURFACE;
783: }
784: }
785:
786: public synchronized EGLDisplay eglGetCurrentDisplay() {
787: EGLContextImpl cimpl = (EGLContextImpl) eglGetCurrentContext();
788: if (cimpl != EGL_NO_CONTEXT) {
789: return cimpl.getDisplay();
790: } else {
791: return EGL_NO_DISPLAY;
792: }
793: }
794:
795: public synchronized boolean eglQueryContext(EGLDisplay display,
796: EGLContext context, int attribute, int[] value) {
797: if (display == null) {
798: throwIAE(Errors.EGL_DISPLAY_NULL);
799: }
800: if (context == null) {
801: throwIAE(Errors.EGL_CONTEXT_NULL);
802: }
803: if (value == null || value.length < 1) {
804: throwIAE(Errors.EGL_VALUE_SHORT);
805: }
806: boolean retval = EGL_TRUE == _eglQueryContext(
807: ((EGLDisplayImpl) display).nativeId(),
808: ((EGLContextImpl) context).nativeId(), attribute, value);
809: return retval;
810: }
811:
812: public synchronized boolean eglWaitGL() {
813: // Ensure all queued commands have been submitted to the GL
814:
815: EGLContextImpl cimpl = (EGLContextImpl) eglGetCurrentContext();
816: GL currGL = cimpl.getGL();
817: ((GL10Impl) currGL).qflush();
818:
819: GL10Impl.grabContext();
820: boolean returnValue = EGL_TRUE == _eglWaitGL();
821:
822: EGLSurfaceImpl currentDrawSurface = cimpl.getDrawSurfaceImpl();
823:
824: if (currentDrawSurface != null) {
825: final Graphics targetGraphics = currentDrawSurface
826: .getTarget();
827: // Creator is null if Graphics is obtained from Image.
828: // In case of Image there are no manus and hence no
829: // shift is required.
830: final Object creator = (targetGraphics != null) ? GameMap
831: .getGraphicsAccess().getGraphicsCreator(
832: targetGraphics) : null;
833: int deltaHeight = 0;
834: if (creator != null) {
835: deltaHeight = _getFullDisplayHeight()
836: - GameMap.getGraphicsAccess()
837: .getGraphicsHeight(targetGraphics);
838: }
839: _putWindowContents(targetGraphics, deltaHeight,
840: currentDrawSurface.getPixmapPointer());
841: } else {
842: // Do nothing
843: }
844:
845: return returnValue;
846: }
847:
848: public synchronized boolean eglWaitNative(int engine,
849: Object bindTarget) {
850: EGLContextImpl cimpl = (EGLContextImpl) eglGetCurrentContext();
851: // IMPL_NOTE: should we really check for cimpl == null here?
852: if (cimpl != null) {
853: EGLSurfaceImpl currentDrawSurface = cimpl
854: .getDrawSurfaceImpl();
855:
856: if (currentDrawSurface != null) {
857: Graphics targetGraphics = currentDrawSurface
858: .getTarget();
859: // Creator is null if Graphics is obtained from Image.
860: // In case of Image there are no manus and hence no
861: // shift is required.
862: Object creator = (targetGraphics != null) ? GameMap
863: .getGraphicsAccess().getGraphicsCreator(
864: targetGraphics) : null;
865: int deltaHeight = 0;
866: if (creator != null) {
867: deltaHeight = _getFullDisplayHeight()
868: - GameMap.getGraphicsAccess()
869: .getGraphicsHeight(targetGraphics);
870: }
871: _getWindowContents(targetGraphics, deltaHeight,
872: currentDrawSurface.getPixmapPointer());
873: } else {
874: // Do nothing
875: }
876: }
877:
878: GL10Impl.grabContext();
879: boolean retval = EGL_TRUE == _eglWaitNative(engine);
880: return retval;
881: }
882:
883: public synchronized boolean eglSwapBuffers(EGLDisplay display,
884: EGLSurface surface) {
885: if (display == null) {
886: throwIAE(Errors.EGL_DISPLAY_NULL);
887: }
888: if (surface == null) {
889: throwIAE(Errors.EGL_SURFACE_NULL);
890: }
891:
892: // Need revisit - what if pixmap or pbuffer?
893: GL10Impl.grabContext();
894: boolean retval = EGL_TRUE == _eglSwapBuffers(
895: ((EGLDisplayImpl) display).nativeId(),
896: ((EGLSurfaceImpl) surface).nativeId());
897: return retval;
898: }
899:
900: public synchronized boolean eglCopyBuffers(EGLDisplay display,
901: EGLSurface surface, Object native_pixmap) {
902: if (display == null) {
903: throwIAE(Errors.EGL_DISPLAY_NULL);
904: }
905: if (surface == null) {
906: throwIAE(Errors.EGL_SURFACE_NULL);
907: }
908: if (native_pixmap == null) {
909: throwIAE(Errors.EGL_NATIVE_PIXMAP_NULL);
910: }
911: if (!(native_pixmap instanceof Graphics)) {
912: throwIAE(Errors.EGL_BAD_PIXMAP);
913: }
914:
915: Graphics imageGraphics = (Graphics) native_pixmap;
916:
917: GL10Impl.grabContext();
918:
919: EGLSurfaceImpl surf = (EGLSurfaceImpl) surface;
920:
921: final Graphics targetGraphics = surf.getTarget();
922: // Creator is null if Graphics is obtained from Image.
923: // In case of Image there are no manus and hence no
924: // shift is required.
925: final Object creator = (targetGraphics != null) ? GameMap
926: .getGraphicsAccess().getGraphicsCreator(targetGraphics)
927: : null;
928: int deltaHeight = 0;
929: if (creator != null) {
930: deltaHeight = _getFullDisplayHeight()
931: - GameMap.getGraphicsAccess().getGraphicsHeight(
932: targetGraphics);
933: }
934: int pixmapPointer;
935:
936: boolean retval;
937: // Duplicate mutable image contents
938: try {
939: retval = EGL_TRUE == _eglCopyBuffers(
940: ((EGLDisplayImpl) display).nativeId(), surf
941: .nativeId(), imageGraphics,
942: surf.getWidth(), surf.getHeight(), deltaHeight);
943: } catch (OutOfMemoryError e) {
944: _garbageCollect(false);
945:
946: try {
947: retval = EGL_TRUE == _eglCopyBuffers(
948: ((EGLDisplayImpl) display).nativeId(), surf
949: .nativeId(), imageGraphics, surf
950: .getWidth(), surf.getHeight(),
951: deltaHeight);
952: } catch (OutOfMemoryError e2) {
953: _garbageCollect(true);
954:
955: retval = EGL_TRUE == _eglCopyBuffers(
956: ((EGLDisplayImpl) display).nativeId(), surf
957: .nativeId(), imageGraphics, surf
958: .getWidth(), surf.getHeight(),
959: deltaHeight);
960: }
961: }
962: return retval;
963: }
964:
965: public EGL10Impl() {
966: }
967: }
|