1 /** 2 * Copyright 2011 JogAmp Community. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without modification, are 5 * permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, this list of 8 * conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 * of conditions and the following disclaimer in the documentation and/or other materials 12 * provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED 15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 * The views and conclusions contained in the software and documentation are those of the 25 * authors and should not be interpreted as representing official policies, either expressed 26 * or implied, of JogAmp Community. 27 */ 28 29 package jogamp.newt.driver.android; 30 31 import com.jogamp.nativewindow.DefaultGraphicsScreen; 32 33 import jogamp.newt.MonitorModeProps; 34 import jogamp.newt.MonitorModeProps.Cache; 35 36 import android.content.Context; 37 import android.graphics.PixelFormat; 38 import android.util.DisplayMetrics; 39 import android.view.Surface; 40 import android.view.WindowManager; 41 42 import com.jogamp.newt.MonitorDevice; 43 import com.jogamp.newt.MonitorMode; 44 45 public class ScreenDriver extends jogamp.newt.ScreenImpl { 46 47 static { DisplayDriver.initSingleton()48 DisplayDriver.initSingleton(); 49 } 50 ScreenDriver()51 public ScreenDriver() { 52 } 53 54 @Override createNativeImpl()55 protected void createNativeImpl() { 56 aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); 57 } 58 59 @Override closeNativeImpl()60 protected void closeNativeImpl() { } 61 62 @Override validateScreenIndex(final int idx)63 protected int validateScreenIndex(final int idx) { 64 return 0; // FIXME: only one screen available ? 65 } 66 getModeImpl(final Cache cache, final android.view.Display aDisplay, final DisplayMetrics outMetrics, final int modeIdx, final int screenSizeNRot, final int nrot)67 private final MonitorMode getModeImpl(final Cache cache, final android.view.Display aDisplay, final DisplayMetrics outMetrics, final int modeIdx, final int screenSizeNRot, final int nrot) { 68 final int[] props = new int[MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL]; 69 int i = 0; 70 props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL; 71 i = getScreenSize(outMetrics, screenSizeNRot, props, i); // width, height 72 i = getBpp(aDisplay, props, i); // bpp 73 props[i++] = (int) ( aDisplay.getRefreshRate() * 100.0f ); // Hz * 100 74 props[i++] = 0; // flags 75 props[i++] = modeIdx; // modeId; 76 props[i++] = nrot; 77 return MonitorModeProps.streamInMonitorMode(null, cache, props, 0); 78 } 79 80 @Override collectNativeMonitorModesAndDevicesImpl(final Cache cache)81 protected void collectNativeMonitorModesAndDevicesImpl(final Cache cache) { 82 // FIXME: Multi Monitor Implementation missing [for newer Android version ?] 83 84 final Context ctx = jogamp.common.os.android.StaticContext.getContext(); 85 final WindowManager wmgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); 86 final DisplayMetrics outMetrics = new DisplayMetrics(); 87 final android.view.Display aDisplay = wmgr.getDefaultDisplay(); 88 aDisplay.getMetrics(outMetrics); 89 90 final int arot = aDisplay.getRotation(); 91 final int nrot = androidRotation2NewtRotation(arot); 92 93 final int modeIdx=0; // no native modeId in use - use 0 94 MonitorMode currentMode = null; 95 for(int r=0; r<4; r++) { // for all rotations 96 final int nrot_i = r*MonitorMode.ROTATE_90; 97 final MonitorMode mode = getModeImpl(cache, aDisplay, outMetrics, modeIdx, 0, nrot_i); 98 if( nrot == nrot_i ) { 99 currentMode = mode; 100 } 101 } 102 103 final int[] props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES - 1 - MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES]; 104 int i = 0; 105 props[i++] = props.length; 106 props[i++] = 0; // crt_idx 107 props[i++] = 0; // is-clone 108 props[i++] = 1; // is-primary 109 i = getScreenSizeMM(outMetrics, props, i); // sizeMM 110 props[i++] = 0; // rotated viewport x pixel-units 111 props[i++] = 0; // rotated viewport y pixel-units 112 props[i++] = outMetrics.widthPixels; // rotated viewport width pixel-units 113 props[i++] = outMetrics.heightPixels; // rotated viewport height pixel-units 114 props[i++] = 0; // rotated viewport x window-units 115 props[i++] = 0; // rotated viewport y window-units 116 props[i++] = outMetrics.widthPixels; // rotated viewport width window-units 117 props[i++] = outMetrics.heightPixels; // rotated viewport height window-units 118 MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, cache.monitorModes, props, 0, null); 119 } 120 121 @Override queryCurrentMonitorModeImpl(final MonitorDevice monitor)122 protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) { 123 final Context ctx = jogamp.common.os.android.StaticContext.getContext(); 124 final WindowManager wmgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); 125 final DisplayMetrics outMetrics = new DisplayMetrics(); 126 final android.view.Display aDisplay = wmgr.getDefaultDisplay(); 127 aDisplay.getMetrics(outMetrics); 128 129 final int currNRot = androidRotation2NewtRotation(aDisplay.getRotation()); 130 return getModeImpl(null, aDisplay, outMetrics, 0, currNRot, currNRot); 131 } 132 133 @Override setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode)134 protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) { 135 return false; 136 } 137 138 //---------------------------------------------------------------------- 139 // Internals only 140 // androidRotation2NewtRotation(final int arot)141 static int androidRotation2NewtRotation(final int arot) { 142 switch(arot) { 143 case Surface.ROTATION_270: return MonitorMode.ROTATE_270; 144 case Surface.ROTATION_180: return MonitorMode.ROTATE_180; 145 case Surface.ROTATION_90: return MonitorMode.ROTATE_90; 146 case Surface.ROTATION_0: 147 } 148 return MonitorMode.ROTATE_0; 149 } getScreenSize(final DisplayMetrics outMetrics, final int nrot, final int[] props, int offset)150 static int getScreenSize(final DisplayMetrics outMetrics, final int nrot, final int[] props, int offset) { 151 // swap width and height, since Android reflects rotated dimension, we don't 152 if (MonitorMode.ROTATE_90 == nrot || MonitorMode.ROTATE_270 == nrot) { 153 props[offset++] = outMetrics.heightPixels; 154 props[offset++] = outMetrics.widthPixels; 155 } else { 156 props[offset++] = outMetrics.widthPixels; 157 props[offset++] = outMetrics.heightPixels; 158 } 159 return offset; 160 } getBpp(final android.view.Display aDisplay, final int[] props, int offset)161 static int getBpp(final android.view.Display aDisplay, final int[] props, int offset) { 162 int bpp; 163 switch(aDisplay.getPixelFormat()) { 164 case PixelFormat.RGBA_8888: bpp=32; break; 165 case PixelFormat.RGBX_8888: bpp=32; break; 166 case PixelFormat.RGB_888: bpp=24; break; 167 case PixelFormat.RGB_565: bpp=16; break; 168 case PixelFormat.RGBA_5551: bpp=16; break; 169 case PixelFormat.RGBA_4444: bpp=16; break; 170 case PixelFormat.RGB_332: bpp= 8; break; 171 default: bpp=32; 172 } 173 props[offset++] = bpp; 174 return offset; 175 } getScreenSizeMM(final DisplayMetrics outMetrics, final int[] props, int offset)176 static int getScreenSizeMM(final DisplayMetrics outMetrics, final int[] props, int offset) { 177 final float inW = outMetrics.widthPixels / outMetrics.xdpi; 178 final float inH = outMetrics.heightPixels / outMetrics.ydpi; 179 final float mmpi = 25.4f; 180 final float mmW = inW * mmpi; 181 final float mmH = inH * mmpi; 182 if( DEBUG ) { 183 System.err.println("Screen A screen "+outMetrics.widthPixels+" x "+outMetrics.heightPixels); 184 System.err.println("Screen A xy dpi "+outMetrics.xdpi+" x "+outMetrics.ydpi); 185 System.err.println("Screen A densityDPI "+outMetrics.densityDpi); 186 System.err.println("Screen A density "+outMetrics.density); 187 System.err.println("Screen N xy inch "+inW+" x "+inH); 188 System.err.println("Screen N xy mm "+mmW+" x "+mmH); 189 } 190 props[offset++] = Math.round(mmW); 191 props[offset++] = Math.round(mmH); 192 return offset; 193 } 194 } 195 196