Beispiel #1
0
/**
 * Convert effective internalformat into GL function parameters
 * valid for underlying driver.
 */
void
DriverFormatsFromEffectiveInternalFormat(gl::GLContext* gl,
                                         TexInternalFormat effectiveinternalformat,
                                         GLenum* out_driverInternalFormat,
                                         GLenum* out_driverFormat,
                                         GLenum* out_driverType)
{
    MOZ_ASSERT(out_driverInternalFormat);
    MOZ_ASSERT(out_driverFormat);
    MOZ_ASSERT(out_driverType);

    TexInternalFormat unsizedinternalformat = LOCAL_GL_NONE;
    TexType type = LOCAL_GL_NONE;

    UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(effectiveinternalformat,
                                                            &unsizedinternalformat, &type);

    // driverType: almost always the generic type that we just got, except on ES
    // we must replace HALF_FLOAT by HALF_FLOAT_OES
    GLenum driverType = type.get();
    if (gl->IsGLES() && type == LOCAL_GL_HALF_FLOAT) {
        driverType = LOCAL_GL_HALF_FLOAT_OES;
    }

    // driverFormat: always just the unsized internalformat that we just got
    GLenum driverFormat = unsizedinternalformat.get();

    // driverInternalFormat: almost always the same as driverFormat, but on desktop GL,
    // in some cases we must pass a different value. On ES, they are equal by definition
    // as it is an error to pass internalformat!=format.
    GLenum driverInternalFormat = driverFormat;
    if (!gl->IsGLES()) {
        // Cases where desktop OpenGL requires a tweak to 'format'
        if (driverFormat == LOCAL_GL_SRGB) {
            driverFormat = LOCAL_GL_RGB;
        } else if (driverFormat == LOCAL_GL_SRGB_ALPHA) {
            driverFormat = LOCAL_GL_RGBA;
        }

        // WebGL2's new formats are not legal values for internalformat,
        // as using unsized internalformat is deprecated.
        if (driverFormat == LOCAL_GL_RED ||
            driverFormat == LOCAL_GL_RG ||
            driverFormat == LOCAL_GL_RED_INTEGER ||
            driverFormat == LOCAL_GL_RG_INTEGER ||
            driverFormat == LOCAL_GL_RGB_INTEGER ||
            driverFormat == LOCAL_GL_RGBA_INTEGER)
        {
            driverInternalFormat = effectiveinternalformat.get();
        }

        // Cases where desktop OpenGL requires a sized internalformat,
        // as opposed to the unsized internalformat that had the same
        // GLenum value as 'format', in order to get the precise
        // semantics that we want. For example, for floating-point formats,
        // we seem to need a sized internalformat to get non-clamped floating
        // point texture sampling. Can't find the spec reference for that,
        // but that's at least the case on my NVIDIA driver version 331.
        if (unsizedinternalformat == LOCAL_GL_DEPTH_COMPONENT ||
            unsizedinternalformat == LOCAL_GL_DEPTH_STENCIL ||
            type == LOCAL_GL_FLOAT ||
            type == LOCAL_GL_HALF_FLOAT)
        {
            driverInternalFormat = effectiveinternalformat.get();
        }
    }

    *out_driverInternalFormat = driverInternalFormat;
    *out_driverFormat = driverFormat;
    *out_driverType = driverType;
}
Beispiel #2
0
/**
 * Convert WebGL/ES format and type into GL internal
 * format valid for underlying driver.
 */
