jdk/src/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java
changeset 23325 4c3942938b0d
parent 16840 64446d4710c4
child 23328 4c53a6ebc779
equal deleted inserted replaced
23324:fb6002beb0ce 23325:4c3942938b0d
     1 /*
     1 /*
     2  * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    28 import java.awt.AWTException;
    28 import java.awt.AWTException;
    29 import java.awt.BufferCapabilities;
    29 import java.awt.BufferCapabilities;
    30 import java.awt.Component;
    30 import java.awt.Component;
    31 import java.awt.Graphics;
    31 import java.awt.Graphics;
    32 import java.awt.Graphics2D;
    32 import java.awt.Graphics2D;
    33 import java.awt.GraphicsConfiguration;
       
    34 import java.awt.GraphicsDevice;
       
    35 import java.awt.GraphicsEnvironment;
       
    36 import java.awt.Image;
    33 import java.awt.Image;
    37 import java.awt.ImageCapabilities;
    34 import java.awt.ImageCapabilities;
    38 import java.awt.Rectangle;
    35 import java.awt.Rectangle;
    39 import java.awt.Transparency;
    36 import java.awt.Transparency;
    40 import java.awt.color.ColorSpace;
    37 import java.awt.color.ColorSpace;
    78     private BufferCapabilities bufferCaps;
    75     private BufferCapabilities bufferCaps;
    79     private long pConfigInfo;
    76     private long pConfigInfo;
    80     private ContextCapabilities oglCaps;
    77     private ContextCapabilities oglCaps;
    81     private OGLContext context;
    78     private OGLContext context;
    82     private final Object disposerReferent = new Object();
    79     private final Object disposerReferent = new Object();
       
    80     private final int maxTextureSize;
       
    81 
    83     private static native boolean initCGL();
    82     private static native boolean initCGL();
    84     private static native long getCGLConfigInfo(int displayID, int visualnum,
    83     private static native long getCGLConfigInfo(int displayID, int visualnum,
    85                                                 int swapInterval);
    84                                                 int swapInterval);
    86     private static native int getOGLCapabilities(long configInfo);
    85     private static native int getOGLCapabilities(long configInfo);
    87 
    86 
       
    87     /**
       
    88      * Returns GL_MAX_TEXTURE_SIZE from the shared opengl context. Must be
       
    89      * called under OGLRQ lock, because this method change current context.
       
    90      *
       
    91      * @return GL_MAX_TEXTURE_SIZE
       
    92      */
       
    93     private static native int nativeGetMaxTextureSize();
       
    94 
    88     static {
    95     static {
    89         cglAvailable = initCGL();
    96         cglAvailable = initCGL();
    90     }
    97     }
    91 
    98 
    92     private CGLGraphicsConfig(CGraphicsDevice device, int pixfmt,
    99     private CGLGraphicsConfig(CGraphicsDevice device, int pixfmt,
    93                                 long configInfo, ContextCapabilities oglCaps)
   100                               long configInfo, int maxTextureSize,
    94     {
   101                               ContextCapabilities oglCaps) {
    95         super(device);
   102         super(device);
    96 
   103 
    97         this.pixfmt = pixfmt;
   104         this.pixfmt = pixfmt;
    98         this.pConfigInfo = configInfo;
   105         this.pConfigInfo = configInfo;
    99         this.oglCaps = oglCaps;
   106         this.oglCaps = oglCaps;
       
   107         this.maxTextureSize = maxTextureSize;
   100         context = new OGLContext(OGLRenderQueue.getInstance(), this);
   108         context = new OGLContext(OGLRenderQueue.getInstance(), this);
   101 
   109 
   102         // add a record to the Disposer so that we destroy the native
   110         // add a record to the Disposer so that we destroy the native
   103         // CGLGraphicsConfigInfo data when this object goes away
   111         // CGLGraphicsConfigInfo data when this object goes away
   104         Disposer.addRecord(disposerReferent,
   112         Disposer.addRecord(disposerReferent,
   124         if (!cglAvailable) {
   132         if (!cglAvailable) {
   125             return null;
   133             return null;
   126         }
   134         }
   127 
   135 
   128         long cfginfo = 0;
   136         long cfginfo = 0;
       
   137         int textureSize = 0;
   129         final String ids[] = new String[1];
   138         final String ids[] = new String[1];
   130         OGLRenderQueue rq = OGLRenderQueue.getInstance();
   139         OGLRenderQueue rq = OGLRenderQueue.getInstance();
   131         rq.lock();
   140         rq.lock();
   132         try {
   141         try {
   133             // getCGLConfigInfo() creates and destroys temporary
   142             // getCGLConfigInfo() creates and destroys temporary
   136             OGLContext.invalidateCurrentContext();
   145             OGLContext.invalidateCurrentContext();
   137 
   146 
   138             cfginfo = getCGLConfigInfo(device.getCGDisplayID(), pixfmt,
   147             cfginfo = getCGLConfigInfo(device.getCGDisplayID(), pixfmt,
   139                                        kOpenGLSwapInterval);
   148                                        kOpenGLSwapInterval);
   140             if (cfginfo != 0L) {
   149             if (cfginfo != 0L) {
       
   150                 textureSize = nativeGetMaxTextureSize();
       
   151                 // 7160609: GL still fails to create a square texture of this
       
   152                 // size. Half should be safe enough.
       
   153                 // Explicitly not support a texture more than 2^14, see 8010999.
       
   154                 textureSize = textureSize <= 16384 ? textureSize / 2 : 8192;
   141                 OGLContext.setScratchSurface(cfginfo);
   155                 OGLContext.setScratchSurface(cfginfo);
   142                 rq.flushAndInvokeNow(new Runnable() {
   156                 rq.flushAndInvokeNow(() -> {
   143                     public void run() {
   157                     ids[0] = OGLContext.getOGLIdString();
   144                         ids[0] = OGLContext.getOGLIdString();
       
   145                     }
       
   146                 });
   158                 });
   147             }
   159             }
   148         } finally {
   160         } finally {
   149             rq.unlock();
   161             rq.unlock();
   150         }
   162         }
   152             return null;
   164             return null;
   153         }
   165         }
   154 
   166 
   155         int oglCaps = getOGLCapabilities(cfginfo);
   167         int oglCaps = getOGLCapabilities(cfginfo);
   156         ContextCapabilities caps = new OGLContextCaps(oglCaps, ids[0]);
   168         ContextCapabilities caps = new OGLContextCaps(oglCaps, ids[0]);
   157 
   169         return new CGLGraphicsConfig(device, pixfmt, cfginfo, textureSize, caps);
   158         return new CGLGraphicsConfig(device, pixfmt, cfginfo, caps);
       
   159     }
   170     }
   160 
   171 
   161     public static boolean isCGLAvailable() {
   172     public static boolean isCGLAvailable() {
   162         return cglAvailable;
   173         return cglAvailable;
   163     }
   174     }
   244         try {
   255         try {
   245             OGLContext.invalidateCurrentContext();
   256             OGLContext.invalidateCurrentContext();
   246         } finally {
   257         } finally {
   247             rq.unlock();
   258             rq.unlock();
   248         }
   259         }
   249 
       
   250         updateTotalDisplayBounds();
       
   251     }
   260     }
   252 
   261 
   253     @Override
   262     @Override
   254     public String toString() {
   263     public String toString() {
   255         int displayID = getDevice().getCGDisplayID();
   264         int displayID = getDevice().getCGDisplayID();
   419     @Override
   428     @Override
   420     public void removeDeviceEventListener(AccelDeviceEventListener l) {
   429     public void removeDeviceEventListener(AccelDeviceEventListener l) {
   421         AccelDeviceEventNotifier.removeListener(l);
   430         AccelDeviceEventNotifier.removeListener(l);
   422     }
   431     }
   423 
   432 
   424     private static final Rectangle totalDisplayBounds = new Rectangle();
       
   425 
       
   426     private static void updateTotalDisplayBounds() {
       
   427         synchronized (totalDisplayBounds) {
       
   428             Rectangle virtualBounds = new Rectangle();
       
   429             for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
       
   430                 for (GraphicsConfiguration gc : gd.getConfigurations()) {
       
   431                     virtualBounds = virtualBounds.union(gc.getBounds());
       
   432                 }
       
   433             }
       
   434             totalDisplayBounds.setBounds(virtualBounds);
       
   435         }
       
   436     }
       
   437 
       
   438     // 7160609: GL still fails to create a square texture of this size,
       
   439     //          so we use this value to cap the total display bounds.
       
   440     native private static int getMaxTextureSize();
       
   441 
       
   442     @Override
   433     @Override
   443     public int getMaxTextureWidth() {
   434     public int getMaxTextureWidth() {
   444         //Temporary disable this logic and use some magic constrain.
   435         return Math.max(maxTextureSize / getDevice().getScaleFactor(),
   445         /*
   436                         getBounds().width);
   446          int width;
       
   447 
       
   448          synchronized (totalDisplayBounds) {
       
   449          if (totalDisplayBounds.width == 0) {
       
   450          updateTotalDisplayBounds();
       
   451          }
       
   452          width = totalDisplayBounds.width;
       
   453          }
       
   454 
       
   455          return Math.min(width, getMaxTextureSize());
       
   456          */
       
   457         return getMaxTextureSize() / (getDevice().getScaleFactor() * 2);
       
   458     }
   437     }
   459 
   438 
   460     @Override
   439     @Override
   461     public int getMaxTextureHeight() {
   440     public int getMaxTextureHeight() {
   462         //Temporary disable this logic and use some magic constrain.
   441         return Math.max(maxTextureSize / getDevice().getScaleFactor(),
   463         /*
   442                         getBounds().height);
   464          int height;
       
   465 
       
   466          synchronized (totalDisplayBounds) {
       
   467          if (totalDisplayBounds.height == 0) {
       
   468          updateTotalDisplayBounds();
       
   469          }
       
   470          height = totalDisplayBounds.height;
       
   471          }
       
   472 
       
   473          return Math.min(height, getMaxTextureSize());
       
   474          */
       
   475         return getMaxTextureSize() / (getDevice().getScaleFactor() * 2);
       
   476     }
   443     }
   477 }
   444 }