Ejemplo n.º 1
0
  private final void evalUpstreamSurface(String dbgPrefix, ProxySurface surface) {
    //
    // evaluate nature of upstreamSurface, may create EGL instances if required
    //

    boolean isEGLSurfaceValid = true; // assume yes

    final EGLGraphicsDevice eglDevice;
    final AbstractGraphicsConfiguration aConfig;
    {
      final AbstractGraphicsConfiguration surfaceConfig = surface.getGraphicsConfiguration();
      final AbstractGraphicsDevice surfaceDevice =
          null != surfaceConfig ? surfaceConfig.getScreen().getDevice() : null;
      if (DEBUG) {
        System.err.println(
            dbgPrefix
                + "SurfaceDevice: "
                + surfaceDevice.getClass().getSimpleName()
                + ", hash 0x"
                + Integer.toHexString(surfaceDevice.hashCode())
                + ", "
                + surfaceDevice);
        System.err.println(
            dbgPrefix
                + "SurfaceConfig: "
                + surfaceConfig.getClass().getSimpleName()
                + ", hash 0x"
                + Integer.toHexString(surfaceConfig.hashCode())
                + ", "
                + surfaceConfig);
      }

      final AbstractGraphicsConfiguration upstreamConfig =
          upstreamSurface.getGraphicsConfiguration();
      final AbstractGraphicsDevice upstreamDevice = upstreamConfig.getScreen().getDevice();
      if (DEBUG) {
        System.err.println(
            dbgPrefix
                + "UpstreamDevice: "
                + upstreamDevice.getClass().getSimpleName()
                + ", hash 0x"
                + Integer.toHexString(upstreamDevice.hashCode())
                + ", "
                + upstreamDevice);
        System.err.println(
            dbgPrefix
                + "UpstreamConfig: "
                + upstreamConfig.getClass().getSimpleName()
                + ", hash 0x"
                + Integer.toHexString(upstreamConfig.hashCode())
                + ", "
                + upstreamConfig);
      }

      if (surfaceDevice instanceof EGLGraphicsDevice) {
        eglDevice = (EGLGraphicsDevice) surfaceDevice;
        aConfig = surfaceConfig;
        if (DEBUG) {
          System.err.println(
              dbgPrefix
                  + "Reusing this eglDevice: "
                  + eglDevice
                  + ", using this config "
                  + aConfig.getClass().getSimpleName()
                  + " "
                  + aConfig);
        }
        if (EGL.EGL_NO_DISPLAY == eglDevice.getHandle()) {
          eglDevice.open();
          isEGLSurfaceValid = false;
          surface.addUpstreamOptionBits(ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE);
        }
      } else if (upstreamDevice instanceof EGLGraphicsDevice) {
        eglDevice = (EGLGraphicsDevice) upstreamDevice;
        aConfig = upstreamConfig;
        if (DEBUG) {
          System.err.println(
              dbgPrefix
                  + "Reusing upstream eglDevice: "
                  + eglDevice
                  + ", using upstream config "
                  + aConfig.getClass().getSimpleName()
                  + " "
                  + aConfig);
        }
        if (EGL.EGL_NO_DISPLAY == eglDevice.getHandle()) {
          eglDevice.open();
          isEGLSurfaceValid = false;
          surface.addUpstreamOptionBits(ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE);
        }
      } else {
        eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
        eglDevice.open();
        aConfig = upstreamConfig;
        isEGLSurfaceValid = false;
        surface.addUpstreamOptionBits(ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE);
      }
    }

    final GLCapabilitiesImmutable capsRequested =
        (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
    final EGLGraphicsConfiguration eglConfig;
    if (aConfig instanceof EGLGraphicsConfiguration) {
      // Config is already in EGL type - reuse ..
      final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities();
      if (!isEGLSurfaceValid
          || !EGLGraphicsConfiguration.isEGLConfigValid(
              eglDevice.getHandle(), capsChosen.getEGLConfig())) {
        // 'refresh' the native EGLConfig handle
        capsChosen.setEGLConfig(
            EGLGraphicsConfiguration.EGLConfigId2EGLConfig(
                eglDevice.getHandle(), capsChosen.getEGLConfigID()));
        if (0 == capsChosen.getEGLConfig()) {
          throw new GLException(
              "Refreshing native EGLConfig handle failed with error "
                  + EGLContext.toHexString(EGL.eglGetError())
                  + ": "
                  + eglDevice
                  + ", "
                  + capsChosen
                  + " of "
                  + aConfig);
        }
        final AbstractGraphicsScreen eglScreen =
            new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
        eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
        if (DEBUG) {
          System.err.println(dbgPrefix + "Refreshing eglConfig: " + eglConfig);
        }
        isEGLSurfaceValid = false;
      } else {
        eglConfig = (EGLGraphicsConfiguration) aConfig;
        if (DEBUG) {
          System.err.println(dbgPrefix + "Reusing eglConfig: " + eglConfig);
        }
      }
    } else {
      final AbstractGraphicsScreen eglScreen =
          new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
      eglConfig =
          EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
              capsRequested,
              capsRequested,
              null,
              eglScreen,
              aConfig.getVisualID(VIDType.NATIVE),
              false /* forceTransparencyFlag */);

      if (null == eglConfig) {
        throw new GLException("Couldn't create EGLGraphicsConfiguration from " + eglScreen);
      } else if (DEBUG) {
        System.err.println(dbgPrefix + "Chosen eglConfig: " + eglConfig);
      }
      isEGLSurfaceValid = false;
    }
    surface.setGraphicsConfiguration(eglConfig);

    if (isEGLSurfaceValid) {
      isEGLSurfaceValid =
          EGLDrawable.isValidEGLSurface(eglDevice.getHandle(), upstreamSurface.getSurfaceHandle());
    }
    if (isEGLSurfaceValid) {
      surface.setSurfaceHandle(upstreamSurface.getSurfaceHandle());
      surface.clearUpstreamOptionBits(ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE);
      if (DEBUG) {
        System.err.println(
            dbgPrefix + "Fin: Already valid EGL surface - use as-is: " + upstreamSurface);
      }
    } else {
      surface.setSurfaceHandle(EGL.EGL_NO_SURFACE);
      surface.addUpstreamOptionBits(
          ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE); // create/destroy in EGLDrawable
      if (DEBUG) {
        System.err.println(dbgPrefix + "Fin: EGL surface n/a - TBD: " + upstreamSurface);
      }
    }
  }
