/** Updates the filter program. */
  public void updateFilter() {
    Texture2dProgram.ProgramType programType;
    float[] kernel = null;
    float colorAdj = 0.0f;

    Log.d(TAG, "Updating filter to " + mNewFilter);
    switch (mNewFilter) {
      case CameraCaptureActivity.FILTER_NONE:
        programType = Texture2dProgram.ProgramType.TEXTURE_EXT;
        break;
      case CameraCaptureActivity.FILTER_BLACK_WHITE:
        // (In a previous version the TEXTURE_EXT_BW variant was enabled by a flag called
        // ROSE_COLORED_GLASSES, because the shader set the red channel to the B&W color
        // and green/blue to zero.)
        programType = Texture2dProgram.ProgramType.TEXTURE_EXT_BW;
        break;
      case CameraCaptureActivity.FILTER_BLUR:
        programType = Texture2dProgram.ProgramType.TEXTURE_EXT_FILT;
        kernel =
            new float[] {
              1f / 16f, 2f / 16f, 1f / 16f,
              2f / 16f, 4f / 16f, 2f / 16f,
              1f / 16f, 2f / 16f, 1f / 16f
            };
        break;
      case CameraCaptureActivity.FILTER_SHARPEN:
        programType = Texture2dProgram.ProgramType.TEXTURE_EXT_FILT;
        kernel = new float[] {0f, -1f, 0f, -1f, 5f, -1f, 0f, -1f, 0f};
        break;
      case CameraCaptureActivity.FILTER_EDGE_DETECT:
        programType = Texture2dProgram.ProgramType.TEXTURE_EXT_FILT;
        kernel =
            new float[] {
              -1f, -1f, -1f,
              -1f, 8f, -1f,
              -1f, -1f, -1f
            };
        break;
      case CameraCaptureActivity.FILTER_EMBOSS:
        programType = Texture2dProgram.ProgramType.TEXTURE_EXT_FILT;
        kernel =
            new float[] {
              2f, 0f, 0f,
              0f, -1f, 0f,
              0f, 0f, -1f
            };
        colorAdj = 0.5f;
        break;
      default:
        throw new RuntimeException("Unknown filter mode " + mNewFilter);
    }

    // Do we need a whole new program?  (We want to avoid doing this if we don't have
    // too -- compiling a program could be expensive.)
    if (programType != mFullScreen.getProgram().getProgramType()) {
      mFullScreen.changeProgram(new Texture2dProgram(programType));
      // If we created a new program, we need to initialize the texture width/height.
      mIncomingSizeUpdated = true;
    }

    // Update the filter kernel (if any).
    if (kernel != null) {
      mFullScreen.getProgram().setKernel(kernel, colorAdj);
    }

    mCurrentFilter = mNewFilter;
  }