void
DriverFormatsFromFormatAndType(GLContext* gl, TexInternalFormat webGLInternalFormat, TexType webGLType,
                               GLenum* out_driverInternalFormat, GLenum* out_driverFormat)
{
    MOZ_ASSERT(out_driverInternalFormat);
    MOZ_ASSERT(out_driverFormat);

    // ES2 requires that format == internalformat; floating-point is
    // indicated purely by the type that's loaded.  For desktop GL, we
    // have to specify a floating point internal format.
    if (gl->IsGLES()) {
        *out_driverFormat = *out_driverInternalFormat = webGLInternalFormat.get();
        return;
    }

    GLenum internalFormat = LOCAL_GL_NONE;
    GLenum format = LOCAL_GL_NONE;

    if (webGLInternalFormat == LOCAL_GL_DEPTH_COMPONENT) {
        format = LOCAL_GL_DEPTH_COMPONENT;
        if (webGLType == LOCAL_GL_UNSIGNED_SHORT)
            internalFormat = LOCAL_GL_DEPTH_COMPONENT16;
        else if (webGLType == LOCAL_GL_UNSIGNED_INT)
            internalFormat = LOCAL_GL_DEPTH_COMPONENT32;
    } else if (webGLInternalFormat == LOCAL_GL_DEPTH_STENCIL) {
        format = LOCAL_GL_DEPTH_STENCIL;
        if (webGLType == LOCAL_GL_UNSIGNED_INT_24_8_EXT)
            internalFormat = LOCAL_GL_DEPTH24_STENCIL8;
    } else {
        switch (webGLType.get()) {
        case LOCAL_GL_UNSIGNED_BYTE:
        case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
        case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
        case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
            format = internalFormat = webGLInternalFormat.get();
            break;

        case LOCAL_GL_FLOAT:
            switch (webGLInternalFormat.get()) {
            case LOCAL_GL_RGBA:
                format = LOCAL_GL_RGBA;
                internalFormat = LOCAL_GL_RGBA32F;
                break;

            case LOCAL_GL_RGB:
                format = LOCAL_GL_RGB;
                internalFormat = LOCAL_GL_RGB32F;
                break;

            case LOCAL_GL_ALPHA:
                format = LOCAL_GL_ALPHA;
                internalFormat = LOCAL_GL_ALPHA32F_ARB;
                break;

            case LOCAL_GL_LUMINANCE:
                format = LOCAL_GL_LUMINANCE;
                internalFormat = LOCAL_GL_LUMINANCE32F_ARB;
                break;

            case LOCAL_GL_LUMINANCE_ALPHA:
                format = LOCAL_GL_LUMINANCE_ALPHA;
                internalFormat = LOCAL_GL_LUMINANCE_ALPHA32F_ARB;
                break;
            }
            break;

        case LOCAL_GL_HALF_FLOAT_OES:
            switch (webGLInternalFormat.get()) {
            case LOCAL_GL_RGBA:
                format = LOCAL_GL_RGBA;
                internalFormat = LOCAL_GL_RGBA16F;
                break;

            case LOCAL_GL_RGB:
                format = LOCAL_GL_RGB;
                internalFormat = LOCAL_GL_RGB16F;
                break;

            case LOCAL_GL_ALPHA:
                format = LOCAL_GL_ALPHA;
                internalFormat = LOCAL_GL_ALPHA16F_ARB;
                break;

            case LOCAL_GL_LUMINANCE:
                format = LOCAL_GL_LUMINANCE;
                internalFormat = LOCAL_GL_LUMINANCE16F_ARB;
                break;

            case LOCAL_GL_LUMINANCE_ALPHA:
                format = LOCAL_GL_LUMINANCE_ALPHA;
                internalFormat = LOCAL_GL_LUMINANCE_ALPHA16F_ARB;
                break;
            }
            break;

        default:
            break;
        }

        // Handle ES2 and GL differences when supporting sRGB internal formats. GL ES
        // requires that format == internalformat, but GL will fail in this case.
        // GL requires:
        //      format  ->  internalformat
        //      GL_RGB      GL_SRGB_EXT
        //      GL_RGBA     GL_SRGB_ALPHA_EXT
        switch (webGLInternalFormat.get()) {
        case LOCAL_GL_SRGB:
            format = LOCAL_GL_RGB;
            internalFormat = LOCAL_GL_SRGB;
            break;
        case LOCAL_GL_SRGB_ALPHA:
            format = LOCAL_GL_RGBA;
            internalFormat = LOCAL_GL_SRGB_ALPHA;
            break;
        }
    }

    MOZ_ASSERT(webGLInternalFormat != LOCAL_GL_NONE && internalFormat != LOCAL_GL_NONE,
               "Coding mistake -- bad format/type passed?");

    *out_driverInternalFormat = internalFormat;
    *out_driverFormat = format;
}