GLenum DriverTypeFromType(GLContext* gl, TexType webGLType) { GLenum type = webGLType.get(); if (gl->IsGLES()) return type; // convert type for half float if not on GLES2 if (type == LOCAL_GL_HALF_FLOAT_OES) { if (gl->IsSupported(gl::GLFeature::texture_half_float)) { return LOCAL_GL_HALF_FLOAT; } else { MOZ_ASSERT(gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float)); } } return type; }
/** * 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; }
/** * 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; }