Ejemplo n.º 2
0
  /**
   * @param defaultQuirks GLRendererQuirks of the EGLDrawableFactory's defaultDevice
   * @param device
   * @param glp desired GLProfile, may be null
   * @param config
   * @param winattrmask
   * @param forceTransparentFlag
   * @return
   */
  public static EGLGLCapabilities EGLConfig2Capabilities(
      GLRendererQuirks defaultQuirks,
      EGLGraphicsDevice device,
      GLProfile glp,
      long config,
      int winattrmask,
      boolean forceTransparentFlag) {
    final long display = device.getHandle();
    final int cfgID;
    final int rType;
    final int visualID;

    final int _attributes[] = {
      EGL.EGL_CONFIG_ID, // 0
      EGL.EGL_RENDERABLE_TYPE,
      EGL.EGL_NATIVE_VISUAL_ID,
      EGL.EGL_CONFIG_CAVEAT,
      EGL.EGL_RED_SIZE, // 4
      EGL.EGL_GREEN_SIZE,
      EGL.EGL_BLUE_SIZE,
      EGL.EGL_ALPHA_SIZE, // 7
      EGL.EGL_STENCIL_SIZE, // 8
      EGL.EGL_DEPTH_SIZE,
      EGL.EGL_TRANSPARENT_TYPE, // 10
      EGL.EGL_TRANSPARENT_RED_VALUE,
      EGL.EGL_TRANSPARENT_GREEN_VALUE,
      EGL.EGL_TRANSPARENT_BLUE_VALUE,
      EGL.EGL_SAMPLES, // 14
      EGLExt.EGL_COVERAGE_BUFFERS_NV, // 15
      EGLExt.EGL_COVERAGE_SAMPLES_NV
    };
    final IntBuffer attributes = Buffers.newDirectIntBuffer(_attributes);
    final IntBuffer values = Buffers.newDirectIntBuffer(attributes.remaining());
    EGL.eglGetConfigAttributes(display, config, attributes, values);

    // get the configID
    if (EGL.EGL_CONFIG_ID != attributes.get(0)) {
      if (DEBUG) {
        // FIXME: this happens on a ATI PC Emulation ..
        System.err.println(
            dbgCfgFailIntro
                + "ConfigID"
                + dbgCfgFailForConfig
                + toHexString(config)
                + dbgCfgFailError
                + toHexString(EGL.eglGetError()));
      }
      return null;
    }
    cfgID = values.get(0);

    if (EGL.EGL_RENDERABLE_TYPE != attributes.get(1)) {
      if (DEBUG) {
        System.err.println(
            dbgCfgFailIntro
                + "EGL_RENDERABLE_TYPE"
                + dbgCfgFailForConfig
                + toHexString(config)
                + dbgCfgFailError
                + toHexString(EGL.eglGetError()));
      }
      return null;
    }
    {
      final int rTypeOrig = values.get(1);
      if (defaultQuirks.exist(GLRendererQuirks.GLES3ViaEGLES2Config)
          && 0 != (EGL.EGL_OPENGL_ES2_BIT & rTypeOrig)) {
        rType = rTypeOrig | EGLExt.EGL_OPENGL_ES3_BIT_KHR;
      } else {
        rType = rTypeOrig;
      }
    }

    if (EGL.EGL_NATIVE_VISUAL_ID == attributes.get(2)) {
      visualID = values.get(2);
    } else {
      if (DEBUG) {
        System.err.println(
            dbgCfgFailIntro
                + "EGL_NATIVE_VISUAL_ID"
                + dbgCfgFailForConfig
                + toHexString(config)
                + dbgCfgFailError
                + toHexString(EGL.eglGetError()));
      }
      visualID = VisualIDHolder.VID_UNDEFINED;
    }

    EGLGLCapabilities caps = null;
    try {
      if (null == glp) {
        glp = EGLGLCapabilities.getCompatible(device, rType);
      }
      if (!EGLGLCapabilities.isCompatible(glp, rType)) {
        if (DEBUG) {
          System.err.println(
              "config "
                  + toHexString(config)
                  + ": Requested GLProfile "
                  + glp
                  + " with quirks "
                  + defaultQuirks
                  + " not compatible with EGL-RenderableType["
                  + EGLGLCapabilities.renderableTypeToString(null, rType)
                  + "]");
        }
        return null;
      }
      caps = new EGLGLCapabilities(config, cfgID, visualID, glp, rType);
    } catch (GLException gle) {
      if (DEBUG) {
        System.err.println("config " + toHexString(config) + ": " + gle);
      }
      return null;
    }

    if (EGL.EGL_CONFIG_CAVEAT == attributes.get(3)) {
      if (EGL.EGL_SLOW_CONFIG == values.get(3)) {
        caps.setHardwareAccelerated(false);
      }
    } else if (DEBUG) {
      System.err.println(
          dbgCfgFailIntro
              + "EGL_CONFIG_CAVEAT"
              + dbgCfgFailForConfig
              + toHexString(config)
              + dbgCfgFailError
              + toHexString(EGL.eglGetError()));
    }
    // ALPHA shall be set at last - due to it's auto setting by the above (!opaque / samples)
    if (EGL.EGL_RED_SIZE == attributes.get(4)) {
      caps.setRedBits(values.get(4));
    } else if (DEBUG) {
      System.err.println(
          dbgCfgFailIntro
              + "EGL_RED_SIZE"
              + dbgCfgFailForConfig
              + toHexString(config)
              + dbgCfgFailError
              + toHexString(EGL.eglGetError()));
    }
    if (EGL.EGL_GREEN_SIZE == attributes.get(5)) {
      caps.setGreenBits(values.get(5));
    } else if (DEBUG) {
      System.err.println(
          dbgCfgFailIntro
              + "EGL_GREEN_SIZE"
              + dbgCfgFailForConfig
              + toHexString(config)
              + dbgCfgFailError
              + toHexString(EGL.eglGetError()));
    }
    if (EGL.EGL_BLUE_SIZE == attributes.get(6)) {
      caps.setBlueBits(values.get(6));
    } else if (DEBUG) {
      System.err.println(
          dbgCfgFailIntro
              + "EGL_BLUE_SIZE"
              + dbgCfgFailForConfig
              + toHexString(config)
              + dbgCfgFailError
              + toHexString(EGL.eglGetError()));
    }
    if (EGL.EGL_ALPHA_SIZE == attributes.get(7)) {
      caps.setAlphaBits(values.get(7));
    } else if (DEBUG) {
      System.err.println(
          dbgCfgFailIntro
              + "EGL_ALPHA_SIZE"
              + dbgCfgFailForConfig
              + toHexString(config)
              + dbgCfgFailError
              + toHexString(EGL.eglGetError()));
    }
    if (EGL.EGL_STENCIL_SIZE == attributes.get(8)) {
      caps.setStencilBits(values.get(8));
    } else if (DEBUG) {
      System.err.println(
          dbgCfgFailIntro
              + "EGL_STENCIL_SIZE"
              + dbgCfgFailForConfig
              + toHexString(config)
              + dbgCfgFailError
              + toHexString(EGL.eglGetError()));
    }
    if (EGL.EGL_DEPTH_SIZE == attributes.get(9)) {
      caps.setDepthBits(values.get(9));
    } else if (DEBUG) {
      System.err.println(
          dbgCfgFailIntro
              + "EGL_DEPTH_SIZE"
              + dbgCfgFailForConfig
              + toHexString(config)
              + dbgCfgFailError
              + toHexString(EGL.eglGetError()));
    }
    if (forceTransparentFlag) {
      caps.setBackgroundOpaque(false);
    } else if (EGL.EGL_TRANSPARENT_TYPE == attributes.get(10)) {
      caps.setBackgroundOpaque(values.get(10) != EGL.EGL_TRANSPARENT_RGB);
    } else if (DEBUG) {
      System.err.println(
          dbgCfgFailIntro
              + "EGL_TRANSPARENT_TYPE"
              + dbgCfgFailForConfig
              + toHexString(config)
              + dbgCfgFailError
              + toHexString(EGL.eglGetError()));
    }
    if (!caps.isBackgroundOpaque()) {
      if (EGL.EGL_TRANSPARENT_RED_VALUE == attributes.get(11)) {
        final int v = values.get(11);
        caps.setTransparentRedValue(EGL.EGL_DONT_CARE == v ? -1 : v);
      } else if (DEBUG) {
        System.err.println(
            dbgCfgFailIntro
                + "EGL_TRANSPARENT_RED_VALUE"
                + dbgCfgFailForConfig
                + toHexString(config)
                + dbgCfgFailError
                + toHexString(EGL.eglGetError()));
      }
      if (EGL.EGL_TRANSPARENT_GREEN_VALUE == attributes.get(12)) {
        final int v = values.get(12);
        caps.setTransparentGreenValue(EGL.EGL_DONT_CARE == v ? -1 : v);
      } else if (DEBUG) {
        System.err.println(
            dbgCfgFailIntro
                + "EGL_TRANSPARENT_GREEN_VALUE"
                + dbgCfgFailForConfig
                + toHexString(config)
                + dbgCfgFailError
                + toHexString(EGL.eglGetError()));
      }
      if (EGL.EGL_TRANSPARENT_BLUE_VALUE == attributes.get(13)) {
        final int v = values.get(13);
        caps.setTransparentBlueValue(EGL.EGL_DONT_CARE == v ? -1 : v);
      } else if (DEBUG) {
        System.err.println(
            dbgCfgFailIntro
                + "EGL_TRANSPARENT_BLUE_VALUE"
                + dbgCfgFailForConfig
                + toHexString(config)
                + dbgCfgFailError
                + toHexString(EGL.eglGetError()));
      }
      /**
       * Not defined in EGL if( EGL.EGL_TRANSPARENT_ALPHA_VALUE == attributes.get(??) ) { final int
       * v = values.get(??); caps.setTransparentAlphaValue(EGL.EGL_DONT_CARE==v?-1:v); } else
       * if(DEBUG) {
       * System.err.println(dbgStr01+"EGL_TRANSPARENT_ALPHA_VALUE"+dbgStr02+toHexString(config)+dbgEGLCfgFailError+toHexString(EGL.eglGetError()));
       * }
       */
    }
    if (EGL.EGL_SAMPLES == attributes.get(14)) {
      final int numSamples = values.get(14);
      caps.setSampleBuffers(numSamples > 0 ? true : false);
      caps.setNumSamples(numSamples);
    } else if (DEBUG) {
      System.err.println(
          dbgCfgFailIntro
              + "EGL_SAMPLES"
              + dbgCfgFailForConfig
              + toHexString(config)
              + dbgCfgFailError
              + toHexString(EGL.eglGetError()));
    }
    if (!caps.getSampleBuffers()) {
      // try NV_coverage_sample extension
      if (EGLExt.EGL_COVERAGE_BUFFERS_NV == attributes.get(15)) {
        final boolean enabled = values.get(15) > 0;
        if (enabled && EGLExt.EGL_COVERAGE_SAMPLES_NV == attributes.get(16)) {
          caps.setSampleExtension(GLGraphicsConfigurationUtil.NV_coverage_sample);
          caps.setSampleBuffers(true);
          caps.setNumSamples(values.get(16));
        } else if (DEBUG) {
          System.err.println(
              dbgCfgFailIntro
                  + "EGL_COVERAGE_SAMPLES_NV"
                  + dbgCfgFailForConfig
                  + toHexString(config)
                  + dbgCfgFailError
                  + toHexString(EGL.eglGetError()));
        }
      }
      /**
       * else if(DEBUG) { // Not required - vendor extension - don't be verbose!
       * System.err.println(dbgCfgFailIntro+"EGL_COVERAGE_BUFFERS_NV"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
       * }
       */
    }

    // Since the passed GLProfile may be null,
    // we use EGL_RENDERABLE_TYPE derived profile as created in the EGLGLCapabilities constructor.
    final int availableTypeBits = EGLConfigDrawableTypeBits(device, config);
    final int drawableTypeBits = winattrmask & availableTypeBits;

    if (0 == drawableTypeBits) {
      return null;
    }

    return (EGLGLCapabilities)
        GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, caps);
  }