diff --git a/contrib/single_file_transcoder/README.md b/contrib/single_file_transcoder/README.md index 95f6ae9..d082120 100644 --- a/contrib/single_file_transcoder/README.md +++ b/contrib/single_file_transcoder/README.md @@ -16,4 +16,4 @@ Why? Because all it now takes to support Basis Universal is the addition of a single file, two if using the header, with no configuration or further build steps. -The library is small, adding, for example, 181kB to an Emscripten compiled WebAssembly project (with transcoding disabled for BC7, ASTC and ATC). +The library is small, adding, for example, 181kB to an Emscripten compiled WebAssembly project (with transcoding disabled for BC7, ASTC and ATC; reenabling ASTC adds a further 64kB). diff --git a/contrib/single_file_transcoder/basisutranslib-in.cpp b/contrib/single_file_transcoder/basisutranslib-in.cpp index a684ea6..d5c5dff 100644 --- a/contrib/single_file_transcoder/basisutranslib-in.cpp +++ b/contrib/single_file_transcoder/basisutranslib-in.cpp @@ -4,9 +4,9 @@ * ./combine.sh -r ../../transcoder -o basisutranslib.cpp basisutranslib-in.cpp * \endcode * - * \todo -Wunused-parameter errors when removing BASISD_SUPPORT_ETC2_EAC_A8 - * \todo enable and test BASISD_SUPPORT_ASTC in browsers - * \todo BASISD_SUPPORT_DXT5A needs enabling for BC3? + * \note BASISD_SUPPORT_DXT5A needs enabling for BC3 + * + * \todo remove the need for -Wno-pragma-once-outside-header when compiling standalone */ /* @@ -21,8 +21,46 @@ #endif #if TARGET_OS_IPHONE || defined(__EMSCRIPTEN__) #define BASISD_SUPPORT_BC7 0 -#define BASISD_SUPPORT_ASTC 0 #define BASISD_SUPPORT_ATC 0 #endif #include "basisu_transcoder.cpp" + +/** + * Collection of unused functions and const variables to work around \c + * -Wunused-function and \c -Wunused-const-variable warnings. + * + * \todo LTO does its thing so any unused are removed but is there a better way? + */ +void _basisu_translib_dummy() { + // These first ones are not used at all + BASISU_NOTE_UNUSED(basisu::byteswap16); + BASISU_NOTE_UNUSED(basisu::byteswap32); + BASISU_NOTE_UNUSED(basisu::BASISU_PATH_SEPERATOR_CHAR); + BASISU_NOTE_UNUSED(basisu::cHuffmanTotalSortedCodelengthCodes); + BASISU_NOTE_UNUSED(basist::COLOR5_PAL0_DELTA_LO); + BASISU_NOTE_UNUSED(basist::COLOR5_PAL0_DELTA_HI); + BASISU_NOTE_UNUSED(basist::COLOR5_PAL1_DELTA_LO); + BASISU_NOTE_UNUSED(basist::COLOR5_PAL1_DELTA_HI); + BASISU_NOTE_UNUSED(basist::COLOR5_PAL2_DELTA_LO); + BASISU_NOTE_UNUSED(basist::COLOR5_PAL2_DELTA_HI); + BASISU_NOTE_UNUSED(basist::COLOR5_PAL2_PREV_HI); + BASISU_NOTE_UNUSED(basist::COLOR5_PAL_MIN_DELTA_B_RUNLEN); + BASISU_NOTE_UNUSED(basist::COLOR5_PAL_DELTA_5_RUNLEN_VLC_BITS); + BASISU_NOTE_UNUSED(basist::NO_ENDPOINT_PRED_INDEX); + BASISU_NOTE_UNUSED(basist::MAX_SELECTOR_HISTORY_BUF_SIZE); +#if BASISD_SUPPORT_ETC2_EAC_A8 + // Unused but only when building with EAC + BASISU_NOTE_UNUSED(basist::g_eac_a8_modifier_table); +#endif +#if BASISD_SUPPORT_PVRTC1 + // Unused but only when building with PVRTC + BASISU_NOTE_UNUSED(basist::g_pvrtc_bilinear_weights); +#else + // Unused only when not building with PVRTC + BASISU_NOTE_UNUSED(basist::g_etc1_inten_tables16); + BASISU_NOTE_UNUSED(basist::g_etc1_inten_tables48); + BASISU_NOTE_UNUSED(basist::g_etc_5_to_8); + BASISU_NOTE_UNUSED(basist::g_etc1_x_selector_unpack); +#endif +} diff --git a/contrib/single_file_transcoder/examples/emscripten.cpp b/contrib/single_file_transcoder/examples/emscripten.cpp index dc82f14..dd20ea2 100644 --- a/contrib/single_file_transcoder/examples/emscripten.cpp +++ b/contrib/single_file_transcoder/examples/emscripten.cpp @@ -9,8 +9,10 @@ * export EM_FLAGS="-s ENVIRONMENT=web -s WASM=1 --shell-file shell.html --closure 1" * emcc $CC_FLAGS $EM_FLAGS -o out.html emscripten.cpp * \endcode - * - * Released under a CC0 license. + * Alternatively include the transcoder header and build \c basisutranslib + * separately (the resulting binary is exactly the same size). + * \n + * Example code released under a CC0 license. */ #include @@ -899,14 +901,21 @@ struct posTex2d { /* * Possibly missing GL enums. + * + * Note: GL_COMPRESSED_RGB_ETC1_WEBGL is the same as GL_ETC1_RGB8_OES */ +#ifndef GL_ETC1_RGB8_OES +#define GL_ETC1_RGB8_OES 0x8D64 +#endif #ifndef GL_COMPRESSED_RGB8_ETC2 #define GL_COMPRESSED_RGB8_ETC2 0x9274 #endif - #ifndef GL_COMPRESSED_RGBA8_ETC2_EAC #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 #endif +#ifndef COMPRESSED_RGBA_ASTC_4x4_KHR +#define COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#endif //***************************** Basis Universal /*****************************/ @@ -932,9 +941,12 @@ static etc1_global_selector_codebook* globalCodebook = NULL; * \return corresponding Basis format */ static transcoder_texture_format supports(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE const ctx, bool const alpha) { +#if BASISD_SUPPORT_PVRTC1 || !defined(BASISD_SUPPORT_PVRTC1) /* * Test for both prefixed and non-prefixed versions. This should grab iOS * and other ImgTec GPUs first as a preference. + * + * TODO: do older iOS expose ASTC to the browser and does it transcode to RGBA? */ static bool const pvr = GL_HAS_EXT(ctx, "WEBKIT_WEBGL_compressed_texture_pvrtc") || GL_HAS_EXT(ctx, "WEBGL_compressed_texture_pvrtc"); @@ -943,41 +955,68 @@ static transcoder_texture_format supports(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE const ? cTFPVRTC1_4_RGBA // 9 : cTFPVRTC1_4_RGB; // 8 } +#endif +#if BASISD_SUPPORT_ASTC || !defined(BASISD_SUPPORT_ASTC) + /* + * Then Android, ChromeOS and others with ASTC (newer iOS devices should + * make the list but don't appear to be exposed). + */ + static bool const astc = GL_HAS_EXT(ctx, "WEBGL_compressed_texture_astc"); + if (astc) { + //return cTFASTC_4x4; // 10 + } +#endif +#if BASISD_SUPPORT_DXT1 || !defined(BASISD_SUPPORT_DXT1) /* * We choose DXT next, since a worry is the browser will claim ETC support - * then transcode (transcoding slower and with more artefacts) + * then transcode (transcoding slower and with more artefacts). This gives + * us desktop and various (usually Intel) Android devices. */ - static bool const dxt = GL_HAS_EXT(ctx, "WEBGL_compressed_texture_s3tc"); + static bool const dxt = GL_HAS_EXT(ctx, "WEBGL_compressed_texture_s3tc") + || GL_HAS_EXT(ctx, "WEBKIT_WEBGL_compressed_texture_s3tc"); if (dxt) { return (alpha) ? cTFBC3 // 3 : cTFBC1; // 2 } +#endif /* - * Finally ETC then falling back on RGB. + * Then ETC2 (which may be incorrect). */ - static bool const etc = GL_HAS_EXT(ctx, "WEBGL_compressed_texture_etc"); - if (etc) { + static bool const etc2 = GL_HAS_EXT(ctx, "WEBGL_compressed_texture_etc"); + if (etc2) { return (alpha) ? cTFETC2 // 1 : cTFETC1; // 0 } + /* + * Finally ETC1, falling back on RGBA. + * + * TODO: we might just prefer to transcode to dithered 565 once available + */ + static bool const etc1 = GL_HAS_EXT(ctx, "WEBGL_compressed_texture_etc1"); + if (etc1 && !alpha) { + return cTFETC1; // 0 + } /* * We choose 8888 over 4444 and 565 (in the hope that is is never chosen). */ - return cTFRGBA32; + return cTFRGBA32; // 13 } /** * Returns the equivalent GL type given a BasisU type. * + * \note This relies on \c #supports() returning the supported formats, and so + * only converts to the GL equivalents (without further testing for support). + * * \param[in] type BasisU transcode target * \return equivalent GL type */ static GLenum toGlType(transcoder_texture_format const type) { switch (type) { case cTFETC1: - return GL_COMPRESSED_RGB8_ETC2; + return GL_ETC1_RGB8_OES; case cTFETC2: return GL_COMPRESSED_RGBA8_ETC2_EAC; case cTFBC1: @@ -988,6 +1027,8 @@ static GLenum toGlType(transcoder_texture_format const type) { return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; case cTFPVRTC1_4_RGBA: return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + case cTFASTC_4x4: + return GL_COMPRESSED_RGBA_ASTC_4x4_KHR; case cTFRGBA32: return GL_UNSIGNED_BYTE; case cTFRGB565: @@ -1017,6 +1058,7 @@ bool upload(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE const ctx, GLuint const name, const basisu_file_info fileInfo; if (transcoder.get_file_info(data, size, fileInfo)) { transcoder_texture_format type = supports(ctx, fileInfo.m_has_alpha_slices); + printf("Type enum: %d\n", type); basisu_image_info info; if (transcoder.get_image_info(data, size, info, 0)) { uint32_t descW, descH, blocks;