Пример #1
0
  public int chooseCapabilities(
      Capabilities desired, Capabilities[] available, int windowSystemRecommendedChoice) {
    GLCapabilities _desired = (GLCapabilities) desired;
    GLCapabilities[] _available = (GLCapabilities[]) available;

    if (DEBUG) {
      System.err.println("Desired: " + _desired);
      for (int i = 0; i < _available.length; i++) {
        System.err.println("Available " + i + ": " + _available[i]);
      }
      System.err.println("Window system's recommended choice: " + windowSystemRecommendedChoice);
    }

    if (windowSystemRecommendedChoice >= 0
        && windowSystemRecommendedChoice < _available.length
        && _available[windowSystemRecommendedChoice] != null) {
      if (DEBUG) {
        System.err.println(
            "Choosing window system's recommended choice of " + windowSystemRecommendedChoice);
        System.err.println(_available[windowSystemRecommendedChoice]);
      }
      return windowSystemRecommendedChoice;
    }

    // Create score array
    int[] scores = new int[_available.length];
    int NO_SCORE = -9999999;
    int DOUBLE_BUFFER_MISMATCH_PENALTY = 1000;
    int STENCIL_MISMATCH_PENALTY = 500;
    // Pseudo attempt to keep equal rank penalties scale-equivalent
    // (e.g., stencil mismatch is 3 * accum because there are 3 accum
    // components)
    int COLOR_MISMATCH_PENALTY_SCALE = 36;
    int DEPTH_MISMATCH_PENALTY_SCALE = 6;
    int ACCUM_MISMATCH_PENALTY_SCALE = 1;
    int STENCIL_MISMATCH_PENALTY_SCALE = 3;
    for (int i = 0; i < scores.length; i++) {
      scores[i] = NO_SCORE;
    }
    // Compute score for each
    for (int i = 0; i < scores.length; i++) {
      GLCapabilities cur = _available[i];
      if (cur == null) {
        continue;
      }
      if (_desired.isOnscreen() != cur.isOnscreen()) {
        continue;
      }
      if (_desired.getStereo() != cur.getStereo()) {
        continue;
      }
      int score = 0;
      // Compute difference in color depth
      // (Note that this decides the direction of all other penalties)
      score +=
          (COLOR_MISMATCH_PENALTY_SCALE
              * ((cur.getRedBits() + cur.getGreenBits() + cur.getBlueBits() + cur.getAlphaBits())
                  - (_desired.getRedBits()
                      + _desired.getGreenBits()
                      + _desired.getBlueBits()
                      + _desired.getAlphaBits())));
      // Compute difference in depth buffer depth
      score +=
          (DEPTH_MISMATCH_PENALTY_SCALE
              * sign(score)
              * Math.abs(cur.getDepthBits() - _desired.getDepthBits()));
      // Compute difference in accumulation buffer depth
      score +=
          (ACCUM_MISMATCH_PENALTY_SCALE
              * sign(score)
              * Math.abs(
                  (cur.getAccumRedBits()
                          + cur.getAccumGreenBits()
                          + cur.getAccumBlueBits()
                          + cur.getAccumAlphaBits())
                      - (_desired.getAccumRedBits()
                          + _desired.getAccumGreenBits()
                          + _desired.getAccumBlueBits()
                          + _desired.getAccumAlphaBits())));
      // Compute difference in stencil bits
      score +=
          STENCIL_MISMATCH_PENALTY_SCALE
              * sign(score)
              * (cur.getStencilBits() - _desired.getStencilBits());
      if (cur.getDoubleBuffered() != _desired.getDoubleBuffered()) {
        score += sign(score) * DOUBLE_BUFFER_MISMATCH_PENALTY;
      }
      if ((_desired.getStencilBits() > 0) && (cur.getStencilBits() == 0)) {
        score += sign(score) * STENCIL_MISMATCH_PENALTY;
      }
      scores[i] = score;
    }
    // Now prefer hardware-accelerated visuals by pushing scores of
    // non-hardware-accelerated visuals out
    boolean gotHW = false;
    int maxAbsoluteHWScore = 0;
    for (int i = 0; i < scores.length; i++) {
      int score = scores[i];
      if (score == NO_SCORE) {
        continue;
      }
      GLCapabilities cur = _available[i];
      if (cur.getHardwareAccelerated()) {
        int absScore = Math.abs(score);
        if (!gotHW || (absScore > maxAbsoluteHWScore)) {
          gotHW = true;
          maxAbsoluteHWScore = absScore;
        }
      }
    }
    if (gotHW) {
      for (int i = 0; i < scores.length; i++) {
        int score = scores[i];
        if (score == NO_SCORE) {
          continue;
        }
        GLCapabilities cur = _available[i];
        if (!cur.getHardwareAccelerated()) {
          if (score <= 0) {
            score -= maxAbsoluteHWScore;
          } else if (score > 0) {
            score += maxAbsoluteHWScore;
          }
          scores[i] = score;
        }
      }
    }

    if (DEBUG) {
      System.err.print("Scores: [");
      for (int i = 0; i < _available.length; i++) {
        if (i > 0) {
          System.err.print(",");
        }
        System.err.print(" " + scores[i]);
      }
      System.err.println(" ]");
    }

    // Ready to select. Choose score closest to 0.
    int scoreClosestToZero = NO_SCORE;
    int chosenIndex = -1;
    for (int i = 0; i < scores.length; i++) {
      int score = scores[i];
      if (score == NO_SCORE) {
        continue;
      }
      // Don't substitute a positive score for a smaller negative score
      if ((scoreClosestToZero == NO_SCORE)
          || (Math.abs(score) < Math.abs(scoreClosestToZero)
              && ((sign(scoreClosestToZero) < 0) || (sign(score) > 0)))) {
        scoreClosestToZero = score;
        chosenIndex = i;
      }
    }
    if (chosenIndex < 0) {
      throw new NativeWindowException("Unable to select one of the provided GLCapabilities");
    }
    if (DEBUG) {
      System.err.println("Chosen index: " + chosenIndex);
      System.err.println("Chosen capabilities:");
      System.err.println(_available[chosenIndex]);
    }

    return chosenIndex;
  }