From f6f84267b67ba6f6015ad82eb07e6736b3c6eb4e Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sat, 7 Feb 2026 18:50:18 +0800 Subject: [PATCH 01/12] [Feat] (workflow): merge two workflows --- .github/workflows/build.yml | 136 ++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..65fa8487 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,136 @@ +name: Build-Test-Benchmark + +on: + push: + branches: + - dev + - Feat/Backend-Direct-GLES + +jobs: + build: + runs-on: ubuntu-latest + env: + BUILD_ROOT: ${{github.workspace}} + BUILD_TYPE: ${{ secrets.ACTIONS_STEP_DEBUG == 'true' && 'Debug' || 'Release' }} + + steps: + - name: Set Swap Space + uses: pierotofy/set-swap-space@master + with: + swap-size-gb: 32 + + - name: Checkout repo + uses: actions/checkout@v4 + with: + submodules: true + + - name: Get CMake + uses: lukka/get-cmake@latest + + - name: Update glslang external sources + working-directory: ${{env.BUILD_ROOT}}/3rdparty/glslang + run: python update_glslang_sources.py + + - name: Install clang-20 + run: | + sudo apt-get update + sudo apt-get install -y clang-20 clang++-20 lld-20 libc++-20-dev libc++abi-20-dev + + - name: Show installed toolchain + run: | + clang-20 --version + clang++-20 --version + ld.lld-20 --version || ld.lld --version || true + dpkg -l 'libc++*' || true + + - name: Configure CMake + working-directory: ${{env.BUILD_ROOT}} + run: | + cmake -S . -B build-ci -G Ninja -DCMAKE_C_COMPILER=clang-20 -DCMAKE_CXX_COMPILER=clang++-20 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON -DBENCHMARK_ENABLE_TESTING=OFF -DMOBILEGL_BUILD_TEST=ON -DMOBILEGL_BUILD_BENCHMARK=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + + - name: Build + working-directory: ${{env.BUILD_ROOT}}/build-ci + run: cmake --build . + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: build-ci + path: ${{env.BUILD_ROOT}}/build-ci + + test: + runs-on: ubuntu-latest + needs: build + env: + TEST_ROOT: ${{github.workspace}} + BUILD_TYPE: ${{ secrets.ACTIONS_STEP_DEBUG == 'true' && 'Debug' || 'Release' }} + + steps: + - name: Set Swap Space + uses: pierotofy/set-swap-space@master + with: + swap-size-gb: 32 + + - name: Checkout repo + uses: actions/checkout@v4 + with: + submodules: true + + - name: Get CMake + uses: lukka/get-cmake@latest + + - name: Install clang-20 + run: | + sudo apt-get update + sudo apt-get install -y clang-20 clang++-20 lld-20 libc++-20-dev libc++abi-20-dev + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-ci + path: ${{env.TEST_ROOT}}/build-ci + + - name: Test + working-directory: ${{env.TEST_ROOT}}/build-ci/MobileGL/MG_Test + run: | + if [ "${{ secrets.ACTIONS_STEP_DEBUG }}" == "true" ]; then + ctest -V + else + ctest + fi + + benchmark: + runs-on: ubuntu-latest + needs: build + env: + BENCH_ROOT: ${{github.workspace}} + BUILD_TYPE: ${{ secrets.ACTIONS_STEP_DEBUG == 'true' && 'Debug' || 'Release' }} + + steps: + - name: Set Swap Space + uses: pierotofy/set-swap-space@master + with: + swap-size-gb: 32 + + - name: Checkout repo + uses: actions/checkout@v4 + with: + submodules: true + + - name: Get CMake + uses: lukka/get-cmake@latest + + - name: Install clang-20 + run: | + sudo apt-get update + sudo apt-get install -y clang-20 clang++-20 lld-20 libc++-20-dev libc++abi-20-dev + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-ci + path: ${{env.BENCH_ROOT}}/build-ci + + - name: Benchmark + working-directory: ${{env.BENCH_ROOT}}/build-ci/MobileGL/MG_Benchmark + run: ctest -V -C ${{env.BUILD_TYPE}} From a079e5e6b97dc696c989f1ef53f18dda421543bf Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sat, 7 Feb 2026 19:15:45 +0800 Subject: [PATCH 02/12] [Debug] (workflow): checking inter-job artifact exchange --- .github/workflows/build.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 65fa8487..3f34f8bf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -92,12 +92,29 @@ jobs: - name: Test working-directory: ${{env.TEST_ROOT}}/build-ci/MobileGL/MG_Test + continue-on-error: true run: | if [ "${{ secrets.ACTIONS_STEP_DEBUG }}" == "true" ]; then ctest -V else ctest fi + echo "CTEST_EXIT=$?" >> $GITHUB_ENV + + - name: Rerun failed tests with output + if: always() + working-directory: ${{env.TEST_ROOT}}/build-ci/MobileGL/MG_Test + run: | + ctest --rerun-failed --output-on-failure || true + + - name: Show LastTest.log + if: always() + run: | + cat "${{env.TEST_ROOT}}/build-ci/MobileGL/MG_Test/Testing/Temporary/LastTest.log" || true + + - name: Fail if tests failed + if: ${{ env.CTEST_EXIT != '' && env.CTEST_EXIT != '0' }} + run: exit ${{ env.CTEST_EXIT }} benchmark: runs-on: ubuntu-latest From 40333fa84ac19e91ac8cc58a554f6da5bd3554ca Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sat, 7 Feb 2026 20:06:43 +0800 Subject: [PATCH 03/12] [Remove] (workflow): remove combined workflow --- .github/workflows/build.yml | 153 ------------------------------------ 1 file changed, 153 deletions(-) delete mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 3f34f8bf..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,153 +0,0 @@ -name: Build-Test-Benchmark - -on: - push: - branches: - - dev - - Feat/Backend-Direct-GLES - -jobs: - build: - runs-on: ubuntu-latest - env: - BUILD_ROOT: ${{github.workspace}} - BUILD_TYPE: ${{ secrets.ACTIONS_STEP_DEBUG == 'true' && 'Debug' || 'Release' }} - - steps: - - name: Set Swap Space - uses: pierotofy/set-swap-space@master - with: - swap-size-gb: 32 - - - name: Checkout repo - uses: actions/checkout@v4 - with: - submodules: true - - - name: Get CMake - uses: lukka/get-cmake@latest - - - name: Update glslang external sources - working-directory: ${{env.BUILD_ROOT}}/3rdparty/glslang - run: python update_glslang_sources.py - - - name: Install clang-20 - run: | - sudo apt-get update - sudo apt-get install -y clang-20 clang++-20 lld-20 libc++-20-dev libc++abi-20-dev - - - name: Show installed toolchain - run: | - clang-20 --version - clang++-20 --version - ld.lld-20 --version || ld.lld --version || true - dpkg -l 'libc++*' || true - - - name: Configure CMake - working-directory: ${{env.BUILD_ROOT}} - run: | - cmake -S . -B build-ci -G Ninja -DCMAKE_C_COMPILER=clang-20 -DCMAKE_CXX_COMPILER=clang++-20 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON -DBENCHMARK_ENABLE_TESTING=OFF -DMOBILEGL_BUILD_TEST=ON -DMOBILEGL_BUILD_BENCHMARK=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5 - - - name: Build - working-directory: ${{env.BUILD_ROOT}}/build-ci - run: cmake --build . - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: build-ci - path: ${{env.BUILD_ROOT}}/build-ci - - test: - runs-on: ubuntu-latest - needs: build - env: - TEST_ROOT: ${{github.workspace}} - BUILD_TYPE: ${{ secrets.ACTIONS_STEP_DEBUG == 'true' && 'Debug' || 'Release' }} - - steps: - - name: Set Swap Space - uses: pierotofy/set-swap-space@master - with: - swap-size-gb: 32 - - - name: Checkout repo - uses: actions/checkout@v4 - with: - submodules: true - - - name: Get CMake - uses: lukka/get-cmake@latest - - - name: Install clang-20 - run: | - sudo apt-get update - sudo apt-get install -y clang-20 clang++-20 lld-20 libc++-20-dev libc++abi-20-dev - - - name: Download build artifacts - uses: actions/download-artifact@v4 - with: - name: build-ci - path: ${{env.TEST_ROOT}}/build-ci - - - name: Test - working-directory: ${{env.TEST_ROOT}}/build-ci/MobileGL/MG_Test - continue-on-error: true - run: | - if [ "${{ secrets.ACTIONS_STEP_DEBUG }}" == "true" ]; then - ctest -V - else - ctest - fi - echo "CTEST_EXIT=$?" >> $GITHUB_ENV - - - name: Rerun failed tests with output - if: always() - working-directory: ${{env.TEST_ROOT}}/build-ci/MobileGL/MG_Test - run: | - ctest --rerun-failed --output-on-failure || true - - - name: Show LastTest.log - if: always() - run: | - cat "${{env.TEST_ROOT}}/build-ci/MobileGL/MG_Test/Testing/Temporary/LastTest.log" || true - - - name: Fail if tests failed - if: ${{ env.CTEST_EXIT != '' && env.CTEST_EXIT != '0' }} - run: exit ${{ env.CTEST_EXIT }} - - benchmark: - runs-on: ubuntu-latest - needs: build - env: - BENCH_ROOT: ${{github.workspace}} - BUILD_TYPE: ${{ secrets.ACTIONS_STEP_DEBUG == 'true' && 'Debug' || 'Release' }} - - steps: - - name: Set Swap Space - uses: pierotofy/set-swap-space@master - with: - swap-size-gb: 32 - - - name: Checkout repo - uses: actions/checkout@v4 - with: - submodules: true - - - name: Get CMake - uses: lukka/get-cmake@latest - - - name: Install clang-20 - run: | - sudo apt-get update - sudo apt-get install -y clang-20 clang++-20 lld-20 libc++-20-dev libc++abi-20-dev - - - name: Download build artifacts - uses: actions/download-artifact@v4 - with: - name: build-ci - path: ${{env.BENCH_ROOT}}/build-ci - - - name: Benchmark - working-directory: ${{env.BENCH_ROOT}}/build-ci/MobileGL/MG_Benchmark - run: ctest -V -C ${{env.BUILD_TYPE}} From b90df42a4558e1b5480635d160d2f6e36525999c Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sat, 7 Feb 2026 23:10:11 +0800 Subject: [PATCH 04/12] [Feat] (MG_Util/Texture, MG_Backend/DirectGLES): implementing BGRA texture readback (WIP) --- MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp | 50 ++++++++++++++++--- .../MG_Util/Texture/PixelStoreProcessor.cpp | 45 +++++++++++------ .../MG_Util/Texture/PixelStoreProcessor.h | 5 +- 3 files changed, 77 insertions(+), 23 deletions(-) diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index 6878eac9..eb26c12b 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -25,6 +25,7 @@ #include #include #include +#include namespace MobileGL::MG_Backend::DirectGLES { enum class DrawSyncBit : Uint32 { @@ -1322,19 +1323,28 @@ namespace MobileGL::MG_Backend::DirectGLES { } void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels) { + DebugImpl::ErrorLopper errorLopper; MGLOG_D("GetTexImage: target=%s level=%d format=%s type=%s pixels=%p", MG_Util::ConvertGLEnumToString(target).c_str(), level, MG_Util::ConvertGLEnumToString(format).c_str(), MG_Util::ConvertGLEnumToString(type).c_str(), pixels); - MOBILEGL_ASSERT(format == GL_RGBA || format == GL_RGBA_INTEGER, - "Only GL_RGBA and GL_RGBA_INTEGER are supported currently, while requested %s.", + MOBILEGL_ASSERT(format == GL_RGBA || format == GL_RGBA_INTEGER || format == GL_BGRA, + "Only GL_RGBA, GL_RGBA_INTEGER and GL_BGRA are supported currently, while requested %s.", MG_Util::ConvertGLEnumToString(format).c_str()); MOBILEGL_ASSERT(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT || type == GL_UNSIGNED_INT_2_10_10_10_REV || - type == GL_INT || type == GL_FLOAT, + type == GL_INT || type == GL_FLOAT || + type == GL_UNSIGNED_INT_8_8_8_8 || type == GL_UNSIGNED_INT_8_8_8_8_REV, "Only GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, GL_UNSIGNED_INT_2_10_10_10_REV, " - "GL_INT and GL_FLOAT are supported currently, while requested %s.", + "GL_INT, GL_FLOAT, GL_UNSIGNED_INT_8_8_8_8 and GL_UNSIGNED_INT_8_8_8_8_REV " + "are supported currently, while requested %s.", MG_Util::ConvertGLEnumToString(type).c_str()); + GLenum esFormat = format, esType = type; + if (esFormat == GL_BGRA) + esFormat = GL_RGBA; + if (esType == GL_UNSIGNED_INT_8_8_8_8 || esType == GL_UNSIGNED_INT_8_8_8_8_REV) + esType = GL_UNSIGNED_BYTE; + MGLOG_D("GetTexImage: SyncNeccessaryTextures()"); TextureImpl::SyncNeccessaryTextures(); @@ -1380,14 +1390,21 @@ namespace MobileGL::MG_Backend::DirectGLES { return; } + errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { + MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); + }); + MGLOG_D("GetTexImage: Applying TempPixelStoreParameterSync (PACK)"); TempPixelStoreParameterSync tempPackParamsSync(false); + errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { + MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); + }); + const auto& storageType = textureObject->GetStorageType(); MGLOG_D("GetTexImage: texture storage type = %d", (int)storageType); if (storageType == TextureStorageType::Buffer) { - MGLOG_E("GetTexImage: Texture storage type Buffer is not supported."); MGLOG_E("GetTexImage: Texture storage type Buffer is not supported."); return; } @@ -1432,8 +1449,17 @@ namespace MobileGL::MG_Backend::DirectGLES { usePBO = false; MGLOG_D("GetTexImage: Not using PBO"); } - MGLOG_D("GetTexImage: glReadPixels()"); - MG_External::GLES::glReadPixels(0, 0, size.x(), size.y(), format, type, pixels); + + errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { + MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); + }); + MGLOG_D("GetTexImage: glReadPixels(0, 0, %d, %d, %s, %s, %p)", size.x(), size.y(), + MG_Util::ConvertGLEnumToString(esFormat).c_str(), MG_Util::ConvertGLEnumToString(esType).c_str(), pixels); + MG_External::GLES::glReadPixels(0, 0, size.x(), size.y(), esFormat, esType, pixels); + + errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { + MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); + }); if (usePBO) { // pull back to client memory if PBO is used MGLOG_D("ReadPixels: PBO used, mapping buffer to client memory"); @@ -1448,12 +1474,20 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_External::GLES::glUnmapBuffer(GL_PIXEL_PACK_BUFFER); } else { MGLOG_E("ReadPixels: glMapBufferRange returned nullptr"); - MGLOG_E("ReadPixels: glMapBufferRange returned nullptr"); } MGLOG_D("ReadPixels: Restoring previous pixel pack buffer binding %u", prevPixelPackBuffer); MG_External::GLES::glBindBuffer(GL_PIXEL_PACK_BUFFER, prevPixelPackBuffer); + } else { + if (esFormat == GL_RGBA && format == GL_BGRA && esType == GL_UNSIGNED_BYTE && type == GL_UNSIGNED_INT_8_8_8_8_REV) { + MGLOG_D("ReadPixels: ProcessColorSwizzle BGRA (not implemented)"); + + } } + + errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { + MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); + }); MGLOG_D("GetTexImage: finished"); } diff --git a/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp b/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp index 6092914f..74c532fe 100644 --- a/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp +++ b/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp @@ -72,7 +72,7 @@ namespace MobileGL::MG_Util::PixelStoreProcessor { // assume 8 bit per channel // swizzle.size() == channel count - static void ProcessColorSwizzle(void* data, SizeT pixelCount, const Vector& swizzle) { + void ProcessColorSwizzle(void* data, SizeT pixelCount, const Vector& swizzle) { const auto bpp = swizzle.size(); Uint8* bytes = static_cast(data); Uint8 pixelScratch[4]; @@ -172,22 +172,25 @@ namespace MobileGL::MG_Util::PixelStoreProcessor { return outputPixels; } - void* ProcessTexturePixelsDataPack(const void* inputPixels, const PixelStoreParameters& params, SizeT pixelSize, + void* ProcessTexturePixelsDataPack(const void* inputPixels, const PixelStoreParameters& params, + TextureInternalFormat srcInternalFormat, TexturePixelDataType srcDataType, + TextureInputFormat dstInputFormat, TexturePixelDataType dstDataType, IntVec3 dimension, Bool isBitmap, SizeT& outSize) { - if (pixelSize == 0) { - outSize = 0; - return nullptr; - } + const SizeT pixelSize = MG_Util::GetInternalBytesPerPixel(srcInternalFormat, srcDataType); Int width = dimension.x(); Int height = dimension.y(); Int depth = dimension.z(); - const Int outputWidth = (params.RowLength > 0) ? params.RowLength : width; - const SizeT outputRowStride = CalculateRowStride(outputWidth, pixelSize, params.Alignment); - const SizeT inputRowStride = static_cast(width) * pixelSize; + if (pixelSize == 0) { + outSize = 0; + return nullptr; + } - const Int effectiveHeight = (params.ImageHeight > 0) ? params.ImageHeight : height; + // TODO: take care of PixelStoreParameters + const SizeT outputRowStride = width * pixelSize; + const Int effectiveHeight = height; + const SizeT inputRowStride = outputRowStride; outSize = static_cast(outputRowStride) * static_cast(effectiveHeight) * static_cast(depth); void* outputPixels = malloc(outSize); @@ -201,12 +204,22 @@ namespace MobileGL::MG_Util::PixelStoreProcessor { const Uint8* src = static_cast(inputPixels); Uint8* dst = static_cast(outputPixels); - dst += static_cast(params.SkipImages) * static_cast(effectiveHeight) * outputRowStride; - dst += static_cast(params.SkipRows) * outputRowStride; - dst += static_cast(params.SkipPixels) * pixelSize; - Vector tempRow(static_cast(width) * pixelSize); + bool needSwizzle = false; + static Vector swizzle; + swizzle = { TextureSwizzleParam::Red, TextureSwizzleParam::Green, + TextureSwizzleParam::Blue, TextureSwizzleParam::Alpha }; + if (srcInternalFormat == TextureInternalFormat::RGBA && dstInputFormat == TextureInputFormat::BGRA) { + swizzle = { TextureSwizzleParam::Blue, TextureSwizzleParam::Green, + TextureSwizzleParam::Red, TextureSwizzleParam::Alpha }; + needSwizzle = true; + } + if (dstDataType == TexturePixelDataType::UnsignedInt8888) { + std::reverse(swizzle.begin(), swizzle.end()); + needSwizzle = true; + } + for (Int z = 0; z < depth; ++z) { Uint8* layerDst = dst; const Uint8* layerSrc = src; @@ -222,6 +235,10 @@ namespace MobileGL::MG_Util::PixelStoreProcessor { ProcessLSBFirst(tempRow.data(), static_cast(width), 1); } + if (needSwizzle) { + ProcessColorSwizzle(tempRow.data(), static_cast(width), swizzle); + } + Memcpy(layerDst, tempRow.data(), static_cast(width) * pixelSize); layerSrc += inputRowStride; diff --git a/MobileGL/MG_Util/Texture/PixelStoreProcessor.h b/MobileGL/MG_Util/Texture/PixelStoreProcessor.h index d5fcbca2..32f4ba0d 100644 --- a/MobileGL/MG_Util/Texture/PixelStoreProcessor.h +++ b/MobileGL/MG_Util/Texture/PixelStoreProcessor.h @@ -17,6 +17,9 @@ namespace MobileGL::MG_Util::PixelStoreProcessor { TextureInternalFormat targetInternalFormat, TextureInputFormat textureInputFormat, TexturePixelDataType inputDataType, IntVec3 dimension, Bool isBitmap, SizeT& outSize); - void* ProcessTexturePixelsDataPack(const void* inputPixels, const PixelStoreParameters& params, SizeT pixelSize, + void* ProcessTexturePixelsDataPack(const void* inputPixels, const PixelStoreParameters& params, + TextureInternalFormat srcInternalFormat, TexturePixelDataType srcDataType, + TextureInputFormat dstInputFormat, TexturePixelDataType dstDataType, IntVec3 dimension, Bool isBitmap, SizeT& outSize); + void ProcessColorSwizzle(void* data, SizeT pixelCount, const Vector& swizzle); } // namespace MobileGL::MG_Util::PixelStoreProcessor From c4e40c2eb24856fc04f86afe7b23fa90e1424c57 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Tue, 17 Feb 2026 17:11:52 +0800 Subject: [PATCH 05/12] [Chore] (format): Update .clang-format --- .clang-format | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.clang-format b/.clang-format index 1c0cdc87..c07d66a4 100644 --- a/.clang-format +++ b/.clang-format @@ -9,16 +9,19 @@ BraceWrapping: AfterClass: false AfterControlStatement: Never AfterEnum: false - AfterNamespace: false - AfterStruct: false - AfterUnion: false - BeforeElse: false + AfterNamespace: false + AfterStruct: false + AfterUnion: false + BeforeElse: false SplitEmptyFunction: false SplitEmptyRecord: false -AllowShortBlocksOnASingleLine: Empty +AllowShortBlocksOnASingleLine: Empty AllowShortIfStatementsOnASingleLine: WithoutElse AlwaysBreakTemplateDeclarations: Yes NamespaceIndentation: All AllowShortFunctionsOnASingleLine: Inline SortIncludes: false +FixNamespaceComments: true +ShortNamespaceLines: 0 +CompactNamespaces: false From 5938a18131c29659c9cf8e260277e3497d390dbb Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Wed, 18 Feb 2026 10:35:04 +0800 Subject: [PATCH 06/12] [Chore] (Scripts): Upgrade clang-format --- scripts/format_code.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/format_code.sh b/scripts/format_code.sh index f2f7951c..eb3bff6e 100755 --- a/scripts/format_code.sh +++ b/scripts/format_code.sh @@ -18,7 +18,7 @@ cd "$(dirname "$0")" || { printf "%s\n" "Cannot cd to script dir"; exit 1; } DIR="../MobileGL" CLANG_FORMAT_CONFIG="../.clang-format" -CLANG_FORMAT_PATH="$(command -v clang-format-21 2>/dev/null || true)" +CLANG_FORMAT_PATH="$(command -v clang-format-23 2>/dev/null || true)" if [ -z "$CLANG_FORMAT_PATH" ]; then CLANG_FORMAT_PATH="$(command -v clang-format 2>/dev/null || true)" fi From fe89dc82dc172d0f3b9b27248b70188f23cf959a Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Wed, 18 Feb 2026 10:35:29 +0800 Subject: [PATCH 07/12] [Chore] (clang-tidy): Update .clang-tidy --- .clang-tidy | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 .clang-tidy diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 00000000..76055bbf --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,144 @@ +#Generated from CLion Inspection settings +--- +Checks: '-*, +bugprone-argument-comment, +bugprone-assert-side-effect, +bugprone-bad-signal-to-kill-thread, +bugprone-branch-clone, +bugprone-copy-constructor-init, +bugprone-dangling-handle, +bugprone-dynamic-static-initializers, +bugprone-fold-init-type, +bugprone-forward-declaration-namespace, +bugprone-forwarding-reference-overload, +bugprone-inaccurate-erase, +bugprone-incorrect-roundings, +bugprone-integer-division, +bugprone-lambda-function-name, +bugprone-macro-parentheses, +bugprone-macro-repeated-side-effects, +bugprone-misplaced-operator-in-strlen-in-alloc, +bugprone-misplaced-pointer-arithmetic-in-alloc, +bugprone-misplaced-widening-cast, +bugprone-move-forwarding-reference, +bugprone-multiple-statement-macro, +bugprone-no-escape, +bugprone-parent-virtual-call, +bugprone-posix-return, +bugprone-reserved-identifier, +bugprone-sizeof-container, +bugprone-sizeof-expression, +bugprone-spuriously-wake-up-functions, +bugprone-string-constructor, +bugprone-string-integer-assignment, +bugprone-string-literal-with-embedded-nul, +bugprone-suspicious-enum-usage, +bugprone-suspicious-include, +bugprone-suspicious-memset-usage, +bugprone-suspicious-missing-comma, +bugprone-suspicious-semicolon, +bugprone-suspicious-string-compare, +bugprone-suspicious-memory-comparison, +bugprone-suspicious-realloc-usage, +bugprone-swapped-arguments, +bugprone-terminating-continue, +bugprone-throw-keyword-missing, +bugprone-too-small-loop-variable, +bugprone-undefined-memory-manipulation, +bugprone-undelegated-constructor, +bugprone-unhandled-self-assignment, +bugprone-unused-raii, +bugprone-unused-return-value, +bugprone-use-after-move, +bugprone-virtual-near-miss, +cert-dcl21-cpp, +cert-dcl58-cpp, +cert-err34-c, +cert-err52-cpp, +cert-err60-cpp, +cert-flp30-c, +cert-msc50-cpp, +cert-msc51-cpp, +cert-str34-c, +cppcoreguidelines-interfaces-global-init, +cppcoreguidelines-narrowing-conversions, +cppcoreguidelines-pro-type-member-init, +cppcoreguidelines-pro-type-static-cast-downcast, +cppcoreguidelines-slicing, +google-default-arguments, +google-runtime-operator, +hicpp-exception-baseclass, +hicpp-multiway-paths-covered, +misc-misplaced-const, +misc-new-delete-overloads, +misc-non-copyable-objects, +misc-throw-by-value-catch-by-reference, +misc-unconventional-assign-operator, +misc-uniqueptr-reset-release, +modernize-avoid-bind, +modernize-concat-nested-namespaces, +modernize-deprecated-headers, +modernize-deprecated-ios-base-aliases, +modernize-loop-convert, +modernize-make-shared, +modernize-make-unique, +modernize-pass-by-value, +modernize-raw-string-literal, +modernize-redundant-void-arg, +modernize-replace-auto-ptr, +modernize-replace-disallow-copy-and-assign-macro, +modernize-replace-random-shuffle, +modernize-return-braced-init-list, +modernize-shrink-to-fit, +modernize-unary-static-assert, +modernize-use-auto, +modernize-use-bool-literals, +modernize-use-emplace, +modernize-use-equals-default, +modernize-use-equals-delete, +modernize-use-noexcept, +modernize-use-nullptr, +modernize-use-override, +modernize-use-transparent-functors, +modernize-use-uncaught-exceptions, +mpi-buffer-deref, +mpi-type-mismatch, +openmp-use-default-none, +performance-faster-string-find, +performance-for-range-copy, +performance-implicit-conversion-in-loop, +performance-inefficient-algorithm, +performance-inefficient-string-concatenation, +performance-inefficient-vector-operation, +performance-move-const-arg, +performance-move-constructor-init, +performance-no-automatic-move, +performance-noexcept-move-constructor, +performance-trivially-destructible, +performance-type-promotion-in-math-fn, +performance-unnecessary-copy-initialization, +performance-unnecessary-value-param, +portability-simd-intrinsics, +readability-avoid-const-params-in-decls, +readability-const-return-type, +readability-container-size-empty, +readability-convert-member-functions-to-static, +readability-delete-null-pointer, +readability-deleted-default, +readability-inconsistent-declaration-parameter-name, +readability-make-member-function-const, +readability-misleading-indentation, +readability-misplaced-array-index, +readability-non-const-parameter, +readability-redundant-control-flow, +readability-redundant-declaration, +readability-redundant-function-ptr-dereference, +readability-redundant-smartptr-get, +readability-redundant-string-cstr, +readability-redundant-string-init, +readability-simplify-subscript-expr, +readability-static-accessed-through-instance, +readability-static-definition-in-anonymous-namespace, +readability-string-compare, +readability-uniqueptr-delete-release, +readability-use-anyofallof' From 8413874e8239b2afa1c22779f0dc898e85172c13 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Wed, 18 Feb 2026 10:36:56 +0800 Subject: [PATCH 08/12] [Feat|Refactor] (MG_Backend|MG_Impl): Implement BackendObject, replacing previous methods. --- CMakeLists.txt | 6 +- MobileGL/Config.h | 28 +- MobileGL/Defines.h | 5 - MobileGL/GlobalObjects.cpp | 20 + MobileGL/Init.cpp | 5 +- .../BackendObject.cpp} | 11 +- MobileGL/MG_Backend/BackendObject.h | 108 + MobileGL/MG_Backend/BackendObjects.h | 19 + MobileGL/MG_Backend/Backends.h | 91 - .../DirectGLES/BackendObject_DirectGLES.cpp | 136 + .../DirectGLES/BackendObject_DirectGLES.h | 39 + MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp | 399 ++- MobileGL/MG_Backend/DirectGLES/DirectGLES.h | 12 +- MobileGL/MG_Backend/DirectGLES/Managers.cpp | 206 +- MobileGL/MG_Backend/DirectGLES/Utils.cpp | 6 +- MobileGL/MG_Backend/Init.cpp | 120 +- MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp | 253 ++ MobileGL/MG_Impl/EGLImpl/EGLImpl.h | 64 + .../MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.cpp | 218 -- .../MG_Impl/EGLImpl/Exporting/Definitions.cpp | 65 +- .../EGLImpl/Temporary/TemporaryEGLImpl.cpp | 195 -- .../EGLImpl/Temporary/TemporaryEGLImpl.h | 66 - .../MG_Impl/GLImpl/Drawing/GL_Drawing.cpp | 353 +- .../GLImpl/Framebuffer/GL_Framebuffer.cpp | 1291 ++++--- .../GLImpl/Framebuffer/GL_Framebuffer.h | 9 - MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp | 1748 +++++----- MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.h | 16 +- .../MG_Impl/GLImpl/Program/GL_Program.cpp | 16 +- .../MG_Impl/GLImpl/Texture/GL_Texture.cpp | 2951 ++++++++--------- MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.h | 124 +- MobileGL/MG_Impl/Init.cpp | 52 +- .../FramebufferState/FramebufferObject.cpp | 10 +- .../GLState/TextureState/TextureObject.h | 1 + .../MG_Util/BackendLoaders/OpenGL/Loader.cpp | 1662 ++++------ .../MG_Util/BackendLoaders/OpenGL/Loader.h | 1000 +++--- .../Converters/EGLToStr/EGLEnumConverter.h | 2 +- .../GLToGlslang/ProgramEnumConverter.h | 2 +- .../Converters/GLToMG/DataTypeConverter.h | 2 +- .../GLToMG/FramebufferEnumConverter.cpp | 32 +- .../Converters/GLToMG/ProgramEnumConverter.h | 2 +- .../Converters/GLToStr/GLEnumConverter.cpp | 4 +- .../Converters/GLToStr/GLEnumConverter.h | 2 +- .../Converters/MGToGL/DataTypeConverter.h | 2 +- .../Converters/MGToGL/ErrorCodeConverter.h | 2 +- .../MGToGL/FramebufferEnumConverter.cpp | 28 +- .../Converters/MGToGL/ProgramEnumConverter.h | 2 +- .../Converters/MGToStr/DataTypeConverter.h | 2 +- .../Converters/MGToStr/GLExtensionConverter.h | 2 +- MobileGL/MG_Util/Metrics/BufferMetrics.h | 2 +- .../MG_Util/Texture/PixelStoreProcessor.cpp | 8 +- .../MG_Util/Texture/TextureFormatProcessor.h | 2 +- MobileGL/MG_Util/Types.h | 8 +- 52 files changed, 5546 insertions(+), 5863 deletions(-) create mode 100644 MobileGL/GlobalObjects.cpp rename MobileGL/{MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.h => MG_Backend/BackendObject.cpp} (50%) create mode 100644 MobileGL/MG_Backend/BackendObject.h create mode 100644 MobileGL/MG_Backend/BackendObjects.h delete mode 100644 MobileGL/MG_Backend/Backends.h create mode 100644 MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp create mode 100644 MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.h create mode 100644 MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp create mode 100644 MobileGL/MG_Impl/EGLImpl/EGLImpl.h delete mode 100644 MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.cpp delete mode 100644 MobileGL/MG_Impl/EGLImpl/Temporary/TemporaryEGLImpl.cpp delete mode 100644 MobileGL/MG_Impl/EGLImpl/Temporary/TemporaryEGLImpl.h diff --git a/CMakeLists.txt b/CMakeLists.txt index fee592ff..cece4a2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,6 +122,7 @@ endif () set(SOURCE_FILES MobileGL/Init.cpp + MobileGL/GlobalObjects.cpp MobileGL/MG_Util/Debug/Log.cpp @@ -171,8 +172,7 @@ set(SOURCE_FILES MobileGL/MG_Impl/GLXImpl/LookUp/LookUp.cpp MobileGL/MG_Impl/EGLImpl/Exporting/Definitions.cpp - MobileGL/MG_Impl/EGLImpl/Temporary/TemporaryEGLImpl.cpp - MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.cpp + MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp # @INSERTION_POINT:SOURCE_FILE_GLIMPL@ # MobileGL/MG_Impl/GLImpl/Sampler/Validators.cpp @@ -197,8 +197,10 @@ set(SOURCE_FILES MobileGL/MG_Impl/GetProcAddress.cpp MobileGL/MG_Backend/Init.cpp + MobileGL/MG_Backend/BackendObject.cpp MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp + MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp MobileGL/MG_Backend/DirectGLES/Utils.cpp MobileGL/MG_Backend/DirectGLES/Managers.cpp diff --git a/MobileGL/Config.h b/MobileGL/Config.h index b80440a1..f9fec45d 100644 --- a/MobileGL/Config.h +++ b/MobileGL/Config.h @@ -8,24 +8,14 @@ #pragma once #include -#include +#include -namespace MobileGL { - namespace MG_Config { - inline const String ProjectName = "MobileGL"; - inline const String CoreName = "MobileGL Core"; - inline const String CoreVendor = "MobileGL-Dev (BZLZHH, Swung0x48, Tungsten)"; - inline const Version CoreVersion = {26, 2, 0, "-dev", VersionType::Development}; - inline const VersionStringFormatAttrib DefaultVersionStringFormatAttrib = {2, 2, 0, true, true}; - extern UniquePtr RendererInfoPtr; +namespace MobileGL::MG_Config { + inline const String ProjectName = "MobileGL"; + inline const String CoreName = "MobileGL Core"; + inline const String CoreVendor = "MobileGL-Dev (BZLZHH, Swung0x48, Tungsten)"; + inline const Version CoreVersion = {26, 2, 0, "-dev", VersionType::Development}; + inline const VersionStringFormatAttrib DefaultVersionStringFormatAttrib = {2, 2, 0, true, true}; - namespace Backend { -#define MOBILEGL_BACKEND MOBILEGL_BACKEND_TYPE_DIRECT_GLES - - namespace Diligent { - inline const MG_Backend::Diligent::SpecificBackendType SpecificBackend = - MG_Backend::Diligent::SpecificBackendType::Vulkan; - } - } // namespace Backend - } // namespace MG_Config -} // namespace MobileGL + extern BackendType ActiveBackendType; +} // namespace MobileGL::MG_Config diff --git a/MobileGL/Defines.h b/MobileGL/Defines.h index d7c5bd19..80c7366e 100644 --- a/MobileGL/Defines.h +++ b/MobileGL/Defines.h @@ -33,11 +33,6 @@ #define MOBILEGL_GL_API MOBILEGL_API #define MOBILEGL_EGL_API MOBILEGL_API -#define MOBILEGL_BACKEND_TYPE_UNKNOWN 0 -#define MOBILEGL_BACKEND_TYPE_DILIGENT 1 -#define MOBILEGL_BACKEND_TYPE_MRHI 2 -#define MOBILEGL_BACKEND_TYPE_DIRECT_GLES 3 - // ====================== MobileGL configurations ======================= // #define MOBILEGL_LOG_ACTIVE_LEVEL MOBILEGL_LOG_LEVEL_INFO diff --git a/MobileGL/GlobalObjects.cpp b/MobileGL/GlobalObjects.cpp new file mode 100644 index 00000000..f5c40733 --- /dev/null +++ b/MobileGL/GlobalObjects.cpp @@ -0,0 +1,20 @@ +// MobileGL - MobileGL/GlobalObjects.cpp +// Copyright (c) 2025-2026 MobileGL-Dev +// Licensed under the GNU Lesser General Public License v3.0: +// https://www.gnu.org/licenses/gpl-3.0.txt +// https://www.gnu.org/licenses/lgpl-3.0.txt +// SPDX-License-Identifier: LGPL-3.0-only +// End of Source File Header + +#include "Config.h" + +namespace MobileGL { + namespace MG_Config { + BackendType ActiveBackendType; + } // namespace MG_Config + + namespace MG_Backend { + UniquePtr pActiveBackendObject; + GlobalBackendFunctionsTable gBackendFunctionsTable; + } // namespace MG_Backend +} // namespace MobileGL diff --git a/MobileGL/Init.cpp b/MobileGL/Init.cpp index 054f6727..19767622 100644 --- a/MobileGL/Init.cpp +++ b/MobileGL/Init.cpp @@ -9,7 +9,7 @@ #include "Init.h" #include "Config.h" #include -#include +#include #include #include #include @@ -33,7 +33,6 @@ namespace MobileGL { MGLOG_I("MobileGL closing..."); glslang::FinalizeProcess(); delete MG_State::pGLContext; - MG_Config::RendererInfoPtr.reset(); delete MG_Impl::GLImpl::TextureImpl::pProxyTextureManager; delete MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo; MG_Util::Debug::Close(); @@ -65,4 +64,4 @@ namespace MobileGL { return TRUE; } #endif -} // namespace MobileGL \ No newline at end of file +} // namespace MobileGL diff --git a/MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.h b/MobileGL/MG_Backend/BackendObject.cpp similarity index 50% rename from MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.h rename to MobileGL/MG_Backend/BackendObject.cpp index 29519e04..87869987 100644 --- a/MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.h +++ b/MobileGL/MG_Backend/BackendObject.cpp @@ -1,4 +1,4 @@ -// MobileGL - MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.h +// MobileGL - MobileGL/MG_Backend/BackendObject.cpp // Copyright (c) 2025-2026 MobileGL-Dev // Licensed under the GNU Lesser General Public License v3.0: // https://www.gnu.org/licenses/gpl-3.0.txt @@ -6,5 +6,10 @@ // SPDX-License-Identifier: LGPL-3.0-only // End of Source File Header -#pragma once -#include \ No newline at end of file +#include "BackendObject.h" + +namespace MobileGL::MG_Backend { + void BackendObject::SetWindowHandle(const WindowHandle& handle) { + m_windowHandle = handle; + } +} // namespace MobileGL::MG_Backend diff --git a/MobileGL/MG_Backend/BackendObject.h b/MobileGL/MG_Backend/BackendObject.h new file mode 100644 index 00000000..6833afe0 --- /dev/null +++ b/MobileGL/MG_Backend/BackendObject.h @@ -0,0 +1,108 @@ +// MobileGL - MobileGL/MG_Backend/BackendObject.h +// Copyright (c) 2025-2026 MobileGL-Dev +// Licensed under the GNU Lesser General Public License v3.0: +// https://www.gnu.org/licenses/gpl-3.0.txt +// https://www.gnu.org/licenses/lgpl-3.0.txt +// SPDX-License-Identifier: LGPL-3.0-only +// End of Source File Header + +#pragma once +#include + +namespace MobileGL { + + enum class BackendType { + DirectGLES, + BackendTypeCount, + Unknown = -1 + }; + + namespace MG_Backend { + struct GLFunctionsTable { + void (*DrawArrays)(GLenum mode, GLint first, GLsizei count); + void (*DrawElements)(GLenum mode, GLsizei count, GLenum type, const void* indices); + void (*DrawElementsBaseVertex)(GLenum mode, GLsizei count, GLenum type, const void* indices, + GLint basevertex); + void (*MultiDrawElements)(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices, + GLsizei drawcount); + void (*MultiDrawElementsBaseVertex)(GLenum mode, const GLsizei* count, GLenum type, + const GLvoid* const* indices, GLsizei drawcount, + const GLint* basevertex); + void (*MultiDrawElementsIndirect)(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, + GLsizei stride); + void (*MultiDrawArraysIndirect)(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride); + void (*DrawRangeElementsBaseVertex)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, + const void* indices, GLint basevertex); + void (*DrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, + const void* indices); + void (*DrawElementsInstancedBaseVertexBaseInstance)(GLenum mode, GLsizei count, GLenum type, + const void* indices, GLsizei instancecount, + GLint basevertex, GLuint baseinstance); + void (*DrawElementsInstancedBaseVertex)(GLenum mode, GLsizei count, GLenum type, const void* indices, + GLsizei instancecount, GLint basevertex); + void (*DrawElementsInstancedBaseInstance)(GLenum mode, GLsizei count, GLenum type, const void* indices, + GLsizei instancecount, GLuint baseinstance); + void (*DrawElementsInstanced)(GLenum mode, GLsizei count, GLenum type, const void* indices, + GLsizei instancecount); + void (*DrawArraysInstancedBaseInstance)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, + GLuint baseinstance); + void (*DrawArraysInstanced)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); + void (*DrawElementsIndirect)(GLenum mode, GLenum type, const void* indirect); + void (*DrawArraysIndirect)(GLenum mode, const void* indirect); + void (*Clear)(GLbitfield mask); + void (*ClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + void (*ClearBufferfv)(GLenum buffer, GLint drawbuffer, const GLfloat* value); + void (*ClearBufferuiv)(GLenum buffer, GLint drawbuffer, const GLuint* value); + void (*ClearBufferiv)(GLenum buffer, GLint drawbuffer, const GLint* value); + void (*BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + void (*CopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, + GLsizei height, GLint border); + void (*CopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height); + void (*GenerateMipmap)(GLenum target); + void (*ReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + void* pixels); + void (*GetTexImage)(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels); + }; + struct GlobalBackendFunctionsTable { + GLFunctionsTable GL; + void (*Present)(); + }; + + struct DynamicBackendParameters { + SizeT UniformBufferOffsetAlignment = 256; + }; + + enum class WindowBackend { + Android, + // TODO: X11, Wayland, Windows, macOS, etc. + WindowBackendCount, + Unknown = -1 + }; + + struct WindowHandle { + WindowBackend Backend = WindowBackend::Unknown; + void* Handle = nullptr; + }; + + class BackendObject { + public: + virtual ~BackendObject() = default; + + virtual void Initialize() = 0; + virtual void InitWindowSurface() = 0; + + void SetWindowHandle(const WindowHandle& handle); + + virtual const RendererInfo& GetRendererInfo() const = 0; + virtual String GetBackendAPIVersionString() const = 0; + virtual const GlobalBackendFunctionsTable& GetBackendFunctions() const = 0; + virtual const DynamicBackendParameters& GetDynamicParameters() const = 0; + virtual BackendType GetBackendType() const = 0; + + protected: + WindowHandle m_windowHandle; + }; + } // namespace MG_Backend +} // namespace MobileGL diff --git a/MobileGL/MG_Backend/BackendObjects.h b/MobileGL/MG_Backend/BackendObjects.h new file mode 100644 index 00000000..d2c7cb5b --- /dev/null +++ b/MobileGL/MG_Backend/BackendObjects.h @@ -0,0 +1,19 @@ +// MobileGL - MobileGL/MG_Backend/BackendObjects.h +// Copyright (c) 2025-2026 MobileGL-Dev +// Licensed under the GNU Lesser General Public License v3.0: +// https://www.gnu.org/licenses/gpl-3.0.txt +// https://www.gnu.org/licenses/lgpl-3.0.txt +// SPDX-License-Identifier: LGPL-3.0-only +// End of Source File Header + +#pragma once +#include +#include "BackendObject.h" +#include "DirectGLES/BackendObject_DirectGLES.h" + +namespace MobileGL::MG_Backend { + extern UniquePtr pActiveBackendObject; + extern GlobalBackendFunctionsTable gBackendFunctionsTable; + + void Init(); +} // namespace MobileGL::MG_Backend diff --git a/MobileGL/MG_Backend/Backends.h b/MobileGL/MG_Backend/Backends.h deleted file mode 100644 index 8b45d667..00000000 --- a/MobileGL/MG_Backend/Backends.h +++ /dev/null @@ -1,91 +0,0 @@ -// MobileGL - MobileGL/MG_Backend/Backends.h -// Copyright (c) 2025-2026 MobileGL-Dev -// Licensed under the GNU Lesser General Public License v3.0: -// https://www.gnu.org/licenses/gpl-3.0.txt -// https://www.gnu.org/licenses/lgpl-3.0.txt -// SPDX-License-Identifier: LGPL-3.0-only -// End of Source File Header - -#pragma once -#include -#include - -namespace MobileGL { - namespace MG_Backend { - namespace Unknown { - inline RendererInfo RendererInfoUnknown = { - .RendererName = "", // Renderer Name - .BackendName = "", // Backend Name - .ExtraVendor = ", ", // Extra vendor - .RendererGLInfo = - { - // OpenGL Info - .TargetGLVersion = {3, 3, 0}, // Target OpenGL Version - .TargetGLSLVersion = {4, 6, 0}, // Target Shading Language Version - .Extensions = {}, // OpenGL Extensions - .IsCompatibilityProfile = false // Is Compatibility Profile - }, - .BackendCapability = {.AllowVSOnlyPrograms = false} // Backend Capability - }; - } - - namespace Diligent { - enum class SpecificBackendType { - Vulkan, - Metal - }; - - inline RendererInfo RendererInfoVulkan = { - .RendererName = "MG-DE-Vulkan", // Renderer Name - .BackendName = "Diligent Engine (Vulkan)", // Backend Name - .ExtraVendor = Nullopt, // Extra vendor - .RendererGLInfo = - { - // OpenGL Info - .TargetGLVersion = {3, 3, 0}, // Target OpenGL Version - .TargetGLSLVersion = {4, 6, 0}, // Target Shading Language Version - .Extensions = {V_OpenGL30, V_OpenGL31, V_OpenGL32, // OpenGL Extensions - V_OpenGL33}, - .IsCompatibilityProfile = false // Is Compatibility Profile - }, - .BackendCapability = {.AllowVSOnlyPrograms = false} // Backend Capability - }; - - inline RendererInfo RendererInfoMetal = { - .RendererName = "MG-DE-Metal", // Renderer Name - .BackendName = "Diligent Engine (Metal)", // Backend Name - .ExtraVendor = Nullopt, // Extra vendor - .RendererGLInfo = - { - // OpenGL Info - .TargetGLVersion = {3, 3, 0}, // Target OpenGL Version - .TargetGLSLVersion = {4, 6, 0}, // Target Shading Language Version - .Extensions = {V_OpenGL30, V_OpenGL31, V_OpenGL32, // OpenGL Extensions - V_OpenGL33}, - .IsCompatibilityProfile = false // Is Compatibility Profile - }, - .BackendCapability = {.AllowVSOnlyPrograms = false} // Backend Capability - }; - } // namespace Diligent - - namespace DirectGLES { - inline RendererInfo RendererInfo = { - .RendererName = "Espryt", // Renderer Name - .BackendName = "Direct (OpenGL ES)", // Backend Name - .ExtraVendor = Nullopt, // Extra vendor - .RendererGLInfo = - { - // OpenGL Info - .TargetGLVersion = {3, 3, 0}, // Target OpenGL Version - .TargetGLSLVersion = {4, 6, 0}, // Target Shading Language Version - .Extensions = {V_OpenGL30, V_OpenGL31, V_OpenGL32, // OpenGL Extensions - V_OpenGL33, E_GL_ARB_draw_buffers_blend}, - .IsCompatibilityProfile = false // Is Compatibility Profile - }, - .BackendCapability = {.AllowVSOnlyPrograms = false} // Backend Capability - }; - } // namespace DirectGLES - - void Init(); - } // namespace MG_Backend -} // namespace MobileGL diff --git a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp new file mode 100644 index 00000000..3f45da86 --- /dev/null +++ b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp @@ -0,0 +1,136 @@ +// MobileGL - MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp +// Copyright (c) 2025-2026 MobileGL-Dev +// Licensed under the GNU Lesser General Public License v3.0: +// https://www.gnu.org/licenses/gpl-3.0.txt +// https://www.gnu.org/licenses/lgpl-3.0.txt +// SPDX-License-Identifier: LGPL-3.0-only +// End of Source File Header + +#include "BackendObject_DirectGLES.h" +#include "MG_Backend/BackendObject.h" +#include +#include +#include + +namespace MobileGL::MG_Backend::DirectGLES { + BackendObject_DirectGLES::~BackendObject_DirectGLES() { + DestroyEGLContext(); + } + + void BackendObject_DirectGLES::InitWindowSurface() { + // Only use EGL for now + auto nativeWindow = reinterpret_cast(m_windowHandle.Handle); + if (!DirectGLES::InitWindowSurface(nativeWindow)) { + MGLOG_E("Failed to initialize window surface for DirectGLES backend"); + } + } + + void BackendObject_DirectGLES::Initialize() { + if (!MG_Util::BackendLoader::AcquireEGLFunctions(m_EGLFunctions)) { + MGLOG_E("Failed to acquire EGL functions for DirectGLES backend"); + return; + } + if (!MG_Util::BackendLoader::AcquireGLESFunctions(m_GLESFunctions, m_EGLFunctions.eglGetProcAddress)) { + MGLOG_E("Failed to acquire GLES functions for DirectGLES backend"); + return; + } + m_initialized = true; + + DirectGLES::SetEGLFuncsTable(m_EGLFunctions); + DirectGLES::SetGLESFuncsTable(m_GLESFunctions); + + if (!MG_Util::BackendLoader::FillInGLESCapabilities(m_GLESCapabilities, m_GLESFunctions, m_EGLFunctions)) { + MGLOG_E("Failed to fill in GLES capabilities for DirectGLES backend"); + return; + } + DirectGLES::SetGLESCapabilities(m_GLESCapabilities); + UpdateDynamicBackendParameters(); + } + + const RendererInfo& BackendObject_DirectGLES::GetRendererInfo() const { + static RendererInfo RendererInfo = { + .RendererName = "Espryt", // Renderer Name + .BackendName = "Direct (OpenGL ES)", // Backend Name + .ExtraVendor = Nullopt, // Extra vendor + .RendererGLInfo = + { + .TargetGLVersion = {3, 3, 0}, // Target OpenGL Version + .TargetGLSLVersion = {4, 6, 0}, // Target Shading Language Version + .Extensions = {V_OpenGL30, V_OpenGL31, V_OpenGL32, // OpenGL Extensions + V_OpenGL33, E_GL_ARB_draw_buffers_blend}, + .IsCompatibilityProfile = false // Is Compatibility Profile + }, + .StaticBackendCapability = {.AllowVSOnlyPrograms = false} // Backend Capability + }; + return RendererInfo; + } + + String BackendObject_DirectGLES::GetBackendAPIVersionString() const { + if (!m_initialized) { + return ""; + } + // Format: + // , OpenGL ES + String versionString = std::format("{}, OpenGL ES {}.{}", m_GLESCapabilities.GLESRendererString, + m_GLESCapabilities.GLESVersion.Major, m_GLESCapabilities.GLESVersion.Minor); + return versionString; + } + + BackendType BackendObject_DirectGLES::GetBackendType() const { + return BackendType::DirectGLES; + } + + const GlobalBackendFunctionsTable& BackendObject_DirectGLES::GetBackendFunctions() const { + static GlobalBackendFunctionsTable funcsTable; + static Bool funcsTableInitialized = false; + if (!funcsTableInitialized) { + funcsTable.Present = DirectGLES::Present; + funcsTable.GL.DrawArrays = DrawArrays; + funcsTable.GL.DrawElements = DrawElements; + funcsTable.GL.DrawElementsBaseVertex = DrawElementsBaseVertex; + funcsTable.GL.MultiDrawElements = MultiDrawElements; + funcsTable.GL.MultiDrawElementsBaseVertex = MultiDrawElementsBaseVertex; + funcsTable.GL.MultiDrawElementsIndirect = MultiDrawElementsIndirect; + funcsTable.GL.MultiDrawArraysIndirect = MultiDrawArraysIndirect; + funcsTable.GL.DrawRangeElementsBaseVertex = DrawRangeElementsBaseVertex; + funcsTable.GL.DrawRangeElements = DrawRangeElements; + funcsTable.GL.DrawElementsInstancedBaseVertexBaseInstance = DrawElementsInstancedBaseVertexBaseInstance; + funcsTable.GL.DrawElementsInstancedBaseVertex = DrawElementsInstancedBaseVertex; + funcsTable.GL.DrawElementsInstancedBaseInstance = DrawElementsInstancedBaseInstance; + funcsTable.GL.DrawElementsInstanced = DrawElementsInstanced; + funcsTable.GL.DrawArraysInstancedBaseInstance = DrawArraysInstancedBaseInstance; + funcsTable.GL.DrawArraysInstanced = DrawArraysInstanced; + funcsTable.GL.DrawElementsIndirect = DrawElementsIndirect; + funcsTable.GL.DrawArraysIndirect = DrawArraysIndirect; + funcsTable.GL.Clear = Clear; + funcsTable.GL.ClearBufferfi = ClearBufferfi; + funcsTable.GL.ClearBufferfv = ClearBufferfv; + funcsTable.GL.ClearBufferuiv = ClearBufferuiv; + funcsTable.GL.ClearBufferiv = ClearBufferiv; + funcsTable.GL.BlitFramebuffer = BlitFramebuffer; + funcsTable.GL.CopyTexImage2D = CopyTexImage2D; + funcsTable.GL.CopyTexSubImage2D = CopyTexSubImage2D; + funcsTable.GL.GenerateMipmap = GenerateMipmap; + funcsTable.GL.ReadPixels = ReadPixels; + funcsTable.GL.GetTexImage = GetTexImage; + funcsTableInitialized = true; + } + return funcsTable; + } + + const DynamicBackendParameters& BackendObject_DirectGLES::GetDynamicParameters() const { + return m_dynamicParameters; + } + + void BackendObject_DirectGLES::UpdateDynamicBackendParameters() { + m_dynamicParameters.UniformBufferOffsetAlignment = m_GLESCapabilities.UniformBufferOffsetAlignment; + } + + const MG_External::GLESFunctionsTable& BackendObject_DirectGLES::GetGLESFunctions() const { + return m_GLESFunctions; + } + + const MG_External::EGLFunctionsTable& BackendObject_DirectGLES::GetEGLFunctions() const { + return m_EGLFunctions; + } +} // namespace MobileGL::MG_Backend::DirectGLES diff --git a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.h b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.h new file mode 100644 index 00000000..e539a271 --- /dev/null +++ b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.h @@ -0,0 +1,39 @@ +// MobileGL - MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.h +// Copyright (c) 2025-2026 MobileGL-Dev +// Licensed under the GNU Lesser General Public License v3.0: +// https://www.gnu.org/licenses/gpl-3.0.txt +// https://www.gnu.org/licenses/lgpl-3.0.txt +// SPDX-License-Identifier: LGPL-3.0-only +// End of Source File Header + +#pragma once +#include +#include "../BackendObject.h" +#include + +namespace MobileGL::MG_Backend::DirectGLES { + class BackendObject_DirectGLES : public BackendObject { + public: + ~BackendObject_DirectGLES() override; + void Initialize() override; + void InitWindowSurface() override; + + const RendererInfo& GetRendererInfo() const override; + String GetBackendAPIVersionString() const override; + const GlobalBackendFunctionsTable& GetBackendFunctions() const override; + const DynamicBackendParameters& GetDynamicParameters() const override; + BackendType GetBackendType() const override; + + const MG_External::GLESFunctionsTable& GetGLESFunctions() const; + const MG_External::EGLFunctionsTable& GetEGLFunctions() const; + + private: + void UpdateDynamicBackendParameters(); + + Bool m_initialized = false; + MG_External::EGLFunctionsTable m_EGLFunctions; + MG_External::GLESFunctionsTable m_GLESFunctions; + MG_External::GLESCapabilities m_GLESCapabilities; + DynamicBackendParameters m_dynamicParameters; + }; +} // namespace MobileGL::MG_Backend::DirectGLES diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index eb26c12b..5a0dd3c3 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -7,12 +7,7 @@ // End of Source File Header #include "DirectGLES.h" -#include "GLES3/gl32.h" -#include "MG_State/GLState/ErrorState/Error.h" -#include "MG_State/GLState/RenderState/RenderState.h" -#include "MG_State/GLState/SamplerState/SamplerObject.h" -#include "MG_Util/Debug/Log.h" -#include "MG_Util/Types.h" +#include "EGL/egl.h" #include "Utils.h" #include "Managers.h" #include @@ -28,6 +23,10 @@ #include namespace MobileGL::MG_Backend::DirectGLES { + MG_External::EGLFunctionsTable g_EGLFuncs; + MG_External::GLESFunctionsTable g_GLESFuncs; + MG_External::GLESCapabilities g_GLESCapabilities; + enum class DrawSyncBit : Uint32 { None = 0, IndexBuffer = 1 << 0, @@ -47,18 +46,18 @@ namespace MobileGL::MG_Backend::DirectGLES { namespace DebugImpl { #if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG void ErrorLopper::Loop(std::function func) { - GLenum err = MG_External::GLES::glGetError(); + GLenum err = g_GLESFuncs.glGetError(); while (err != GL_NO_ERROR) { func(err); - err = MG_External::GLES::glGetError(); + err = g_GLESFuncs.glGetError(); } } void ErrorLopper::Clear() { - GLenum err = MG_External::GLES::glGetError(); + GLenum err = g_GLESFuncs.glGetError(); while (err != GL_NO_ERROR) { MGLOG_D("Stray GL Error cleared: %s", MG_Util::ConvertGLEnumToString(err).c_str()); - err = MG_External::GLES::glGetError(); + err = g_GLESFuncs.glGetError(); } } @@ -77,11 +76,11 @@ namespace MobileGL::MG_Backend::DirectGLES { #if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG OpenGLScopeMarker::OpenGLScopeMarker(String scopeName) { - MG_External::GLES::glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, scopeName.c_str()); + g_GLESFuncs.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, scopeName.c_str()); } OpenGLScopeMarker::~OpenGLScopeMarker() { - MG_External::GLES::glPopDebugGroup(); + g_GLESFuncs.glPopDebugGroup(); } #else OpenGLScopeMarker::OpenGLScopeMarker(String scopeName) {} @@ -297,16 +296,16 @@ namespace MobileGL::MG_Backend::DirectGLES { const auto& parameters = MG_State::pGLContext->GetRenderStateParameters(); if (parameters.Viewport != g_syncedRenderStateParameters.Viewport) { - MG_External::GLES::glViewport(parameters.Viewport.x(), parameters.Viewport.y(), parameters.Viewport.z(), - parameters.Viewport.w()); + g_GLESFuncs.glViewport(parameters.Viewport.x(), parameters.Viewport.y(), parameters.Viewport.z(), + parameters.Viewport.w()); } #define SYNC_CAPABILITY(cap_mg, cap_gl) \ if (parameters.cap_mg##Enabled != g_syncedRenderStateParameters.cap_mg##Enabled) { \ if (parameters.cap_mg##Enabled) { \ - MG_External::GLES::glEnable(cap_gl); \ + g_GLESFuncs.glEnable(cap_gl); \ } else { \ - MG_External::GLES::glDisable(cap_gl); \ + g_GLESFuncs.glDisable(cap_gl); \ } \ } SYNC_CAPABILITY(DepthTest, GL_DEPTH_TEST); @@ -340,19 +339,19 @@ namespace MobileGL::MG_Backend::DirectGLES { if (anyCapDirty) { if (allEnabled) { - MG_External::GLES::glEnable(GL_BLEND); + g_GLESFuncs.glEnable(GL_BLEND); for (auto& s : syncedStates) s.Enabled = true; } else if (allDisabled) { - MG_External::GLES::glDisable(GL_BLEND); + g_GLESFuncs.glDisable(GL_BLEND); for (auto& s : syncedStates) s.Enabled = false; } else { for (Uint i = 0; i < FBO::MAX_DRAW_BUFFERS; ++i) { if (targetStates[i].Enabled != syncedStates[i].Enabled) { syncedStates[i].Enabled = targetStates[i].Enabled; - syncedStates[i].Enabled ? MG_External::GLES::glEnablei(GL_BLEND, i) - : MG_External::GLES::glDisablei(GL_BLEND, i); + syncedStates[i].Enabled ? g_GLESFuncs.glEnablei(GL_BLEND, i) + : g_GLESFuncs.glDisablei(GL_BLEND, i); } } } @@ -382,11 +381,10 @@ namespace MobileGL::MG_Backend::DirectGLES { if (anyFuncDirty) { if (allFuncsSame) { - MG_External::GLES::glBlendFuncSeparate( - MG_Util::ConvertBlendFactorToGLEnum(first.SrcFactorRGB), - MG_Util::ConvertBlendFactorToGLEnum(first.DstFactorRGB), - MG_Util::ConvertBlendFactorToGLEnum(first.SrcFactorAlpha), - MG_Util::ConvertBlendFactorToGLEnum(first.DstFactorAlpha)); + g_GLESFuncs.glBlendFuncSeparate(MG_Util::ConvertBlendFactorToGLEnum(first.SrcFactorRGB), + MG_Util::ConvertBlendFactorToGLEnum(first.DstFactorRGB), + MG_Util::ConvertBlendFactorToGLEnum(first.SrcFactorAlpha), + MG_Util::ConvertBlendFactorToGLEnum(first.DstFactorAlpha)); for (auto& syn : syncedStates) { syn.SrcFactorRGB = first.SrcFactorRGB; @@ -406,7 +404,7 @@ namespace MobileGL::MG_Backend::DirectGLES { syn.SrcFactorAlpha = cur.SrcFactorAlpha; syn.DstFactorAlpha = cur.DstFactorAlpha; - MG_External::GLES::glBlendFuncSeparatei( + g_GLESFuncs.glBlendFuncSeparatei( i, MG_Util::ConvertBlendFactorToGLEnum(cur.SrcFactorRGB), MG_Util::ConvertBlendFactorToGLEnum(cur.DstFactorRGB), MG_Util::ConvertBlendFactorToGLEnum(cur.SrcFactorAlpha), @@ -419,42 +417,42 @@ namespace MobileGL::MG_Backend::DirectGLES { { // Depth state if (parameters.DepthFunc != g_syncedRenderStateParameters.DepthFunc) { - MG_External::GLES::glDepthFunc(MG_Util::ConvertDepthTestFuncToGLEnum(parameters.DepthFunc)); + g_GLESFuncs.glDepthFunc(MG_Util::ConvertDepthTestFuncToGLEnum(parameters.DepthFunc)); } if (parameters.DepthMask != g_syncedRenderStateParameters.DepthMask) { - MG_External::GLES::glDepthMask(parameters.DepthMask ? GL_TRUE : GL_FALSE); + g_GLESFuncs.glDepthMask(parameters.DepthMask ? GL_TRUE : GL_FALSE); } } { // Color mask if (parameters.ColorMask != g_syncedRenderStateParameters.ColorMask) { const BoolVec4& colorMask = parameters.ColorMask; - MG_External::GLES::glColorMask(ToGLBoolean(colorMask.x()), ToGLBoolean(colorMask.y()), - ToGLBoolean(colorMask.z()), ToGLBoolean(colorMask.w())); + g_GLESFuncs.glColorMask(ToGLBoolean(colorMask.x()), ToGLBoolean(colorMask.y()), + ToGLBoolean(colorMask.z()), ToGLBoolean(colorMask.w())); } } { // Clear values if (parameters.ClearColor != g_syncedRenderStateParameters.ClearColor) { const FloatVec4& clearCol = parameters.ClearColor; - MG_External::GLES::glClearColor(clearCol.x(), clearCol.y(), clearCol.z(), clearCol.w()); + g_GLESFuncs.glClearColor(clearCol.x(), clearCol.y(), clearCol.z(), clearCol.w()); } if (parameters.ClearDepth != g_syncedRenderStateParameters.ClearDepth) { - MG_External::GLES::glClearDepthf(parameters.ClearDepth); + g_GLESFuncs.glClearDepthf(parameters.ClearDepth); } } { // Cull face mode if (parameters.CullFaceModeSetting != g_syncedRenderStateParameters.CullFaceModeSetting) { const CullFaceMode& cfm = parameters.CullFaceModeSetting; - MG_External::GLES::glCullFace(MG_Util::ConvertCullFaceModeToGLEnum(cfm)); + g_GLESFuncs.glCullFace(MG_Util::ConvertCullFaceModeToGLEnum(cfm)); } } { // Scissor box if (parameters.ScissorBox != g_syncedRenderStateParameters.ScissorBox) { const IntVec4& scissorBox = parameters.ScissorBox; - MG_External::GLES::glScissor(scissorBox.x(), scissorBox.y(), scissorBox.z(), scissorBox.w()); + g_GLESFuncs.glScissor(scissorBox.x(), scissorBox.y(), scissorBox.z(), scissorBox.w()); } } @@ -470,7 +468,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #endif auto currentProgram = MG_State::pGLContext->GetCurrentProgram(); if (!currentProgram || !currentProgram->GetLinkStatus()) { - MG_External::GLES::glUseProgram(0); + g_GLESFuncs.glUseProgram(0); return; } const auto& backendProgramIt = g_backendProgramObjects.find(currentProgram); @@ -506,8 +504,8 @@ namespace MobileGL::MG_Backend::DirectGLES { } } else { MGLOG_D("Binding default framebuffer as %s FBO", (target == FramebufferTarget::Read ? "READ" : "DRAW")); - MG_External::GLES::glBindFramebuffer( - target == FramebufferTarget::Draw ? GL_DRAW_FRAMEBUFFER : GL_READ_FRAMEBUFFER, 0); + g_GLESFuncs.glBindFramebuffer(target == FramebufferTarget::Draw ? GL_DRAW_FRAMEBUFFER : GL_READ_FRAMEBUFFER, + 0); } } @@ -535,7 +533,7 @@ namespace MobileGL::MG_Backend::DirectGLES { backendVAOIt->second->Bind(); } } else { - MG_External::GLES::glBindVertexArray(0); + g_GLESFuncs.glBindVertexArray(0); } } @@ -592,19 +590,18 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedNC("UpdateGlobalUBO", TRACY_ZONECOLOR_BACKEND); #endif - MG_External::GLES::glBindBuffer(GL_UNIFORM_BUFFER, - backendProgramIt->second->GetBackendGlobalUBOId()); - MG_External::GLES::glBufferSubData(GL_UNIFORM_BUFFER, 0, currentProgram->GetUBOSize(), - currentProgram->MapUBO()); - MG_External::GLES::glBindBuffer(GL_UNIFORM_BUFFER, 0); + g_GLESFuncs.glBindBuffer(GL_UNIFORM_BUFFER, backendProgramIt->second->GetBackendGlobalUBOId()); + g_GLESFuncs.glBufferSubData(GL_UNIFORM_BUFFER, 0, currentProgram->GetUBOSize(), + currentProgram->MapUBO()); + g_GLESFuncs.glBindBuffer(GL_UNIFORM_BUFFER, 0); - Uint blockIndex = MG_External::GLES::glGetUniformBlockIndex( - backendProgramId, MG_Util::ShaderTranspiler::GLOBAL_UBO_NAME); + Uint blockIndex = g_GLESFuncs.glGetUniformBlockIndex(backendProgramId, + MG_Util::ShaderTranspiler::GLOBAL_UBO_NAME); - MG_External::GLES::glUniformBlockBinding(backendProgramId, blockIndex, 0); + g_GLESFuncs.glUniformBlockBinding(backendProgramId, blockIndex, 0); - MG_External::GLES::glBindBufferBase(GL_UNIFORM_BUFFER, 0, - backendProgramIt->second->GetBackendGlobalUBOId()); + g_GLESFuncs.glBindBufferBase(GL_UNIFORM_BUFFER, 0, + backendProgramIt->second->GetBackendGlobalUBOId()); } { @@ -621,9 +618,8 @@ namespace MobileGL::MG_Backend::DirectGLES { // Connect program ubo index to backend binding point auto binding = currentProgram->GetUniformBlockBinding(i); auto& name = currentProgram->GetUniformBlockName(i); - GLuint backendBlkIdx = - MG_External::GLES::glGetUniformBlockIndex(backendProgramId, name.c_str()); - MG_External::GLES::glUniformBlockBinding(backendProgramId, backendBlkIdx, lastUBOBinding); + GLuint backendBlkIdx = g_GLESFuncs.glGetUniformBlockIndex(backendProgramId, name.c_str()); + g_GLESFuncs.glUniformBlockBinding(backendProgramId, backendBlkIdx, lastUBOBinding); // Connect buffer to backend binding point auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, binding); @@ -636,12 +632,12 @@ namespace MobileGL::MG_Backend::DirectGLES { const auto& backendBufferObject = backendBufferIt->second; backendBufferObject->Bind(GL_UNIFORM_BUFFER); if (range.end == 0) { - MG_External::GLES::glBindBufferBase(GL_UNIFORM_BUFFER, lastUBOBinding, - backendBufferObject->GetBackendBufferId()); + g_GLESFuncs.glBindBufferBase(GL_UNIFORM_BUFFER, lastUBOBinding, + backendBufferObject->GetBackendBufferId()); } else { - MG_External::GLES::glBindBufferRange(GL_UNIFORM_BUFFER, lastUBOBinding, - backendBufferObject->GetBackendBufferId(), - range.start, range.end - range.start); + g_GLESFuncs.glBindBufferRange(GL_UNIFORM_BUFFER, lastUBOBinding, + backendBufferObject->GetBackendBufferId(), + range.start, range.end - range.start); } } else { MGLOG_E("No backend buffer found for UBO binding, cannot bind UBO."); @@ -660,9 +656,9 @@ namespace MobileGL::MG_Backend::DirectGLES { auto unit = currentProgram->GetUniformSamplerOrImageUnitIndex(loc); if (unit == -1) continue; auto& name = currentProgram->GetUniformName(loc); - auto locAtBackend = MG_External::GLES::glGetUniformLocation( + auto locAtBackend = g_GLESFuncs.glGetUniformLocation( backendProgramIt->second->GetBackendProgramId(), name.c_str()); - MG_External::GLES::glUniform1i(locAtBackend, unit); + g_GLESFuncs.glUniform1i(locAtBackend, unit); auto samplerObject = MG_State::pGLContext->GetTextureUnitObject(unit).GetSamplerObject(); @@ -682,7 +678,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } } } else { - MG_External::GLES::glUseProgram(0); + g_GLESFuncs.glUseProgram(0); MGLOG_E("No backend program found (maybe not synced) for current program, cannot use program."); } } @@ -698,7 +694,7 @@ namespace MobileGL::MG_Backend::DirectGLES { BindCurrentFBO(FramebufferTarget::Draw); - MG_External::GLES::glClear(mask); + g_GLESFuncs.glClear(mask); } void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) { @@ -707,7 +703,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #endif DrawSyncBit syncBit = DrawSyncBit::IndexBuffer; PrepareForDraw(syncBit); - MG_External::GLES::glDrawElements(mode, count, type, indices); + g_GLESFuncs.glDrawElements(mode, count, type, indices); } void DrawArrays(GLenum mode, GLint first, GLsizei count) { @@ -716,7 +712,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #endif DrawSyncBit syncBit = DrawSyncBit::None; PrepareForDraw(syncBit); - MG_External::GLES::glDrawArrays(mode, first, count); + g_GLESFuncs.glDrawArrays(mode, first, count); } void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLint basevertex) { @@ -725,7 +721,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #endif DrawSyncBit syncBit = DrawSyncBit::IndexBuffer; PrepareForDraw(syncBit); - MG_External::GLES::glDrawElementsBaseVertex(mode, count, type, indices, basevertex); + g_GLESFuncs.glDrawElementsBaseVertex(mode, count, type, indices, basevertex); } void MultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const* indices, @@ -737,7 +733,7 @@ namespace MobileGL::MG_Backend::DirectGLES { PrepareForDraw(syncBit); for (GLsizei i = 0; i < drawcount; ++i) { - MG_External::GLES::glDrawElements(mode, count[i], type, indices[i]); + g_GLESFuncs.glDrawElements(mode, count[i], type, indices[i]); } } @@ -750,7 +746,7 @@ namespace MobileGL::MG_Backend::DirectGLES { PrepareForDraw(syncBit); for (GLsizei i = 0; i < drawcount; ++i) { - MG_External::GLES::glDrawElementsBaseVertex(mode, count[i], type, indices[i], basevertex[i]); + g_GLESFuncs.glDrawElementsBaseVertex(mode, count[i], type, indices[i], basevertex[i]); } } @@ -764,7 +760,7 @@ namespace MobileGL::MG_Backend::DirectGLES { for (GLsizei i = 0; i < drawcount; ++i) { const GLvoid* cmd = reinterpret_cast(reinterpret_cast(indirect) + i * (stride ? stride : sizeof(GLsizei) * 4)); - MG_External::GLES::glDrawElementsIndirect(mode, type, cmd); + g_GLESFuncs.glDrawElementsIndirect(mode, type, cmd); } } @@ -778,7 +774,7 @@ namespace MobileGL::MG_Backend::DirectGLES { for (GLsizei i = 0; i < drawcount; ++i) { const GLvoid* cmd = reinterpret_cast(reinterpret_cast(indirect) + i * (stride ? stride : sizeof(GLsizei) * 4)); - MG_External::GLES::glDrawArraysIndirect(mode, cmd); + g_GLESFuncs.glDrawArraysIndirect(mode, cmd); } } @@ -786,13 +782,13 @@ namespace MobileGL::MG_Backend::DirectGLES { const void* indices, GLint basevertex) { DrawSyncBit syncBit = DrawSyncBit::IndexBuffer; PrepareForDraw(syncBit); - MG_External::GLES::glDrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex); + g_GLESFuncs.glDrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex); } void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) { DrawSyncBit syncBit = DrawSyncBit::IndexBuffer; PrepareForDraw(syncBit); - MG_External::GLES::glDrawRangeElements(mode, start, end, count, type, indices); + g_GLESFuncs.glDrawRangeElements(mode, start, end, count, type, indices); } void DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, @@ -805,7 +801,7 @@ namespace MobileGL::MG_Backend::DirectGLES { GLsizei instancecount, GLint basevertex) { DrawSyncBit syncBit = DrawSyncBit::IndexBuffer | DrawSyncBit::Instancing; PrepareForDraw(syncBit); - MG_External::GLES::glDrawElementsInstancedBaseVertex(mode, count, type, indices, instancecount, basevertex); + g_GLESFuncs.glDrawElementsInstancedBaseVertex(mode, count, type, indices, instancecount, basevertex); } void DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, @@ -817,13 +813,13 @@ namespace MobileGL::MG_Backend::DirectGLES { void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount) { DrawSyncBit syncBit = DrawSyncBit::IndexBuffer | DrawSyncBit::Instancing; PrepareForDraw(syncBit); - MG_External::GLES::glDrawElementsInstanced(mode, count, type, indices, instancecount); + g_GLESFuncs.glDrawElementsInstanced(mode, count, type, indices, instancecount); } void DrawElementsIndirect(GLenum mode, GLenum type, const void* indirect) { DrawSyncBit syncBit = DrawSyncBit::IndexBuffer | DrawSyncBit::IndirectBuffer; PrepareForDraw(syncBit); - MG_External::GLES::glDrawElementsIndirect(mode, type, indirect); + g_GLESFuncs.glDrawElementsIndirect(mode, type, indirect); } void DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, @@ -835,13 +831,13 @@ namespace MobileGL::MG_Backend::DirectGLES { void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) { DrawSyncBit syncBit = DrawSyncBit::Instancing; PrepareForDraw(syncBit); - MG_External::GLES::glDrawArraysInstanced(mode, first, count, instancecount); + g_GLESFuncs.glDrawArraysInstanced(mode, first, count, instancecount); } void DrawArraysIndirect(GLenum mode, const void* indirect) { DrawSyncBit syncBit = DrawSyncBit::IndirectBuffer; PrepareForDraw(syncBit); - MG_External::GLES::glDrawArraysIndirect(mode, indirect); + g_GLESFuncs.glDrawArraysIndirect(mode, indirect); } void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, @@ -871,7 +867,7 @@ namespace MobileGL::MG_Backend::DirectGLES { }); MGLOG_D("ES %s(%d, %d, %d, %d, %d, %d, %d, %d, 0x%x, %s)", __func__, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, MG_Util::ConvertGLEnumToString(filter).c_str()); - MG_External::GLES::glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + g_GLESFuncs.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); @@ -920,23 +916,23 @@ namespace MobileGL::MG_Backend::DirectGLES { __func__, s_prevDrawFBO, s_prevReadFBO); static GLuint tempFBO = 0; if (!tempFBO) { - MG_External::GLES::glGenFramebuffers(1, &tempFBO); + g_GLESFuncs.glGenFramebuffers(1, &tempFBO); } if (isRead) { - MG_External::GLES::glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, (GLint*)&s_prevReadFBO); - MG_External::GLES::glBindFramebuffer(GL_READ_FRAMEBUFFER, tempFBO); + g_GLESFuncs.glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, (GLint*)&s_prevReadFBO); + g_GLESFuncs.glBindFramebuffer(GL_READ_FRAMEBUFFER, tempFBO); } else { - MG_External::GLES::glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&s_prevDrawFBO); - MG_External::GLES::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFBO); + g_GLESFuncs.glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&s_prevDrawFBO); + g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFBO); } } void RestoreFBOFromTemp(Bool isRead) { if (isRead) { MGLOG_D("%s: Restoring previous read FBO=%u", __func__, s_prevReadFBO); - MG_External::GLES::glBindFramebuffer(GL_READ_FRAMEBUFFER, s_prevReadFBO); + g_GLESFuncs.glBindFramebuffer(GL_READ_FRAMEBUFFER, s_prevReadFBO); } else { MGLOG_D("%s: Restoring previous draw FBO=%u", __func__, s_prevDrawFBO); - MG_External::GLES::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, s_prevDrawFBO); + g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, s_prevDrawFBO); } } @@ -1001,14 +997,14 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Util::IsStencilFormatInternalFormat(MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat)); if (!isDepthFormat) { - MG_External::GLES::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); + g_GLESFuncs.glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); } else { MGLOG_D("%s: Backend depth", __func__); - MG_External::GLES::glTexImage2D(target, level, (GLint)internalformat, width, height, border, format, type, - nullptr); + g_GLESFuncs.glTexImage2D(target, level, (GLint)internalformat, width, height, border, format, type, + nullptr); errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); @@ -1020,16 +1016,16 @@ namespace MobileGL::MG_Backend::DirectGLES { GLenum attachment = isStencilFormat ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT; TempFBOBinder tempFBOBinder(false); - MG_External::GLES::glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, target, currentTex, level); + g_GLESFuncs.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, target, currentTex, level); - if (MG_External::GLES::glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + if (g_GLESFuncs.glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { MGLOG_E("ES glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE"); return; } - MG_External::GLES::glBlitFramebuffer(x, y, x + width, y + height, 0, 0, width, height, - GL_DEPTH_BUFFER_BIT | (isStencilFormat ? GL_STENCIL_BUFFER_BIT : 0), - GL_NEAREST); + g_GLESFuncs.glBlitFramebuffer(x, y, x + width, y + height, 0, 0, width, height, + GL_DEPTH_BUFFER_BIT | (isStencilFormat ? GL_STENCIL_BUFFER_BIT : 0), + GL_NEAREST); errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); @@ -1077,7 +1073,7 @@ namespace MobileGL::MG_Backend::DirectGLES { MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); GLenum internalFormat; - MG_External::GLES::glGetTexLevelParameteriv(target, level, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&internalFormat); + g_GLESFuncs.glGetTexLevelParameteriv(target, level, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&internalFormat); errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); @@ -1087,7 +1083,7 @@ namespace MobileGL::MG_Backend::DirectGLES { Bool isStencilFormat = MG_Util::IsStencilFormatInternalFormat(mgInternalFormat); if (!isDepthFormat) { - MG_External::GLES::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + g_GLESFuncs.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); @@ -1099,16 +1095,16 @@ namespace MobileGL::MG_Backend::DirectGLES { }); GLenum attachment = isStencilFormat ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT; TempFBOBinder tempFBOBinder(false); - MG_External::GLES::glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, target, currentTex, level); + g_GLESFuncs.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, target, currentTex, level); errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); - if (MG_External::GLES::glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + if (g_GLESFuncs.glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { MGLOG_E("ES glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE"); return; } - MG_External::GLES::glBlitFramebuffer( + g_GLESFuncs.glBlitFramebuffer( x, y, x + width, y + height, xoffset, yoffset, xoffset + width, yoffset + height, GL_DEPTH_BUFFER_BIT | (isStencilFormat ? GL_STENCIL_BUFFER_BIT : 0), GL_NEAREST); errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { @@ -1128,11 +1124,11 @@ namespace MobileGL::MG_Backend::DirectGLES { auto backendTexture = TextureImpl::SyncTextureObjectToBackend(texture); backendTexture->Bind(target, unitIndex); - MG_External::GLES::glGenerateMipmap(target); + g_GLESFuncs.glGenerateMipmap(target); } const GLubyte* GetString(GLenum name) { - return MG_External::GLES::glGetString(name); + return g_GLESFuncs.glGetString(name); } void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { @@ -1142,7 +1138,7 @@ namespace MobileGL::MG_Backend::DirectGLES { BindCurrentFBO(FramebufferTarget::Draw); - MG_External::GLES::glClearBufferfi(buffer, drawbuffer, depth, stencil); + g_GLESFuncs.glClearBufferfi(buffer, drawbuffer, depth, stencil); } void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) { @@ -1152,7 +1148,7 @@ namespace MobileGL::MG_Backend::DirectGLES { BindCurrentFBO(FramebufferTarget::Draw); - MG_External::GLES::glClearBufferfv(buffer, drawbuffer, value); + g_GLESFuncs.glClearBufferfv(buffer, drawbuffer, value); } void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) { @@ -1160,7 +1156,7 @@ namespace MobileGL::MG_Backend::DirectGLES { FramebufferImpl::SyncCurrentFBO(); RenderStateImpl::SyncRenderState(); - MG_External::GLES::glClearBufferiv(buffer, drawbuffer, value); + g_GLESFuncs.glClearBufferiv(buffer, drawbuffer, value); } void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) { @@ -1170,7 +1166,7 @@ namespace MobileGL::MG_Backend::DirectGLES { BindCurrentFBO(FramebufferTarget::Draw); - MG_External::GLES::glClearBufferuiv(buffer, drawbuffer, value); + g_GLESFuncs.glClearBufferuiv(buffer, drawbuffer, value); } class TempPixelStoreParameterSync { @@ -1191,28 +1187,28 @@ namespace MobileGL::MG_Backend::DirectGLES { PixelStoreParameters QueryCurrentGLPixelStoreParams(Bool isUnpack) { PixelStoreParameters p; if (!isUnpack) { - MG_External::GLES::glGetIntegerv(GL_PACK_ALIGNMENT, (GLint*)&p.Alignment); - MG_External::GLES::glGetIntegerv(GL_PACK_ROW_LENGTH, (GLint*)&p.RowLength); - MG_External::GLES::glGetIntegerv(GL_PACK_SKIP_ROWS, (GLint*)&p.SkipRows); - MG_External::GLES::glGetIntegerv(GL_PACK_SKIP_PIXELS, (GLint*)&p.SkipPixels); - // MG_External::GLES::glGetIntegerv(GL_PACK_IMAGE_HEIGHT, (GLint*)&p.ImageHeight); - // MG_External::GLES::glGetIntegerv(GL_PACK_SKIP_IMAGES, (GLint*)&p.SkipImages); + g_GLESFuncs.glGetIntegerv(GL_PACK_ALIGNMENT, (GLint*)&p.Alignment); + g_GLESFuncs.glGetIntegerv(GL_PACK_ROW_LENGTH, (GLint*)&p.RowLength); + g_GLESFuncs.glGetIntegerv(GL_PACK_SKIP_ROWS, (GLint*)&p.SkipRows); + g_GLESFuncs.glGetIntegerv(GL_PACK_SKIP_PIXELS, (GLint*)&p.SkipPixels); + // g_GLESFuncs.glGetIntegerv(GL_PACK_IMAGE_HEIGHT, (GLint*)&p.ImageHeight); + // g_GLESFuncs.glGetIntegerv(GL_PACK_SKIP_IMAGES, (GLint*)&p.SkipImages); // GLint tmp; - // MG_External::GLES::glGetIntegerv(GL_PACK_SWAP_BYTES, &tmp); + // g_GLESFuncs.glGetIntegerv(GL_PACK_SWAP_BYTES, &tmp); // p.SwapBytes = tmp ? true : false; - // MG_External::GLES::glGetIntegerv(GL_PACK_LSB_FIRST, &tmp); + // g_GLESFuncs.glGetIntegerv(GL_PACK_LSB_FIRST, &tmp); // p.LSBFirst = tmp ? true : false; } else { - MG_External::GLES::glGetIntegerv(GL_UNPACK_ALIGNMENT, (GLint*)&p.Alignment); - MG_External::GLES::glGetIntegerv(GL_UNPACK_ROW_LENGTH, (GLint*)&p.RowLength); - MG_External::GLES::glGetIntegerv(GL_UNPACK_SKIP_ROWS, (GLint*)&p.SkipRows); - MG_External::GLES::glGetIntegerv(GL_UNPACK_SKIP_PIXELS, (GLint*)&p.SkipPixels); - MG_External::GLES::glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, (GLint*)&p.ImageHeight); - MG_External::GLES::glGetIntegerv(GL_UNPACK_SKIP_IMAGES, (GLint*)&p.SkipImages); + g_GLESFuncs.glGetIntegerv(GL_UNPACK_ALIGNMENT, (GLint*)&p.Alignment); + g_GLESFuncs.glGetIntegerv(GL_UNPACK_ROW_LENGTH, (GLint*)&p.RowLength); + g_GLESFuncs.glGetIntegerv(GL_UNPACK_SKIP_ROWS, (GLint*)&p.SkipRows); + g_GLESFuncs.glGetIntegerv(GL_UNPACK_SKIP_PIXELS, (GLint*)&p.SkipPixels); + g_GLESFuncs.glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, (GLint*)&p.ImageHeight); + g_GLESFuncs.glGetIntegerv(GL_UNPACK_SKIP_IMAGES, (GLint*)&p.SkipImages); // GLint tmp; - // MG_External::GLES::glGetIntegerv(GL_UNPACK_SWAP_BYTES, &tmp); + // g_GLESFuncs.glGetIntegerv(GL_UNPACK_SWAP_BYTES, &tmp); // p.SwapBytes = tmp ? true : false; - // MG_External::GLES::glGetIntegerv(GL_UNPACK_LSB_FIRST, &tmp); + // g_GLESFuncs.glGetIntegerv(GL_UNPACK_LSB_FIRST, &tmp); // p.LSBFirst = tmp ? true : false; } return p; @@ -1220,23 +1216,23 @@ namespace MobileGL::MG_Backend::DirectGLES { void Sync(Bool isUnpack, const PixelStoreParameters& params) { if (!isUnpack) { - MG_External::GLES::glPixelStorei(GL_PACK_ALIGNMENT, params.Alignment); - MG_External::GLES::glPixelStorei(GL_PACK_ROW_LENGTH, params.RowLength); - MG_External::GLES::glPixelStorei(GL_PACK_SKIP_ROWS, params.SkipRows); - MG_External::GLES::glPixelStorei(GL_PACK_SKIP_PIXELS, params.SkipPixels); - // MG_External::GLES::glPixelStorei(GL_PACK_IMAGE_HEIGHT, params.ImageHeight); - // MG_External::GLES::glPixelStorei(GL_PACK_SKIP_IMAGES, params.SkipImages); - // MG_External::GLES::glPixelStorei(GL_PACK_SWAP_BYTES, params.SwapBytes ? GL_TRUE : GL_FALSE); - // MG_External::GLES::glPixelStorei(GL_PACK_LSB_FIRST, params.LSBFirst ? GL_TRUE : GL_FALSE); + g_GLESFuncs.glPixelStorei(GL_PACK_ALIGNMENT, params.Alignment); + g_GLESFuncs.glPixelStorei(GL_PACK_ROW_LENGTH, params.RowLength); + g_GLESFuncs.glPixelStorei(GL_PACK_SKIP_ROWS, params.SkipRows); + g_GLESFuncs.glPixelStorei(GL_PACK_SKIP_PIXELS, params.SkipPixels); + // g_GLESFuncs.glPixelStorei(GL_PACK_IMAGE_HEIGHT, params.ImageHeight); + // g_GLESFuncs.glPixelStorei(GL_PACK_SKIP_IMAGES, params.SkipImages); + // g_GLESFuncs.glPixelStorei(GL_PACK_SWAP_BYTES, params.SwapBytes ? GL_TRUE : GL_FALSE); + // g_GLESFuncs.glPixelStorei(GL_PACK_LSB_FIRST, params.LSBFirst ? GL_TRUE : GL_FALSE); } else { - MG_External::GLES::glPixelStorei(GL_UNPACK_ALIGNMENT, params.Alignment); - MG_External::GLES::glPixelStorei(GL_UNPACK_ROW_LENGTH, params.RowLength); - MG_External::GLES::glPixelStorei(GL_UNPACK_SKIP_ROWS, params.SkipRows); - MG_External::GLES::glPixelStorei(GL_UNPACK_SKIP_PIXELS, params.SkipPixels); - MG_External::GLES::glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, params.ImageHeight); - MG_External::GLES::glPixelStorei(GL_UNPACK_SKIP_IMAGES, params.SkipImages); - // MG_External::GLES::glPixelStorei(GL_UNPACK_SWAP_BYTES, params.SwapBytes ? GL_TRUE : GL_FALSE); - // MG_External::GLES::glPixelStorei(GL_UNPACK_LSB_FIRST, params.LSBFirst ? GL_TRUE : GL_FALSE); + g_GLESFuncs.glPixelStorei(GL_UNPACK_ALIGNMENT, params.Alignment); + g_GLESFuncs.glPixelStorei(GL_UNPACK_ROW_LENGTH, params.RowLength); + g_GLESFuncs.glPixelStorei(GL_UNPACK_SKIP_ROWS, params.SkipRows); + g_GLESFuncs.glPixelStorei(GL_UNPACK_SKIP_PIXELS, params.SkipPixels); + g_GLESFuncs.glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, params.ImageHeight); + g_GLESFuncs.glPixelStorei(GL_UNPACK_SKIP_IMAGES, params.SkipImages); + // g_GLESFuncs.glPixelStorei(GL_UNPACK_SWAP_BYTES, params.SwapBytes ? GL_TRUE : GL_FALSE); + // g_GLESFuncs.glPixelStorei(GL_UNPACK_LSB_FIRST, params.LSBFirst ? GL_TRUE : GL_FALSE); } } }; @@ -1266,7 +1262,7 @@ namespace MobileGL::MG_Backend::DirectGLES { MGLOG_D("ReadPixels: Applying TempPixelStoreParameterSync (PACK)"); TempPixelStoreParameterSync tempPackParamsSync(false); - GLenum fbStatus = MG_External::GLES::glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); + GLenum fbStatus = g_GLESFuncs.glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); MGLOG_D("ReadPixels: GL_READ_FRAMEBUFFER status = %s", MG_Util::ConvertGLEnumToString(fbStatus).c_str()); if (fbStatus != GL_FRAMEBUFFER_COMPLETE) { @@ -1292,32 +1288,32 @@ namespace MobileGL::MG_Backend::DirectGLES { } const auto& backendBufferObject = backendBufferIt->second; backendBufferObject->Bind(GL_PIXEL_PACK_BUFFER); - MG_External::GLES::glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, (GLint*)&prevPixelPackBuffer); + g_GLESFuncs.glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, (GLint*)&prevPixelPackBuffer); } else { usePBO = false; MGLOG_D("ReadPixels: Not using PBO"); } MGLOG_D("ReadPixels: glReadPixels()"); - MG_External::GLES::glReadPixels(x, y, width, height, format, type, pixels); + g_GLESFuncs.glReadPixels(x, y, width, height, format, type, pixels); if (usePBO) { // pull back to client memory if PBO is used MGLOG_D("ReadPixels: PBO used, mapping buffer to client memory"); - GLvoid* pboMappedPtr = MG_External::GLES::glMapBufferRange( - GL_PIXEL_PACK_BUFFER, 0, pixelPackBufferObject->GetSize(), GL_MAP_READ_BIT); + GLvoid* pboMappedPtr = g_GLESFuncs.glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, + pixelPackBufferObject->GetSize(), GL_MAP_READ_BIT); if (pboMappedPtr) { MGLOG_D("ReadPixels: Copying data from PBO to client memory"); SizeT size = pixelPackBufferObject->GetSize(); pixelPackBufferObject->UploadSubData({pboMappedPtr, size}, 0); pixelPackBufferObject->ClearDirty(); MGLOG_D("ReadPixels: Unmapping PBO"); - MG_External::GLES::glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + g_GLESFuncs.glUnmapBuffer(GL_PIXEL_PACK_BUFFER); } else { MGLOG_E("ReadPixels: glMapBufferRange returned nullptr"); MGLOG_E("ReadPixels: glMapBufferRange returned nullptr"); } MGLOG_D("ReadPixels: Restoring previous pixel pack buffer binding %u", prevPixelPackBuffer); - MG_External::GLES::glBindBuffer(GL_PIXEL_PACK_BUFFER, prevPixelPackBuffer); + g_GLESFuncs.glBindBuffer(GL_PIXEL_PACK_BUFFER, prevPixelPackBuffer); } MGLOG_D("ReadPixels: finished"); } @@ -1332,18 +1328,16 @@ namespace MobileGL::MG_Backend::DirectGLES { "Only GL_RGBA, GL_RGBA_INTEGER and GL_BGRA are supported currently, while requested %s.", MG_Util::ConvertGLEnumToString(format).c_str()); MOBILEGL_ASSERT(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT || type == GL_UNSIGNED_INT_2_10_10_10_REV || - type == GL_INT || type == GL_FLOAT || - type == GL_UNSIGNED_INT_8_8_8_8 || type == GL_UNSIGNED_INT_8_8_8_8_REV, + type == GL_INT || type == GL_FLOAT || type == GL_UNSIGNED_INT_8_8_8_8 || + type == GL_UNSIGNED_INT_8_8_8_8_REV, "Only GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, GL_UNSIGNED_INT_2_10_10_10_REV, " "GL_INT, GL_FLOAT, GL_UNSIGNED_INT_8_8_8_8 and GL_UNSIGNED_INT_8_8_8_8_REV " "are supported currently, while requested %s.", MG_Util::ConvertGLEnumToString(type).c_str()); GLenum esFormat = format, esType = type; - if (esFormat == GL_BGRA) - esFormat = GL_RGBA; - if (esType == GL_UNSIGNED_INT_8_8_8_8 || esType == GL_UNSIGNED_INT_8_8_8_8_REV) - esType = GL_UNSIGNED_BYTE; + if (esFormat == GL_BGRA) esFormat = GL_RGBA; + if (esType == GL_UNSIGNED_INT_8_8_8_8 || esType == GL_UNSIGNED_INT_8_8_8_8_REV) esType = GL_UNSIGNED_BYTE; MGLOG_D("GetTexImage: SyncNeccessaryTextures()"); TextureImpl::SyncNeccessaryTextures(); @@ -1376,12 +1370,11 @@ namespace MobileGL::MG_Backend::DirectGLES { TempFBOBinder tempFBOBinder(true); MGLOG_D("GetTexImage: glFramebufferTexture2D(level=%d)", level); - MG_External::GLES::glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, backendTexId, - level); + g_GLESFuncs.glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, backendTexId, level); MGLOG_D("GetTexImage: glReadBuffer(GL_COLOR_ATTACHMENT0)"); - MG_External::GLES::glReadBuffer(GL_COLOR_ATTACHMENT0); + g_GLESFuncs.glReadBuffer(GL_COLOR_ATTACHMENT0); - GLenum fbStatus = MG_External::GLES::glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); + GLenum fbStatus = g_GLESFuncs.glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); MGLOG_D("GetTexImage: GL_READ_FRAMEBUFFER status = %s", MG_Util::ConvertGLEnumToString(fbStatus).c_str()); if (fbStatus != GL_FRAMEBUFFER_COMPLETE) { @@ -1444,7 +1437,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } const auto& backendBufferObject = backendBufferIt->second; backendBufferObject->Bind(GL_PIXEL_PACK_BUFFER); - MG_External::GLES::glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, (GLint*)&prevPixelPackBuffer); + g_GLESFuncs.glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, (GLint*)&prevPixelPackBuffer); } else { usePBO = false; MGLOG_D("GetTexImage: Not using PBO"); @@ -1454,8 +1447,9 @@ namespace MobileGL::MG_Backend::DirectGLES { MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); MGLOG_D("GetTexImage: glReadPixels(0, 0, %d, %d, %s, %s, %p)", size.x(), size.y(), - MG_Util::ConvertGLEnumToString(esFormat).c_str(), MG_Util::ConvertGLEnumToString(esType).c_str(), pixels); - MG_External::GLES::glReadPixels(0, 0, size.x(), size.y(), esFormat, esType, pixels); + MG_Util::ConvertGLEnumToString(esFormat).c_str(), MG_Util::ConvertGLEnumToString(esType).c_str(), + pixels); + g_GLESFuncs.glReadPixels(0, 0, size.x(), size.y(), esFormat, esType, pixels); errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); @@ -1463,25 +1457,25 @@ namespace MobileGL::MG_Backend::DirectGLES { if (usePBO) { // pull back to client memory if PBO is used MGLOG_D("ReadPixels: PBO used, mapping buffer to client memory"); - GLvoid* pboMappedPtr = MG_External::GLES::glMapBufferRange( - GL_PIXEL_PACK_BUFFER, 0, pixelPackBufferObject->GetSize(), GL_MAP_READ_BIT); + GLvoid* pboMappedPtr = g_GLESFuncs.glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, + pixelPackBufferObject->GetSize(), GL_MAP_READ_BIT); if (pboMappedPtr) { MGLOG_D("ReadPixels: Copying data from PBO to client memory"); SizeT size = pixelPackBufferObject->GetSize(); pixelPackBufferObject->UploadSubData({pboMappedPtr, size}, 0); pixelPackBufferObject->ClearDirty(); MGLOG_D("ReadPixels: Unmapping PBO"); - MG_External::GLES::glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + g_GLESFuncs.glUnmapBuffer(GL_PIXEL_PACK_BUFFER); } else { MGLOG_E("ReadPixels: glMapBufferRange returned nullptr"); } MGLOG_D("ReadPixels: Restoring previous pixel pack buffer binding %u", prevPixelPackBuffer); - MG_External::GLES::glBindBuffer(GL_PIXEL_PACK_BUFFER, prevPixelPackBuffer); + g_GLESFuncs.glBindBuffer(GL_PIXEL_PACK_BUFFER, prevPixelPackBuffer); } else { - if (esFormat == GL_RGBA && format == GL_BGRA && esType == GL_UNSIGNED_BYTE && type == GL_UNSIGNED_INT_8_8_8_8_REV) { + if (esFormat == GL_RGBA && format == GL_BGRA && esType == GL_UNSIGNED_BYTE && + type == GL_UNSIGNED_INT_8_8_8_8_REV) { MGLOG_D("ReadPixels: ProcessColorSwizzle BGRA (not implemented)"); - } } @@ -1491,4 +1485,89 @@ namespace MobileGL::MG_Backend::DirectGLES { MGLOG_D("GetTexImage: finished"); } -} // namespace MobileGL::MG_Backend::DirectGLES \ No newline at end of file + void SetEGLFuncsTable(const MG_External::EGLFunctionsTable& eglFuncs) { + g_EGLFuncs = eglFuncs; + } + + void SetGLESFuncsTable(const MG_External::GLESFunctionsTable& glesFuncs) { + g_GLESFuncs = glesFuncs; + } + + void SetGLESCapabilities(const MG_External::GLESCapabilities& capabilities) { + g_GLESCapabilities = capabilities; + } + + static EGLDisplay g_Display = EGL_NO_DISPLAY; + static EGLContext g_Context = EGL_NO_CONTEXT; + static EGLSurface g_Surface = EGL_NO_SURFACE; + static EGLConfig g_Config = nullptr; + Bool InitWindowSurface(NativeWindowType window) { + // TODO: handle custom EGL paramters + if (!window) return false; + + g_Display = g_EGLFuncs.eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (g_Display == EGL_NO_DISPLAY) return false; + + if (!g_EGLFuncs.eglInitialize(g_Display, nullptr, nullptr)) return false; + g_EGLFuncs.eglBindAPI(EGL_OPENGL_ES_API); + + const EGLint configAttribs[] = {EGL_SURFACE_TYPE, + EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, + EGL_OPENGL_ES3_BIT, + EGL_RED_SIZE, + 8, + EGL_GREEN_SIZE, + 8, + EGL_BLUE_SIZE, + 8, + EGL_ALPHA_SIZE, + 8, + EGL_DEPTH_SIZE, + 24, + EGL_STENCIL_SIZE, + 8, + EGL_NONE}; + + EGLint numConfigs = 0; + if (!g_EGLFuncs.eglChooseConfig(g_Display, configAttribs, &g_Config, 1, &numConfigs) || numConfigs == 0) + return false; + + const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE}; + + g_Context = g_EGLFuncs.eglCreateContext(g_Display, g_Config, EGL_NO_CONTEXT, contextAttribs); + if (g_Context == EGL_NO_CONTEXT) return false; + + g_Surface = g_EGLFuncs.eglCreateWindowSurface(g_Display, g_Config, window, nullptr); + if (g_Surface == EGL_NO_SURFACE) return false; + + if (!g_EGLFuncs.eglMakeCurrent(g_Display, g_Surface, g_Surface, g_Context)) return false; + + MGLOG_D("EGL context created successfully: display=%p, surface=%p, context=%p. window=%p", g_Display, g_Surface, + g_Context, window); + return true; + } + + void Present() { + if (g_Display != EGL_NO_DISPLAY && g_Surface != EGL_NO_SURFACE) { + g_EGLFuncs.eglSwapBuffers(g_Display, g_Surface); + } + } + + void DestroyEGLContext() { + if (g_Display != EGL_NO_DISPLAY) { + g_EGLFuncs.eglMakeCurrent(g_Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (g_Context != EGL_NO_CONTEXT) { + g_EGLFuncs.eglDestroyContext(g_Display, g_Context); + g_Context = EGL_NO_CONTEXT; + } + if (g_Surface != EGL_NO_SURFACE) { + g_EGLFuncs.eglDestroySurface(g_Display, g_Surface); + g_Surface = EGL_NO_SURFACE; + } + g_EGLFuncs.eglTerminate(g_Display); + g_Display = EGL_NO_DISPLAY; + } + } + +} // namespace MobileGL::MG_Backend::DirectGLES diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.h b/MobileGL/MG_Backend/DirectGLES/DirectGLES.h index 4c5241cc..4b907fa1 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.h +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.h @@ -10,6 +10,7 @@ #include #include #include +#include #define CallAndCheck(operation) \ MGLOG_D("Call GLES func: %s", #operation); \ @@ -55,5 +56,14 @@ namespace MobileGL::MG_Backend::DirectGLES { const GLubyte* GetString(GLenum name); void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels); + Bool InitWindowSurface(NativeWindowType window); + void Present(); + void SetEGLFuncsTable(const MG_External::EGLFunctionsTable& eglFuncs); + void SetGLESFuncsTable(const MG_External::GLESFunctionsTable& glesFuncs); + void SetGLESCapabilities(const MG_External::GLESCapabilities& capabilities); + void DestroyEGLContext(); -} // namespace MobileGL::MG_Backend::DirectGLES \ No newline at end of file + extern MG_External::EGLFunctionsTable g_EGLFuncs; + extern MG_External::GLESFunctionsTable g_GLESFuncs; + extern MG_External::GLESCapabilities g_GLESCapabilities; +} // namespace MobileGL::MG_Backend::DirectGLES diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index f639ab63..4ad1521a 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -35,10 +35,10 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif - MG_External::GLES::glGenBuffers(1, &m_backendBufferId); + g_GLESFuncs.glGenBuffers(1, &m_backendBufferId); if (m_backendBufferId == 0) { MGLOG_E("Failed to generate buffer object."); - MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(MG_External::GLES::glGetError()).c_str()); + MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(g_GLESFuncs.glGetError()).c_str()); } else { MGLOG_D("Generated buffer object with ID: %u.", m_backendBufferId); } @@ -117,7 +117,7 @@ namespace MobileGL::MG_Backend::DirectGLES { GLenum usage = MG_Util::ConvertBufferUsageToGLEnum(stateBufferObject->GetUsage()); Bind(); - MG_External::GLES::glBufferData(TempBufferTarget, size, data, usage); + g_GLESFuncs.glBufferData(TempBufferTarget, size, data, usage); } void BackendBufferObject::SyncToBackend_glBufferSubData( @@ -138,8 +138,8 @@ namespace MobileGL::MG_Backend::DirectGLES { for (const auto& range : ranges) { Bind(); - MG_External::GLES::glBufferSubData(TempBufferTarget, range.start, range.end - range.start, - reinterpret_cast(data) + range.start); + g_GLESFuncs.glBufferSubData(TempBufferTarget, range.start, range.end - range.start, + reinterpret_cast(data) + range.start); } } @@ -159,20 +159,20 @@ namespace MobileGL::MG_Backend::DirectGLES { SizeT minStart = ranges.GetOverallMinStart(); SizeT maxEnd = ranges.GetOverallMaxEnd(); Bind(); - void* mappedData = MG_External::GLES::glMapBufferRange( - TempBufferTarget, minStart, maxEnd - minStart, - (invalidate ? GL_MAP_INVALIDATE_RANGE_BIT : 0) | (unsynchronized ? GL_MAP_UNSYNCHRONIZED_BIT : 0) | - GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); + void* mappedData = g_GLESFuncs.glMapBufferRange(TempBufferTarget, minStart, maxEnd - minStart, + (invalidate ? GL_MAP_INVALIDATE_RANGE_BIT : 0) | + (unsynchronized ? GL_MAP_UNSYNCHRONIZED_BIT : 0) | + GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); const void* data = stateBufferObject->GetDataReadOnly()->data(); if (mappedData) { MGLOG_D("Mapped buffer data successfully for object with ID: %u", m_backendBufferId); Memcpy(mappedData, reinterpret_cast(data) + minStart, maxEnd - minStart); // Explicitly flush the dirty ranges for (const auto& range : ranges) { - MG_External::GLES::glFlushMappedBufferRange(TempBufferTarget, range.start - minStart, - range.end - range.start); + g_GLESFuncs.glFlushMappedBufferRange(TempBufferTarget, range.start - minStart, + range.end - range.start); } - MG_External::GLES::glUnmapBuffer(TempBufferTarget); + g_GLESFuncs.glUnmapBuffer(TempBufferTarget); } else { MGLOG_E("Failed to map buffer with ID: %u", m_backendBufferId); } @@ -188,7 +188,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } g_boundVertexBufferObject = this; } - MG_External::GLES::glBindBuffer(target, m_backendBufferId); + g_GLESFuncs.glBindBuffer(target, m_backendBufferId); } UnorderedMap, SharedPtr> g_backendBufferObjects; @@ -200,10 +200,10 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif - MG_External::GLES::glGenVertexArrays(1, &m_backendVAOId); + g_GLESFuncs.glGenVertexArrays(1, &m_backendVAOId); if (m_backendVAOId == 0) { MGLOG_E("Failed to generate vertex array object."); - MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(MG_External::GLES::glGetError()).c_str()); + MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(g_GLESFuncs.glGetError()).c_str()); } else { MGLOG_D("Generated vertex array object with ID: %u.", m_backendVAOId); } @@ -213,7 +213,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif - MG_External::GLES::glBindVertexArray(m_backendVAOId); + g_GLESFuncs.glBindVertexArray(m_backendVAOId); } void BackendVertexArrayObject::BindAttributeBuffer(Uint index, @@ -256,9 +256,9 @@ namespace MobileGL::MG_Backend::DirectGLES { m_syncedAttributeVersions[attribIndex].SwitchVersion; if (needsSyncSwitch) { if (attrib.Enabled) { - MG_External::GLES::glEnableVertexAttribArray(attribIndex); + g_GLESFuncs.glEnableVertexAttribArray(attribIndex); } else { - MG_External::GLES::glDisableVertexAttribArray(attribIndex); + g_GLESFuncs.glDisableVertexAttribArray(attribIndex); } } @@ -271,17 +271,17 @@ namespace MobileGL::MG_Backend::DirectGLES { BindAttributeBuffer(attribIndex, attrib); if (!attrib.IsInteger) { - MG_External::GLES::glVertexAttribPointer( + g_GLESFuncs.glVertexAttribPointer( attribIndex, attrib.Size, MG_Util::ConvertDataTypeToGLEnum(attrib.Type), attrib.Normalized ? GL_TRUE : GL_FALSE, attrib.Stride, (const void*)attrib.Offset); } else { - MG_External::GLES::glVertexAttribIPointer(attribIndex, attrib.Size, - MG_Util::ConvertDataTypeToGLEnum(attrib.Type), - attrib.Stride, (const void*)attrib.Offset); + g_GLESFuncs.glVertexAttribIPointer(attribIndex, attrib.Size, + MG_Util::ConvertDataTypeToGLEnum(attrib.Type), attrib.Stride, + (const void*)attrib.Offset); } if (needsSyncFormat) { - MG_External::GLES::glVertexAttribDivisor(attribIndex, attrib.Divisor); + g_GLESFuncs.glVertexAttribDivisor(attribIndex, attrib.Divisor); } } @@ -312,10 +312,10 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif - MG_External::GLES::glGenTextures(1, &m_backendTextureId); + g_GLESFuncs.glGenTextures(1, &m_backendTextureId); if (m_backendTextureId == 0) { MGLOG_E("Failed to generate texture object."); - MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(MG_External::GLES::glGetError()).c_str()); + MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(g_GLESFuncs.glGetError()).c_str()); } else { MGLOG_D("Generated texture object with ID: %u.", m_backendTextureId); } @@ -332,7 +332,7 @@ namespace MobileGL::MG_Backend::DirectGLES { auto targetN = static_cast(MG_Util::ConvertGLEnumToTextureTarget(target)); if (this == g_boundTexturesCache[unit][targetN]) return; - MG_External::GLES::glBindTexture(target, m_backendTextureId); + g_GLESFuncs.glBindTexture(target, m_backendTextureId); g_boundTexturesCache[unit][targetN] = this; } @@ -430,20 +430,20 @@ namespace MobileGL::MG_Backend::DirectGLES { levelDirty ? "true" : "false"); errorLopper.Clear(); - MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + g_GLESFuncs.glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); auto textureTarget = stateTextureObject->GetTarget(); // TODO: handle more texture types switch (textureTarget) { case TextureTarget::Texture2D: case TextureTarget::TextureCubeMap: { - MG_External::GLES::glTexImage2D( - glUploadTarget, static_cast(level), glInternalFormat, - static_cast(levelTexelSize.x()), static_cast(levelTexelSize.y()), - 0, glFormat, glType, pData); + g_GLESFuncs.glTexImage2D(glUploadTarget, static_cast(level), glInternalFormat, + static_cast(levelTexelSize.x()), + static_cast(levelTexelSize.y()), 0, glFormat, glType, + pData); break; } case TextureTarget::Texture3D: { - MG_External::GLES::glTexImage3D( + g_GLESFuncs.glTexImage3D( glUploadTarget, static_cast(level), glInternalFormat, static_cast(levelTexelSize.x()), static_cast(levelTexelSize.y()), static_cast(levelTexelSize.z()), 0, glFormat, glType, pData); @@ -498,16 +498,16 @@ namespace MobileGL::MG_Backend::DirectGLES { textureMipmapObject->GetMipmapTexelSize(uploadTarget, level).y(), byteSize); auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget); - MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + g_GLESFuncs.glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); auto texelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level); - MG_External::GLES::glTexSubImage2D(glUploadTarget, static_cast(level), 0, 0, - static_cast(texelSize.x()), - static_cast(texelSize.y()), glFormat, glType, - textureMipmapObject->MapMipmapData(uploadTarget, level)); + g_GLESFuncs.glTexSubImage2D(glUploadTarget, static_cast(level), 0, 0, + static_cast(texelSize.x()), + static_cast(texelSize.y()), glFormat, glType, + textureMipmapObject->MapMipmapData(uploadTarget, level)); textureMipmapObject->MarkStorageDirty(uploadTarget, level, false); } } @@ -546,7 +546,7 @@ namespace MobileGL::MG_Backend::DirectGLES { TextureImpl::GenerateTextureFormatInfo(textureBufferObject->GetFormat(), &glInternalFormat, &glFormat, &glType); - MG_External::GLES::glTexBuffer(GL_TEXTURE_BUFFER, glInternalFormat, backendId); + g_GLESFuncs.glTexBuffer(GL_TEXTURE_BUFFER, glInternalFormat, backendId); break; } default: @@ -604,8 +604,8 @@ namespace MobileGL::MG_Backend::DirectGLES { #define SYNC_TEX_SAMPLER_PARAM_IF_CHANGED(internalName, glName, type) \ if (m_cacheSamplerParameters.internalName != samplerParams.internalName) { \ - MG_External::GLES::glTexParameteri(target, glName, \ - MG_Util::ConvertSampler##type##ToGLEnum(samplerParams.internalName)); \ + g_GLESFuncs.glTexParameteri(target, glName, \ + MG_Util::ConvertSampler##type##ToGLEnum(samplerParams.internalName)); \ m_cacheSamplerParameters.internalName = samplerParams.internalName; \ errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__, \ t = MG_Util::ConvertSampler##type##ToGLEnum(samplerParams.internalName)](GLenum err) { \ @@ -616,14 +616,14 @@ namespace MobileGL::MG_Backend::DirectGLES { if (m_cacheSamplerParameters.minFilter != samplerParams.minFilter || m_cacheSamplerParameters.mipmapMode != samplerParams.mipmapMode) { - MG_External::GLES::glTexParameteri( + g_GLESFuncs.glTexParameteri( target, GL_TEXTURE_MIN_FILTER, MG_Util::ConvertSamplerFilterModeToGLEnum(samplerParams.minFilter, samplerParams.mipmapMode)); m_cacheSamplerParameters.minFilter = samplerParams.minFilter; m_cacheSamplerParameters.mipmapMode = samplerParams.mipmapMode; } if (m_cacheSamplerParameters.magFilter != samplerParams.magFilter) { - MG_External::GLES::glTexParameteri( + g_GLESFuncs.glTexParameteri( target, GL_TEXTURE_MAG_FILTER, MG_Util::ConvertSamplerFilterModeToGLEnum(samplerParams.magFilter, SamplerMipmapMode::None)); m_cacheSamplerParameters.magFilter = samplerParams.magFilter; @@ -638,11 +638,11 @@ namespace MobileGL::MG_Backend::DirectGLES { SYNC_TEX_SAMPLER_PARAM_IF_CHANGED(compareFunc, GL_TEXTURE_COMPARE_FUNC, CompareFunc) SYNC_TEX_SAMPLER_PARAM_IF_CHANGED(compareMode, GL_TEXTURE_COMPARE_MODE, CompareMode) if (m_cacheSamplerParameters.minLod != samplerParams.minLod) { - MG_External::GLES::glTexParameterf(target, GL_TEXTURE_MIN_LOD, samplerParams.minLod); + g_GLESFuncs.glTexParameterf(target, GL_TEXTURE_MIN_LOD, samplerParams.minLod); m_cacheSamplerParameters.minLod = samplerParams.minLod; } if (m_cacheSamplerParameters.maxLod != samplerParams.maxLod) { - MG_External::GLES::glTexParameterf(target, GL_TEXTURE_MAX_LOD, samplerParams.maxLod); + g_GLESFuncs.glTexParameterf(target, GL_TEXTURE_MAX_LOD, samplerParams.maxLod); m_cacheSamplerParameters.maxLod = samplerParams.maxLod; } errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { @@ -693,14 +693,14 @@ namespace MobileGL::MG_Backend::DirectGLES { const auto& levelRange = stateTextureObject->GetLevelRange(); if (m_cacheLodRange.x() != levelRange.x()) { - MG_External::GLES::glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, static_cast(levelRange.x())); + g_GLESFuncs.glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, static_cast(levelRange.x())); m_cacheLodRange.x() = levelRange.x(); } errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); if (m_cacheLodRange.y() != levelRange.y()) { - MG_External::GLES::glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, static_cast(levelRange.y())); + g_GLESFuncs.glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, static_cast(levelRange.y())); m_cacheLodRange.y() = levelRange.y(); } errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { @@ -711,8 +711,7 @@ namespace MobileGL::MG_Backend::DirectGLES { if (swizzleParams != m_cacheSwizzleParams) { #define SYNC_TEX_SWIZZLE_PARAM_IF_CHANGED(func, glEnum) \ if (m_cacheSwizzleParams.func != swizzleParams.func) { \ - MG_External::GLES::glTexParameteri(target, glEnum, \ - MG_Util::ConvertTextureSwizzleParamToGLEnum(swizzleParams.func)); \ + g_GLESFuncs.glTexParameteri(target, glEnum, MG_Util::ConvertTextureSwizzleParamToGLEnum(swizzleParams.func)); \ m_cacheSwizzleParams.func = swizzleParams.func; \ } SYNC_TEX_SWIZZLE_PARAM_IF_CHANGED(r(), GL_TEXTURE_SWIZZLE_R); @@ -729,7 +728,7 @@ namespace MobileGL::MG_Backend::DirectGLES { if (m_cacheBorderColor != stateTextureObject->GetBorderColor()) { const auto& borderColor = stateTextureObject->GetBorderColor(); GLfloat borderColorArray[4] = {borderColor.x(), borderColor.y(), borderColor.z(), borderColor.w()}; - MG_External::GLES::glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, borderColorArray); + g_GLESFuncs.glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, borderColorArray); m_cacheBorderColor = borderColor; errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); @@ -741,7 +740,7 @@ namespace MobileGL::MG_Backend::DirectGLES { if (unit == g_activeTextureUnit) { return; } - MG_External::GLES::glActiveTexture(GL_TEXTURE0 + unit); + g_GLESFuncs.glActiveTexture(GL_TEXTURE0 + unit); g_activeTextureUnit = unit; } @@ -753,7 +752,7 @@ namespace MobileGL::MG_Backend::DirectGLES { auto targetN = static_cast(MG_Util::ConvertGLEnumToTextureTarget(target)); if (g_boundTexturesCache[unit][targetN] == nullptr) return; - MG_External::GLES::glBindTexture(target, 0); + g_GLESFuncs.glBindTexture(target, 0); g_boundTexturesCache[unit][targetN] = nullptr; } @@ -770,10 +769,10 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif - MG_External::GLES::glGenFramebuffers(1, &m_backendFBOId); + g_GLESFuncs.glGenFramebuffers(1, &m_backendFBOId); if (m_backendFBOId == 0) { MGLOG_E("Failed to generate framebuffer object."); - MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(MG_External::GLES::glGetError()).c_str()); + MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(g_GLESFuncs.glGetError()).c_str()); } else { MGLOG_D("Generated framebuffer object with ID: %u.", m_backendFBOId); } @@ -784,9 +783,9 @@ namespace MobileGL::MG_Backend::DirectGLES { ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif if (target == FramebufferTarget::Read) - MG_External::GLES::glBindFramebuffer(GL_READ_FRAMEBUFFER, m_backendFBOId); + g_GLESFuncs.glBindFramebuffer(GL_READ_FRAMEBUFFER, m_backendFBOId); else - MG_External::GLES::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_backendFBOId); + g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_backendFBOId); } Bool BackendFramebufferObject::SyncAttachmentObject( @@ -802,9 +801,9 @@ namespace MobileGL::MG_Backend::DirectGLES { const auto& backendTextureObject = backendTextureIt->second; auto glTextureTarget = MG_Util::ConvertTextureTargetToGLEnum(textureObject->GetTarget()); backendTextureObject->Bind(glTextureTarget); - MG_External::GLES::glFramebufferTexture2D(glFBOTarget, glBackendAttachment, glTextureTarget, - backendTextureObject->GetBackendTextureId(), - static_cast(attachmentObject.GetTextureLevel())); + g_GLESFuncs.glFramebufferTexture2D(glFBOTarget, glBackendAttachment, glTextureTarget, + backendTextureObject->GetBackendTextureId(), + static_cast(attachmentObject.GetTextureLevel())); } else if (attachmentObject.IsRenderbuffer()) { const auto& renderbufferObject = attachmentObject.GetRenderbuffer(); const auto& backendRenderbufferIt = @@ -819,8 +818,8 @@ namespace MobileGL::MG_Backend::DirectGLES { backendRenderbufferObject->SyncToBackend(renderbufferObject); backendRenderbufferObject->Bind(); - MG_External::GLES::glFramebufferRenderbuffer(glFBOTarget, glBackendAttachment, GL_RENDERBUFFER, - backendRenderbufferObject->GetBackendRenderbufferId()); + g_GLESFuncs.glFramebufferRenderbuffer(glFBOTarget, glBackendAttachment, GL_RENDERBUFFER, + backendRenderbufferObject->GetBackendRenderbufferId()); } return true; } @@ -872,7 +871,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } nEffectiveBuffers = i + 1; } - MG_External::GLES::glDrawBuffers(nEffectiveBuffers, m_backendDrawBuffers); + g_GLESFuncs.glDrawBuffers(nEffectiveBuffers, m_backendDrawBuffers); } // 2. Remap read buffer @@ -884,7 +883,7 @@ namespace MobileGL::MG_Backend::DirectGLES { if (m_backendReadBuffer != glBackendReadBuffer) { m_backendReadBuffer = glBackendReadBuffer; - MG_External::GLES::glReadBuffer(glBackendReadBuffer); + g_GLESFuncs.glReadBuffer(glBackendReadBuffer); } } @@ -917,14 +916,14 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Util::ConvertGLEnumToString(glBackendAttachment).c_str(), m_syncedFrontendAttachmentVersions[i]); GLint objectType = GL_NONE; - MG_External::GLES::glGetFramebufferAttachmentParameteriv( + g_GLESFuncs.glGetFramebufferAttachmentParameteriv( glFBOTarget, glBackendAttachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &objectType); MOBILEGL_ASSERT((objectType == GL_NONE) || (attachmentObject.IsTexture() && objectType == GL_TEXTURE) || (attachmentObject.IsRenderbuffer() && objectType == GL_RENDERBUFFER), "Attachment type not match!"); GLint objectName = 0; - MG_External::GLES::glGetFramebufferAttachmentParameteriv( + g_GLESFuncs.glGetFramebufferAttachmentParameteriv( glFBOTarget, glBackendAttachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &objectName); // Verify that the backend object's name and parameters match the frontend attachment state if (attachmentObject.IsTexture()) { @@ -939,7 +938,7 @@ namespace MobileGL::MG_Backend::DirectGLES { objectName, backendTexId, textureObject->GetExternalIndex()); GLint texLevel = 0; - MG_External::GLES::glGetFramebufferAttachmentParameteriv( + g_GLESFuncs.glGetFramebufferAttachmentParameteriv( glFBOTarget, glBackendAttachment, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &texLevel); MOBILEGL_ASSERT(texLevel == static_cast(attachmentObject.GetTextureLevel()), "Attachment texture level mismatch between GLES and state object."); @@ -989,10 +988,10 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif - m_backendProgramId = MG_External::GLES::glCreateProgram(); + m_backendProgramId = g_GLESFuncs.glCreateProgram(); if (m_backendProgramId == 0) { MGLOG_E("Failed to create program object in backend."); - MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(MG_External::GLES::glGetError()).c_str()); + MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(g_GLESFuncs.glGetError()).c_str()); } else { MGLOG_D("Created backend program object with ID: %u", m_backendProgramId); @@ -1005,7 +1004,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #endif if (m_backendProgramId != 0) { MGLOG_D("Deleting backend program object with ID: %u", m_backendProgramId); - MG_External::GLES::glDeleteProgram(m_backendProgramId); + g_GLESFuncs.glDeleteProgram(m_backendProgramId); } } @@ -1029,19 +1028,19 @@ namespace MobileGL::MG_Backend::DirectGLES { // Detach all existing shaders GLint attachedCount = 0; - MG_External::GLES::glGetProgramiv(m_backendProgramId, GL_ATTACHED_SHADERS, &attachedCount); + g_GLESFuncs.glGetProgramiv(m_backendProgramId, GL_ATTACHED_SHADERS, &attachedCount); MGLOG_D("Currently attached shaders count: %d", attachedCount); if (attachedCount > 0) { Vector attachedShaders(attachedCount); GLsizei actualCount; - MG_External::GLES::glGetAttachedShaders(m_backendProgramId, attachedCount, &actualCount, - attachedShaders.data()); + g_GLESFuncs.glGetAttachedShaders(m_backendProgramId, attachedCount, &actualCount, + attachedShaders.data()); MGLOG_D("Detaching %d existing shaders from program %u", actualCount, m_backendProgramId); for (GLsizei i = 0; i < actualCount; ++i) { MGLOG_D("Detaching shader ID: %u from program %u", attachedShaders[i], m_backendProgramId); - MG_External::GLES::glDetachShader(m_backendProgramId, attachedShaders[i]); + g_GLESFuncs.glDetachShader(m_backendProgramId, attachedShaders[i]); } } @@ -1060,7 +1059,7 @@ namespace MobileGL::MG_Backend::DirectGLES { for (int index = 0; index < attachedShaders.size(); ++index) { auto& shader = attachedShaders[index]; GLenum glShaderType = MG_Util::ConvertShaderStageToGLEnum(shader->GetShaderStage()); - GLuint backendShaderId = MG_External::GLES::glCreateShader(glShaderType); + GLuint backendShaderId = g_GLESFuncs.glCreateShader(glShaderType); if (backendShaderId == 0) { MGLOG_E("Failed to create backend shader for attachment."); @@ -1111,37 +1110,37 @@ namespace MobileGL::MG_Backend::DirectGLES { const char* sourceCStr = source.c_str(); MGLOG_D("Setting shader source for backend shader ID: %u\nsrc:\n%s", backendShaderId, sourceCStr); - MG_External::GLES::glShaderSource(backendShaderId, 1, &sourceCStr, nullptr); - MG_External::GLES::glCompileShader(backendShaderId); + g_GLESFuncs.glShaderSource(backendShaderId, 1, &sourceCStr, nullptr); + g_GLESFuncs.glCompileShader(backendShaderId); GLint compileStatus; - MG_External::GLES::glGetShaderiv(backendShaderId, GL_COMPILE_STATUS, &compileStatus); + g_GLESFuncs.glGetShaderiv(backendShaderId, GL_COMPILE_STATUS, &compileStatus); if (compileStatus == GL_FALSE) { GLint logLength; - MG_External::GLES::glGetShaderiv(backendShaderId, GL_INFO_LOG_LENGTH, &logLength); + g_GLESFuncs.glGetShaderiv(backendShaderId, GL_INFO_LOG_LENGTH, &logLength); Vector log(logLength); - MG_External::GLES::glGetShaderInfoLog(backendShaderId, logLength, nullptr, log.data()); + g_GLESFuncs.glGetShaderInfoLog(backendShaderId, logLength, nullptr, log.data()); MGLOG_E("Shader compilation failed for backend ID %u: %s", backendShaderId, log.data()); continue; } MGLOG_D("Attaching shader ID: %u to program %u", backendShaderId, m_backendProgramId); - MG_External::GLES::glAttachShader(m_backendProgramId, backendShaderId); + g_GLESFuncs.glAttachShader(m_backendProgramId, backendShaderId); MGLOG_D("Processed shader source length: %zu", source.length()); } // Link program MGLOG_D("Linking program %u", m_backendProgramId); - MG_External::GLES::glLinkProgram(m_backendProgramId); + g_GLESFuncs.glLinkProgram(m_backendProgramId); GLint linkStatus; - MG_External::GLES::glGetProgramiv(m_backendProgramId, GL_LINK_STATUS, &linkStatus); + g_GLESFuncs.glGetProgramiv(m_backendProgramId, GL_LINK_STATUS, &linkStatus); if (linkStatus != GL_TRUE) { GLint logLength; - MG_External::GLES::glGetProgramiv(m_backendProgramId, GL_INFO_LOG_LENGTH, &logLength); + g_GLESFuncs.glGetProgramiv(m_backendProgramId, GL_INFO_LOG_LENGTH, &logLength); Vector log(logLength); - MG_External::GLES::glGetProgramInfoLog(m_backendProgramId, logLength, nullptr, log.data()); + g_GLESFuncs.glGetProgramInfoLog(m_backendProgramId, logLength, nullptr, log.data()); MGLOG_E("Program %u linking failed for %u: %s", stateProgramObject->GetExternalIndex(), m_backendProgramId, log.data()); } else { @@ -1150,11 +1149,10 @@ namespace MobileGL::MG_Backend::DirectGLES { // Create global UBO if (stateProgramObject->GetUBOSize() > 0) { - MG_External::GLES::glGenBuffers(1, &m_backendGlobalUBOId); - MG_External::GLES::glBindBuffer(GL_UNIFORM_BUFFER, m_backendGlobalUBOId); - MG_External::GLES::glBufferData(GL_UNIFORM_BUFFER, stateProgramObject->GetUBOSize(), nullptr, - GL_STREAM_DRAW); - MG_External::GLES::glBindBuffer(GL_UNIFORM_BUFFER, 0); + g_GLESFuncs.glGenBuffers(1, &m_backendGlobalUBOId); + g_GLESFuncs.glBindBuffer(GL_UNIFORM_BUFFER, m_backendGlobalUBOId); + g_GLESFuncs.glBufferData(GL_UNIFORM_BUFFER, stateProgramObject->GetUBOSize(), nullptr, GL_STREAM_DRAW); + g_GLESFuncs.glBindBuffer(GL_UNIFORM_BUFFER, 0); } else { m_backendGlobalUBOId = 0; } @@ -1168,7 +1166,7 @@ namespace MobileGL::MG_Backend::DirectGLES { ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif MGLOG_D("Using program %u", m_backendProgramId); - MG_External::GLES::glUseProgram(m_backendProgramId); + g_GLESFuncs.glUseProgram(m_backendProgramId); } } // namespace PrgramImpl @@ -1177,10 +1175,10 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif - MG_External::GLES::glGenSamplers(1, &m_backendSamplerId); + g_GLESFuncs.glGenSamplers(1, &m_backendSamplerId); if (m_backendSamplerId == 0) { MGLOG_E("Failed to generate sampler object."); - MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(MG_External::GLES::glGetError()).c_str()); + MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(g_GLESFuncs.glGetError()).c_str()); } else { MGLOG_D("Generated sampler object with ID: %u.", m_backendSamplerId); } @@ -1211,21 +1209,21 @@ namespace MobileGL::MG_Backend::DirectGLES { #define SYNC_SAMPLER_PARAM_IF_CHANGED(internalName, glName, type) \ if (m_cacheSamplerParameters.internalName != samplerParams.internalName) { \ - MG_External::GLES::glSamplerParameteri(m_backendSamplerId, glName, \ - MG_Util::ConvertSampler##type##ToGLEnum(samplerParams.internalName)); \ + g_GLESFuncs.glSamplerParameteri(m_backendSamplerId, glName, \ + MG_Util::ConvertSampler##type##ToGLEnum(samplerParams.internalName)); \ m_cacheSamplerParameters.internalName = samplerParams.internalName; \ } if (m_cacheSamplerParameters.minFilter != samplerParams.minFilter || m_cacheSamplerParameters.mipmapMode != samplerParams.mipmapMode) { - MG_External::GLES::glSamplerParameteri( + g_GLESFuncs.glSamplerParameteri( m_backendSamplerId, GL_TEXTURE_MIN_FILTER, MG_Util::ConvertSamplerFilterModeToGLEnum(samplerParams.minFilter, samplerParams.mipmapMode)); m_cacheSamplerParameters.minFilter = samplerParams.minFilter; m_cacheSamplerParameters.mipmapMode = samplerParams.mipmapMode; } if (m_cacheSamplerParameters.magFilter != samplerParams.magFilter) { - MG_External::GLES::glSamplerParameteri( + g_GLESFuncs.glSamplerParameteri( m_backendSamplerId, GL_TEXTURE_MAG_FILTER, MG_Util::ConvertSamplerFilterModeToGLEnum(samplerParams.magFilter, SamplerMipmapMode::None)); m_cacheSamplerParameters.magFilter = samplerParams.magFilter; @@ -1237,11 +1235,11 @@ namespace MobileGL::MG_Backend::DirectGLES { SYNC_SAMPLER_PARAM_IF_CHANGED(compareFunc, GL_TEXTURE_COMPARE_FUNC, CompareFunc) SYNC_SAMPLER_PARAM_IF_CHANGED(compareMode, GL_TEXTURE_COMPARE_MODE, CompareMode) if (m_cacheSamplerParameters.minLod != samplerParams.minLod) { - MG_External::GLES::glSamplerParameterf(m_backendSamplerId, GL_TEXTURE_MIN_LOD, samplerParams.minLod); + g_GLESFuncs.glSamplerParameterf(m_backendSamplerId, GL_TEXTURE_MIN_LOD, samplerParams.minLod); m_cacheSamplerParameters.minLod = samplerParams.minLod; } if (m_cacheSamplerParameters.maxLod != samplerParams.maxLod) { - MG_External::GLES::glSamplerParameterf(m_backendSamplerId, GL_TEXTURE_MAX_LOD, samplerParams.maxLod); + g_GLESFuncs.glSamplerParameterf(m_backendSamplerId, GL_TEXTURE_MAX_LOD, samplerParams.maxLod); m_cacheSamplerParameters.maxLod = samplerParams.maxLod; } #undef SYNC_SAMPLER_PARAM_IF_CHANGED @@ -1254,7 +1252,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #endif if (g_boundSamplersCache[unit] == this) return; - MG_External::GLES::glBindSampler(static_cast(unit), m_backendSamplerId); + g_GLESFuncs.glBindSampler(static_cast(unit), m_backendSamplerId); g_boundSamplersCache[unit] = this; } @@ -1268,7 +1266,7 @@ namespace MobileGL::MG_Backend::DirectGLES { void UnbindSampler(Uint unit) { if (g_boundSamplersCache[unit] == nullptr) return; - MG_External::GLES::glBindSampler(static_cast(unit), 0); + g_GLESFuncs.glBindSampler(static_cast(unit), 0); g_boundSamplersCache[unit] = nullptr; } @@ -1282,10 +1280,10 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif - MG_External::GLES::glGenRenderbuffers(1, &m_backendRBOId); + g_GLESFuncs.glGenRenderbuffers(1, &m_backendRBOId); if (m_backendRBOId == 0) { MGLOG_E("Failed to generate renderbuffer object."); - MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(MG_External::GLES::glGetError()).c_str()); + MGLOG_E("ES glGetError(): %s", MG_Util::ConvertGLEnumToString(g_GLESFuncs.glGetError()).c_str()); } } @@ -1293,7 +1291,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif - MG_External::GLES::glBindRenderbuffer(GL_RENDERBUFFER, m_backendRBOId); + g_GLESFuncs.glBindRenderbuffer(GL_RENDERBUFFER, m_backendRBOId); } void BackendRenderbufferObject::SyncToBackend( @@ -1325,8 +1323,8 @@ namespace MobileGL::MG_Backend::DirectGLES { GLenum glInternalFormat, glType, glFormat; TextureImpl::GenerateTextureFormatInfo(internalFormat, &glInternalFormat, &glFormat, &glType); - MG_External::GLES::glRenderbufferStorage(GL_RENDERBUFFER, glInternalFormat, static_cast(width), - static_cast(height)); + g_GLESFuncs.glRenderbufferStorage(GL_RENDERBUFFER, glInternalFormat, static_cast(width), + static_cast(height)); m_cacheInternalFormat = internalFormat; m_cacheWidth = width; diff --git a/MobileGL/MG_Backend/DirectGLES/Utils.cpp b/MobileGL/MG_Backend/DirectGLES/Utils.cpp index 8c528ee7..0ec96fea 100644 --- a/MobileGL/MG_Backend/DirectGLES/Utils.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Utils.cpp @@ -30,8 +30,8 @@ namespace MobileGL::MG_Backend::DirectGLES { ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif using namespace MobileGL::MG_Util::TextureFormatProcessor; - auto options = (MG_External::GLES::g_glesCaps.hasNorm16Texture) ? PixelFormatNormalizeOptionBit::None - : PixelFormatNormalizeOptionBit::NoNorm16; + auto options = (g_GLESCapabilities.SupportsNorm16Texture) ? PixelFormatNormalizeOptionBit::None + : PixelFormatNormalizeOptionBit::NoNorm16; NormalizePixelFormat(MG_Util::ConvertTextureInternalFormatToGLEnum(internalFormat), options, outInternalFormat, outFormat, outType); } @@ -125,7 +125,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif - while (GLenum err = MG_External::GLES::glGetError() != GL_NO_ERROR) { + while (GLenum err = g_GLESFuncs.glGetError() != GL_NO_ERROR) { MGLOG_E("-> GLES Error: %s", MG_Util::ConvertGLEnumToString(err).c_str()); } } diff --git a/MobileGL/MG_Backend/Init.cpp b/MobileGL/MG_Backend/Init.cpp index 2530e531..67a8a466 100644 --- a/MobileGL/MG_Backend/Init.cpp +++ b/MobileGL/MG_Backend/Init.cpp @@ -6,83 +6,63 @@ // SPDX-License-Identifier: LGPL-3.0-only // End of Source File Header -#include "Backends.h" -#include "MG_Util/Types.h" +#include "BackendObjects.h" #include #include #include -namespace MobileGL { - namespace MG_Config { - UniquePtr RendererInfoPtr = nullptr; - } // namespace MG_Config - - namespace MG_Backend { - void LogBackendInfo() { - if (MG_Config::RendererInfoPtr) { - MGLOG_I("MobileGL Backend Info:"); - MGLOG_I(" Renderer Name: %s", MG_Config::RendererInfoPtr->RendererName.c_str()); - MGLOG_I(" Backend Name: %s", MG_Config::RendererInfoPtr->BackendName.c_str()); - if (MG_Config::RendererInfoPtr->ExtraVendor) { - MGLOG_I(" Extra Vendor Info: %s", MG_Config::RendererInfoPtr->ExtraVendor->c_str()); - } - MGLOG_I(" Target OpenGL Version: %d.%d", - MG_Config::RendererInfoPtr->RendererGLInfo.TargetGLVersion.Major, - MG_Config::RendererInfoPtr->RendererGLInfo.TargetGLVersion.Minor); - MGLOG_I(" Target GLSL Version: %d.%d", - MG_Config::RendererInfoPtr->RendererGLInfo.TargetGLSLVersion.Major, - MG_Config::RendererInfoPtr->RendererGLInfo.TargetGLSLVersion.Minor); - MGLOG_I(" OpenGL Extensions:"); - for (const auto& ext : MG_Config::RendererInfoPtr->RendererGLInfo.Extensions) { - MGLOG_I(" - %s", MG_Util::ConvertGLExtToString(ext).c_str()); - } - } else { - MGLOG_W(" No renderer info available"); - } +namespace MobileGL::MG_Backend { + void LogBackendInfo() { + if (!pActiveBackendObject) { + MGLOG_W("No active backend object, cannot log backend info"); + return; } - Bool InitSpecificBackendLibs() { -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_DILIGENT - // Nothing to do - MGLOG_D("Diligent Engine backend loaded"); - return true; -#elif MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - Bool result = MG_Util::BackendLoader::GLES::Init(); - MGLOG_D("DirectGLES backend loaded, GLES version: %d.%d", MG_External::GLES::g_glesCaps.version.Major, - MG_External::GLES::g_glesCaps.version.Minor); - return result; -#else - MGLOG_W("Unknown backend, skipping backend initialization"); + const auto& rendererInfo = pActiveBackendObject->GetRendererInfo(); + MGLOG_I("MobileGL Backend Info:"); + MGLOG_I(" Renderer Name: %s", rendererInfo.RendererName.c_str()); + MGLOG_I(" Backend Name: %s", rendererInfo.BackendName.c_str()); + if (rendererInfo.ExtraVendor) { + MGLOG_I(" Extra Vendor Info: %s", rendererInfo.ExtraVendor->c_str()); + } + MGLOG_I(" Target OpenGL Version: %d.%d", rendererInfo.RendererGLInfo.TargetGLVersion.Major, + rendererInfo.RendererGLInfo.TargetGLVersion.Minor); + MGLOG_I(" Target GLSL Version: %d.%d", rendererInfo.RendererGLInfo.TargetGLSLVersion.Major, + rendererInfo.RendererGLInfo.TargetGLSLVersion.Minor); + MGLOG_I(" OpenGL Extensions:"); + for (const auto& ext : rendererInfo.RendererGLInfo.Extensions) { + MGLOG_I(" - %s", MG_Util::ConvertGLExtToString(ext).c_str()); + } + } + + Bool InitSpecificBackendLibs() { + if (!pActiveBackendObject) { + MGLOG_W("No active backend object, cannot initialize backend libraries"); return false; -#endif + } + pActiveBackendObject->Initialize(); + gBackendFunctionsTable = pActiveBackendObject->GetBackendFunctions(); + return true; + } + + void Init() { + MGLOG_D("Initializing MobileGL Backend..."); + + switch (MG_Config::ActiveBackendType) { + case BackendType::DirectGLES: + pActiveBackendObject = MakeUnique(); + break; + case BackendType::Unknown: + default: + MGLOG_W("Unknown backend type, defaulting to unknown backend"); + pActiveBackendObject = nullptr; } - void Init() { - MGLOG_D("Initializing MobileGL Backend..."); - -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_DILIGENT - switch (MG_Config::Backend::Diligent::SpecificBackend) { - case MG_Backend::Diligent::SpecificBackendType::Vulkan: - MG_Config::RendererInfoPtr = MakeUnique(Diligent::RendererInfoVulkan); - break; - case MG_Backend::Diligent::SpecificBackendType::Metal: - MG_Config::RendererInfoPtr = MakeUnique(Diligent::RendererInfoMetal); - break; - default: - throw RuntimeError("Unsupported renderer type"); - } -#elif MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Config::RendererInfoPtr = MakeUnique(DirectGLES::RendererInfo); -#else - MG_Config::RendererInfoPtr = MakeUnique(Unknown::RendererInfoUnknown); -#endif - - Bool result = InitSpecificBackendLibs(); - if (!result) { - MGLOG_W("Failed to initialize MobileGL backend libraries"); - return; - } - LogBackendInfo(); + Bool result = InitSpecificBackendLibs(); + if (!result) { + MGLOG_W("Failed to initialize MobileGL backend libraries"); + return; } - } // namespace MG_Backend -} // namespace MobileGL \ No newline at end of file + LogBackendInfo(); + } +} // namespace MobileGL::MG_Backend diff --git a/MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp b/MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp new file mode 100644 index 00000000..ef904cd7 --- /dev/null +++ b/MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp @@ -0,0 +1,253 @@ +// MobileGL - MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp +// Copyright (c) 2025-2026 MobileGL-Dev +// Licensed under the GNU Lesser General Public License v3.0: +// https://www.gnu.org/licenses/gpl-3.0.txt +// https://www.gnu.org/licenses/lgpl-3.0.txt +// SPDX-License-Identifier: LGPL-3.0-only +// End of Source File Header + +#include "EGLImpl.h" +#include "EGL/egl.h" +#include + +namespace MobileGL::MG_Impl::EGLImpl { + EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, + const EGLint* attrib_list) { + MGLOG_D("EGLImpl::CreateWindowSurface called with window=%p", window); + const auto& activeBackendObject = MG_Backend::pActiveBackendObject; + if (!activeBackendObject) { + MGLOG_E("activeBackendObject not initialized!"); + return EGL_NO_SURFACE; + } + activeBackendObject->SetWindowHandle({MG_Backend::WindowBackend::Android, reinterpret_cast(window)}); + activeBackendObject->InitWindowSurface(); + glClearColor(1, 1, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); + SwapBuffers((EGLDisplay)1, (EGLSurface)1); + return (EGLSurface)1; + } + + EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface draw) { + MGLOG_D("EGLImpl::SwapBuffers called with dpy=%p", dpy); + if (!MG_Backend::gBackendFunctionsTable.Present) { + MGLOG_E("MG_Backend::gBackendFunctionsTable.Present not initialized!"); + return EGL_FALSE; + } + MG_Backend::gBackendFunctionsTable.Present(); + return EGL_TRUE; + } + + EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, + EGLint* num_config) { + *num_config = 1; + return EGL_TRUE; + } + + EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareCtx, const EGLint* attrib_list) { + return (EGLContext)1; + } + + EGLBoolean Initialize(EGLDisplay dpy, EGLint* major, EGLint* minor) { + if (major) *major = 1; + if (minor) *minor = 5; + return EGL_TRUE; + } + + EGLDisplay GetDisplay(NativeDisplayType display) { + return (EGLDisplay)1; + } + + EGLint GetError() { + return EGL_SUCCESS; + } + + EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { + return EGL_TRUE; + } + + EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx) { + return EGL_TRUE; + } + + EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface) { + return EGL_TRUE; + } + + EGLBoolean Terminate(EGLDisplay dpy) { + return EGL_TRUE; + } + + EGLBoolean ReleaseThread() { + return EGL_TRUE; + } + + EGLContext GetCurrentContext() { + return (EGLContext)1; + } + + EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value) { + if (attribute == EGL_NATIVE_VISUAL_ID) { +#if defined(ANDROID) + *value = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; + return EGL_TRUE; +#elif defined(__linux__) + *value = 0; + return EGL_TRUE; +#elif defined(_WIN32) + *value = 0; + return EGL_TRUE; +#else + *value = 0; + return EGL_FALSE; +#endif + } + return EGL_TRUE; + } + + EGLBoolean BindAPI(EGLenum api) { + return EGL_TRUE; + } + + EGLSurface GetCurrentSurface(EGLint readdraw) { + return (EGLSurface)1; + } + + EGLBoolean QuerySurface(EGLDisplay display, EGLSurface surface, EGLint attribute, EGLint* value) { + return EGL_TRUE; + } + + char const* QueryString(EGLDisplay display, EGLint name) { + return ""; + } + + EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval) { + return EGL_TRUE; + } + + EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list) { + return (EGLSurface)1; + } + + EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { + return EGL_TRUE; + } + + EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { + return EGL_TRUE; + } + + EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { + return EGL_TRUE; + } + + EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, + const EGLint* attrib_list) { + return (EGLSurface)1; + } + + EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, + const EGLint* attrib_list) { + return (EGLSurface)1; + } + + EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config) { + if (num_config) { + *num_config = 1; + } + if (configs && config_size > 0) { + configs[0] = (EGLConfig)1; + } + return EGL_TRUE; + } + + EGLDisplay GetCurrentDisplay() { + return (EGLDisplay)1; + } + + EGLenum QueryAPI() { + return EGL_OPENGL_API; + } + + EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value) { + if (value) { + *value = 1; + } + return EGL_TRUE; + } + + EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) { + return EGL_TRUE; + } + + EGLBoolean WaitClient() { + return EGL_TRUE; + } + + EGLBoolean WaitGL() { + return EGL_TRUE; + } + + EGLBoolean WaitNative(EGLint engine) { + return EGL_TRUE; + } + + EGLSync CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib* attrib_list) { + return reinterpret_cast(0x1); + } + + EGLBoolean DestroySync(void* dpy, void* sync) { + return EGL_TRUE; + } + + EGLint ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) { + return EGL_CONDITION_SATISFIED; + } + + EGLBoolean GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib* value) { + if (value) { + *value = 1; + } + return EGL_TRUE; + } + + EGLImage CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, + const EGLAttrib* attrib_list) { + return reinterpret_cast(0x1); + } + + EGLBoolean DestroyImage(EGLDisplay dpy, EGLImage image) { + return EGL_TRUE; + } + + EGLDisplay GetPlatformDisplay(EGLenum platform, void* native_display, const EGLAttrib* attrib_list) { + return reinterpret_cast(0x1); + } + + EGLSurface CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void* native_window, + const EGLAttrib* attrib_list) { + return reinterpret_cast(0x1); + } + + EGLSurface CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void* native_pixmap, + const EGLAttrib* attrib_list) { + return reinterpret_cast(0x1); + } + + EGLBoolean WaitSync(void* dpy, void* sync, int flags) { + return EGL_TRUE; + } + + __eglMustCastToProperFunctionPointerType GetProcAddress(const char* name) { + MGLOG_D("eglGetProcAddress(%s)", name); +#if !defined(WIN32) && !defined(__APPLE__) + void* proc = dlsym(RTLD_DEFAULT, (const char*)name); +#else + void* proc = NULL; +#endif + if (!proc) { + MGLOG_W("Failed to get function: %s", (const char*)name); + return nullptr; + } + return (__eglMustCastToProperFunctionPointerType)proc; + } +} // namespace MobileGL::MG_Impl::EGLImpl diff --git a/MobileGL/MG_Impl/EGLImpl/EGLImpl.h b/MobileGL/MG_Impl/EGLImpl/EGLImpl.h new file mode 100644 index 00000000..f4787415 --- /dev/null +++ b/MobileGL/MG_Impl/EGLImpl/EGLImpl.h @@ -0,0 +1,64 @@ +// MobileGL - MobileGL/MG_Impl/EGLImpl/EGLImpl.h +// Copyright (c) 2025-2026 MobileGL-Dev +// Licensed under the GNU Lesser General Public License v3.0: +// https://www.gnu.org/licenses/gpl-3.0.txt +// https://www.gnu.org/licenses/lgpl-3.0.txt +// SPDX-License-Identifier: LGPL-3.0-only +// End of Source File Header + +#pragma once +#include + +namespace MobileGL::MG_Impl::EGLImpl { + EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, + const EGLint* attrib_list); + EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface draw); + EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, + EGLint* num_config); + EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareCtx, const EGLint* attrib_list); + EGLBoolean Initialize(EGLDisplay dpy, EGLint* major, EGLint* minor); + EGLDisplay GetDisplay(NativeDisplayType display); + EGLint GetError(); + EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); + EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx); + EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface); + EGLBoolean Terminate(EGLDisplay dpy); + EGLBoolean ReleaseThread(); + EGLContext GetCurrentContext(); + EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value); + EGLBoolean BindAPI(EGLenum api); + EGLSurface GetCurrentSurface(EGLint readdraw); + EGLBoolean QuerySurface(EGLDisplay display, EGLSurface surface, EGLint attribute, EGLint* value); + const char* QueryString(EGLDisplay display, EGLint name); + EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval); + EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list); + EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer); + EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer); + EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); + EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, + const EGLint* attrib_list); + EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, + const EGLint* attrib_list); + EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config); + EGLDisplay GetCurrentDisplay(); + EGLenum QueryAPI(); + EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value); + EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); + EGLBoolean WaitClient(); + EGLBoolean WaitGL(); + EGLBoolean WaitNative(EGLint engine); + EGLSync CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib* attrib_list); + EGLBoolean DestroySync(void* dpy, void* sync); + EGLint ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); + EGLBoolean GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib* value); + EGLImage CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, + const EGLAttrib* attrib_list); + EGLBoolean DestroyImage(EGLDisplay dpy, EGLImage image); + EGLDisplay GetPlatformDisplay(EGLenum platform, void* native_display, const EGLAttrib* attrib_list); + EGLSurface CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void* native_window, + const EGLAttrib* attrib_list); + EGLSurface CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void* native_pixmap, + const EGLAttrib* attrib_list); + EGLBoolean WaitSync(void* dpy, void* sync, int flags); + __eglMustCastToProperFunctionPointerType GetProcAddress(const char* name); +} // namespace MobileGL::MG_Impl::EGLImpl diff --git a/MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.cpp b/MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.cpp deleted file mode 100644 index d187c756..00000000 --- a/MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.cpp +++ /dev/null @@ -1,218 +0,0 @@ -// MobileGL - MobileGL/MG_Impl/EGLImpl/EGLWrapper/EGLWrapper.cpp -// Copyright (c) 2025-2026 MobileGL-Dev -// Licensed under the GNU Lesser General Public License v3.0: -// https://www.gnu.org/licenses/gpl-3.0.txt -// https://www.gnu.org/licenses/lgpl-3.0.txt -// SPDX-License-Identifier: LGPL-3.0-only -// End of Source File Header - -#include "EGLWrapper.h" - -#include "MG_Impl/GetProcAddress.h" - -#include -#include - -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES -namespace MobileGL { - namespace MG_Impl::EGLImpl { - // TODO: implement complete EGL functionality - - EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, - const EGLint* attrib_list) { - return MG_External::EGL::eglCreateWindowSurface(dpy, config, window, attrib_list); - } - - EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, - EGLint* num_config) { - return MG_External::EGL::eglChooseConfig(dpy, attrib_list, configs, config_size, num_config); - } - - EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareCtx, const EGLint* attrib_list) { - return MG_External::EGL::eglCreateContext(dpy, config, shareCtx, attrib_list); - } - - EGLBoolean Initialize(EGLDisplay dpy, EGLint* major, EGLint* minor) { - return MG_External::EGL::eglInitialize(dpy, major, minor); - } - - EGLDisplay GetDisplay(NativeDisplayType display) { - return MG_External::EGL::eglGetDisplay(display); - } - - EGLint GetError() { - return MG_External::EGL::eglGetError(); - } - - EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { - return MG_External::EGL::eglMakeCurrent(dpy, draw, read, ctx); - } - - EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx) { - return MG_External::EGL::eglDestroyContext(dpy, ctx); - } - - EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface) { - return MG_External::EGL::eglDestroySurface(dpy, surface); - } - - EGLBoolean Terminate(EGLDisplay dpy) { - return MG_External::EGL::eglTerminate(dpy); - } - - EGLBoolean ReleaseThread(void) { - return MG_External::EGL::eglReleaseThread(); - } - - EGLContext GetCurrentContext(void) { - return MG_External::EGL::eglGetCurrentContext(); - } - - EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value) { - return MG_External::EGL::eglGetConfigAttrib(dpy, config, attribute, value); - } - - EGLBoolean BindAPI(EGLenum api) { - // We should accept `EGL_OPENGL_API`, - // and bind to `EGL_OPENGL_ES_API` at the backend - MGLOG_D("%s: api = %s", __func__, api == EGL_OPENGL_API ? "EGL_OPENGL_API" : "EGL_OPENGL_ES_API"); - MGLOG_D("%s: calling backend as EGL_OPENGL_ES_API", __func__); - return MG_External::EGL::eglBindAPI(EGL_OPENGL_ES_API); - } - - EGLSurface GetCurrentSurface(EGLint readdraw) { - return MG_External::EGL::eglGetCurrentSurface(readdraw); - } - - EGLBoolean QuerySurface(EGLDisplay display, EGLSurface surface, EGLint attribute, EGLint* value) { - return MG_External::EGL::eglQuerySurface(display, surface, attribute, value); - } - - char const* QueryString(EGLDisplay display, EGLint name) { - return MG_External::EGL::eglQueryString(display, name); - } - - EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval) { - return MG_External::EGL::eglSwapInterval(dpy, interval); - } - - EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface draw) { - return MG_External::EGL::eglSwapBuffers(dpy, draw); - } - - EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list) { - return MG_External::EGL::eglCreatePbufferSurface(dpy, config, attrib_list); - } - - EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - return MG_External::EGL::eglBindTexImage(dpy, surface, buffer); - } - - EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - return MG_External::EGL::eglReleaseTexImage(dpy, surface, buffer); - } - - EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { - return MG_External::EGL::eglCopyBuffers(dpy, surface, target); - } - - EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, - EGLConfig config, const EGLint* attrib_list) { - return MG_External::EGL::eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list); - } - - EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, - const EGLint* attrib_list) { - return MG_External::EGL::eglCreatePixmapSurface(dpy, config, pixmap, attrib_list); - } - - EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config) { - return MG_External::EGL::eglGetConfigs(dpy, configs, config_size, num_config); - } - - EGLDisplay GetCurrentDisplay(void) { - return MG_External::EGL::eglGetCurrentDisplay(); - } - - EGLenum QueryAPI(void) { - return MG_External::EGL::eglQueryAPI(); - } - - EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value) { - return MG_External::EGL::eglQueryContext(dpy, ctx, attribute, value); - } - - EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) { - return MG_External::EGL::eglSurfaceAttrib(dpy, surface, attribute, value); - } - - EGLBoolean WaitClient(void) { - return MG_External::EGL::eglWaitClient(); - } - - EGLBoolean WaitGL(void) { - return MG_External::EGL::eglWaitGL(); - } - - EGLBoolean WaitNative(EGLint engine) { - return MG_External::EGL::eglWaitNative(engine); - } - - __eglMustCastToProperFunctionPointerType GetProcAddress(const char* name) { - MGLOG_D("eglGetProcAddress(%s)", name); - - void* proc = MG_Impl::GetProcAddress(name); - - if (!proc) { - MGLOG_W("Failed to get function: %s", (const char*)name); - return nullptr; - } - return (__eglMustCastToProperFunctionPointerType)proc; - } - - EGLSync CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib* attrib_list) { - return MG_External::EGL::eglCreateSync(dpy, type, attrib_list); - } - - EGLBoolean DestroySync(EGLDisplay dpy, EGLSync sync) { - return MG_External::EGL::eglDestroySync(dpy, sync); - } - - EGLint ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) { - return MG_External::EGL::eglClientWaitSync(dpy, sync, flags, timeout); - } - - EGLBoolean GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib* value) { - return MG_External::EGL::eglGetSyncAttrib(dpy, sync, attribute, value); - } - - EGLImage CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, - const EGLAttrib* attrib_list) { - return MG_External::EGL::eglCreateImage(dpy, ctx, target, buffer, attrib_list); - } - - EGLBoolean DestroyImage(EGLDisplay dpy, EGLImage image) { - return MG_External::EGL::eglDestroyImage(dpy, image); - } - - EGLDisplay GetPlatformDisplay(EGLenum platform, void* native_display, const EGLAttrib* attrib_list) { - return MG_External::EGL::eglGetPlatformDisplay(platform, native_display, attrib_list); - } - - EGLSurface CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void* native_window, - const EGLAttrib* attrib_list) { - return MG_External::EGL::eglCreatePlatformWindowSurface(dpy, config, native_window, attrib_list); - } - - EGLSurface CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void* native_pixmap, - const EGLAttrib* attrib_list) { - return MG_External::EGL::eglCreatePlatformPixmapSurface(dpy, config, native_pixmap, attrib_list); - } - - EGLBoolean WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) { - return MG_External::EGL::eglWaitSync(dpy, sync, flags); - } - } // namespace MG_Impl::EGLImpl -} // namespace MobileGL - -#endif diff --git a/MobileGL/MG_Impl/EGLImpl/Exporting/Definitions.cpp b/MobileGL/MG_Impl/EGLImpl/Exporting/Definitions.cpp index f209fcfa..669da2ab 100644 --- a/MobileGL/MG_Impl/EGLImpl/Exporting/Definitions.cpp +++ b/MobileGL/MG_Impl/EGLImpl/Exporting/Definitions.cpp @@ -7,20 +7,26 @@ // End of Source File Header #include -#include "../Temporary/TemporaryEGLImpl.h" +#include "../EGLImpl.h" MOBILEGL_EGL_API EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint* attrib_list) { + MGLOG_D("[MobileGL] eglCreateWindowSurface(dpy=%p, config=%p, window=%p, attrib_list=%p)", dpy, config, window, + attrib_list); return MobileGL::MG_Impl::EGLImpl::CreateWindowSurface(dpy, config, window, attrib_list); } MOBILEGL_EGL_API EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config) { + MGLOG_D("[MobileGL] eglChooseConfig(dpy=%p, attrib_list=%p, configs=%p, config_size=%d, num_config=%p)", dpy, + attrib_list, configs, config_size, num_config); return MobileGL::MG_Impl::EGLImpl::ChooseConfig(dpy, attrib_list, configs, config_size, num_config); } MOBILEGL_EGL_API EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareCtx, const EGLint* attrib_list) { + MGLOG_D("[MobileGL] eglCreateContext(dpy=%p, config=%p, shareCtx=%p, attrib_list=%p)", dpy, config, shareCtx, + attrib_list); #ifdef TRACY_ENABLE tracy::StartupProfiler(); #endif @@ -28,22 +34,27 @@ MOBILEGL_EGL_API EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, E } MOBILEGL_EGL_API EGLBoolean eglInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) { + MGLOG_D("[MobileGL] eglInitialize(dpy=%p, major=%p, minor=%p)", dpy, major, minor); return MobileGL::MG_Impl::EGLImpl::Initialize(dpy, major, minor); } MOBILEGL_EGL_API EGLDisplay eglGetDisplay(NativeDisplayType display) { + MGLOG_D("[MobileGL] eglGetDisplay(display=%p)", display); return MobileGL::MG_Impl::EGLImpl::GetDisplay(display); } MOBILEGL_EGL_API EGLint eglGetError() { + MGLOG_D("[MobileGL] eglGetError()"); return MobileGL::MG_Impl::EGLImpl::GetError(); } MOBILEGL_EGL_API EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { + MGLOG_D("[MobileGL] eglMakeCurrent(dpy=%p, draw=%p, read=%p, ctx=%p)", dpy, draw, read, ctx); return MobileGL::MG_Impl::EGLImpl::MakeCurrent(dpy, draw, read, ctx); } MOBILEGL_EGL_API EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { + MGLOG_D("[MobileGL] eglDestroyContext(dpy=%p, ctx=%p)", dpy, ctx); #ifdef TRACY_ENABLE tracy::ShutdownProfiler(); #endif @@ -51,46 +62,58 @@ MOBILEGL_EGL_API EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { } MOBILEGL_EGL_API EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { + MGLOG_D("[MobileGL] eglDestroySurface(dpy=%p, surface=%p)", dpy, surface); return MobileGL::MG_Impl::EGLImpl::DestroySurface(dpy, surface); } MOBILEGL_EGL_API EGLBoolean eglTerminate(EGLDisplay dpy) { + MGLOG_D("[MobileGL] eglTerminate(dpy=%p)", dpy); return MobileGL::MG_Impl::EGLImpl::Terminate(dpy); } MOBILEGL_EGL_API EGLBoolean eglReleaseThread(void) { + MGLOG_D("[MobileGL] eglReleaseThread()"); return MobileGL::MG_Impl::EGLImpl::ReleaseThread(); } MOBILEGL_EGL_API EGLContext eglGetCurrentContext(void) { + MGLOG_D("[MobileGL] eglGetCurrentContext()"); return MobileGL::MG_Impl::EGLImpl::GetCurrentContext(); } MOBILEGL_EGL_API EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value) { + MGLOG_D("[MobileGL] eglGetConfigAttrib(dpy=%p, config=%p, attribute=%d, value=%p)", dpy, config, attribute, value); return MobileGL::MG_Impl::EGLImpl::GetConfigAttrib(dpy, config, attribute, value); } MOBILEGL_EGL_API EGLBoolean eglBindAPI(EGLenum api) { + MGLOG_D("[MobileGL] eglBindAPI(api=%u)", api); return MobileGL::MG_Impl::EGLImpl::BindAPI(api); } MOBILEGL_EGL_API EGLSurface eglGetCurrentSurface(EGLint readdraw) { + MGLOG_D("[MobileGL] eglGetCurrentSurface(readdraw=%d)", readdraw); return MobileGL::MG_Impl::EGLImpl::GetCurrentSurface(readdraw); } MOBILEGL_EGL_API EGLBoolean eglQuerySurface(EGLDisplay display, EGLSurface surface, EGLint attribute, EGLint* value) { + MGLOG_D("[MobileGL] eglQuerySurface(display=%p, surface=%p, attribute=%d, value=%p)", display, surface, attribute, + value); return MobileGL::MG_Impl::EGLImpl::QuerySurface(display, surface, attribute, value); } -MOBILEGL_EGL_API char const * eglQueryString(EGLDisplay display, EGLint name) { +MOBILEGL_EGL_API char const* eglQueryString(EGLDisplay display, EGLint name) { + MGLOG_D("[MobileGL] eglQueryString(display=%p, name=%d)", display, name); return MobileGL::MG_Impl::EGLImpl::QueryString(display, name); } MOBILEGL_EGL_API EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) { + MGLOG_D("[MobileGL] eglSwapInterval(dpy=%p, interval=%d)", dpy, interval); return MobileGL::MG_Impl::EGLImpl::SwapInterval(dpy, interval); } MOBILEGL_EGL_API EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) { + MGLOG_D("[MobileGL] eglSwapBuffers(dpy=%p, draw=%p)", dpy, draw); #ifdef TRACY_ENABLE FrameMark; #endif @@ -98,108 +121,140 @@ MOBILEGL_EGL_API EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) { } MOBILEGL_EGL_API EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list) { + MGLOG_D("[MobileGL] eglCreatePbufferSurface(dpy=%p, config=%p, attrib_list=%p)", dpy, config, attrib_list); return MobileGL::MG_Impl::EGLImpl::CreatePbufferSurface(dpy, config, attrib_list); } MOBILEGL_EGL_API __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char* name) { + MGLOG_D("[MobileGL] eglGetProcAddress(name=%s)", name ? name : "null"); return MobileGL::MG_Impl::EGLImpl::GetProcAddress(name); } MOBILEGL_EGL_API EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { + MGLOG_D("[MobileGL] eglBindTexImage(dpy=%p, surface=%p, buffer=%d)", dpy, surface, buffer); return MobileGL::MG_Impl::EGLImpl::BindTexImage(dpy, surface, buffer); } MOBILEGL_EGL_API EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { + MGLOG_D("[MobileGL] eglReleaseTexImage(dpy=%p, surface=%p, buffer=%d)", dpy, surface, buffer); return MobileGL::MG_Impl::EGLImpl::ReleaseTexImage(dpy, surface, buffer); } MOBILEGL_EGL_API EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { + MGLOG_D("[MobileGL] eglCopyBuffers(dpy=%p, surface=%p, target=%p)", dpy, surface, target); return MobileGL::MG_Impl::EGLImpl::CopyBuffers(dpy, surface, target); } -MOBILEGL_EGL_API EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, - EGLClientBuffer buffer, EGLConfig config, - const EGLint* attrib_list) { +MOBILEGL_EGL_API EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, + EGLConfig config, const EGLint* attrib_list) { + MGLOG_D("[MobileGL] eglCreatePbufferFromClientBuffer(dpy=%p, buftype=%u, buffer=%p, config=%p, attrib_list=%p)", + dpy, buftype, buffer, config, attrib_list); return MobileGL::MG_Impl::EGLImpl::CreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list); } MOBILEGL_EGL_API EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* attrib_list) { + MGLOG_D("[MobileGL] eglCreatePixmapSurface(dpy=%p, config=%p, pixmap=%p, attrib_list=%p)", dpy, config, pixmap, + attrib_list); return MobileGL::MG_Impl::EGLImpl::CreatePixmapSurface(dpy, config, pixmap, attrib_list); } MOBILEGL_EGL_API EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config) { + MGLOG_D("[MobileGL] eglGetConfigs(dpy=%p, configs=%p, config_size=%d, num_config=%p)", dpy, configs, config_size, + num_config); return MobileGL::MG_Impl::EGLImpl::GetConfigs(dpy, configs, config_size, num_config); } MOBILEGL_EGL_API EGLDisplay eglGetCurrentDisplay(void) { + MGLOG_D("[MobileGL] eglGetCurrentDisplay()"); return MobileGL::MG_Impl::EGLImpl::GetCurrentDisplay(); } MOBILEGL_EGL_API EGLenum eglQueryAPI(void) { + MGLOG_D("[MobileGL] eglQueryAPI()"); return MobileGL::MG_Impl::EGLImpl::QueryAPI(); } MOBILEGL_EGL_API EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value) { + MGLOG_D("[MobileGL] eglQueryContext(dpy=%p, ctx=%p, attribute=%d, value=%p)", dpy, ctx, attribute, value); return MobileGL::MG_Impl::EGLImpl::QueryContext(dpy, ctx, attribute, value); } MOBILEGL_EGL_API EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) { + MGLOG_D("[MobileGL] eglSurfaceAttrib(dpy=%p, surface=%p, attribute=%d, value=%d)", dpy, surface, attribute, value); return MobileGL::MG_Impl::EGLImpl::SurfaceAttrib(dpy, surface, attribute, value); } MOBILEGL_EGL_API EGLBoolean eglWaitClient(void) { + MGLOG_D("[MobileGL] eglWaitClient()"); return MobileGL::MG_Impl::EGLImpl::WaitClient(); } MOBILEGL_EGL_API EGLBoolean eglWaitGL(void) { + MGLOG_D("[MobileGL] eglWaitGL()"); return MobileGL::MG_Impl::EGLImpl::WaitGL(); } MOBILEGL_EGL_API EGLBoolean eglWaitNative(EGLint engine) { + MGLOG_D("[MobileGL] eglWaitNative(engine=%d)", engine); return MobileGL::MG_Impl::EGLImpl::WaitNative(engine); } MOBILEGL_EGL_API EGLSync eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib* attrib_list) { + MGLOG_D("[MobileGL] eglCreateSync(dpy=%p, type=%u, attrib_list=%p)", dpy, type, attrib_list); return MobileGL::MG_Impl::EGLImpl::CreateSync(dpy, type, attrib_list); } MOBILEGL_EGL_API EGLBoolean eglDestroySync(EGLDisplay dpy, EGLSync sync) { + MGLOG_D("[MobileGL] eglDestroySync(dpy=%p, sync=%p)", dpy, sync); return MobileGL::MG_Impl::EGLImpl::DestroySync(dpy, sync); } MOBILEGL_EGL_API EGLint eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) { + MGLOG_D("[MobileGL] eglClientWaitSync(dpy=%p, sync=%p, flags=%d, timeout=%llu)", dpy, sync, flags, + static_cast(timeout)); return MobileGL::MG_Impl::EGLImpl::ClientWaitSync(dpy, sync, flags, timeout); } MOBILEGL_EGL_API EGLBoolean eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib* value) { + MGLOG_D("[MobileGL] eglGetSyncAttrib(dpy=%p, sync=%p, attribute=%d, value=%p)", dpy, sync, attribute, value); return MobileGL::MG_Impl::EGLImpl::GetSyncAttrib(dpy, sync, attribute, value); } MOBILEGL_EGL_API EGLImage eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib* attrib_list) { + MGLOG_D("[MobileGL] eglCreateImage(dpy=%p, ctx=%p, target=%u, buffer=%p, attrib_list=%p)", dpy, ctx, target, buffer, + attrib_list); return MobileGL::MG_Impl::EGLImpl::CreateImage(dpy, ctx, target, buffer, attrib_list); } MOBILEGL_EGL_API EGLBoolean eglDestroyImage(EGLDisplay dpy, EGLImage image) { + MGLOG_D("[MobileGL] eglDestroyImage(dpy=%p, image=%p)", dpy, image); return MobileGL::MG_Impl::EGLImpl::DestroyImage(dpy, image); } MOBILEGL_EGL_API EGLDisplay eglGetPlatformDisplay(EGLenum platform, void* native_display, const EGLAttrib* attrib_list) { + MGLOG_D("[MobileGL] eglGetPlatformDisplay(platform=%u, native_display=%p, attrib_list=%p)", platform, + native_display, attrib_list); return MobileGL::MG_Impl::EGLImpl::GetPlatformDisplay(platform, native_display, attrib_list); } MOBILEGL_EGL_API EGLSurface eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void* native_window, const EGLAttrib* attrib_list) { + MGLOG_D("[MobileGL] eglCreatePlatformWindowSurface(dpy=%p, config=%p, native_window=%p, attrib_list=%p)", dpy, + config, native_window, attrib_list); return MobileGL::MG_Impl::EGLImpl::CreatePlatformWindowSurface(dpy, config, native_window, attrib_list); } MOBILEGL_EGL_API EGLSurface eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void* native_pixmap, const EGLAttrib* attrib_list) { + MGLOG_D("[MobileGL] eglCreatePlatformPixmapSurface(dpy=%p, config=%p, native_pixmap=%p, attrib_list=%p)", dpy, + config, native_pixmap, attrib_list); return MobileGL::MG_Impl::EGLImpl::CreatePlatformPixmapSurface(dpy, config, native_pixmap, attrib_list); } MOBILEGL_EGL_API EGLBoolean eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) { + MGLOG_D("[MobileGL] eglWaitSync(dpy=%p, sync=%p, flags=%d)", dpy, sync, flags); return MobileGL::MG_Impl::EGLImpl::WaitSync(dpy, sync, flags); } diff --git a/MobileGL/MG_Impl/EGLImpl/Temporary/TemporaryEGLImpl.cpp b/MobileGL/MG_Impl/EGLImpl/Temporary/TemporaryEGLImpl.cpp deleted file mode 100644 index d3cc5508..00000000 --- a/MobileGL/MG_Impl/EGLImpl/Temporary/TemporaryEGLImpl.cpp +++ /dev/null @@ -1,195 +0,0 @@ -// MobileGL - MobileGL/MG_Impl/EGLImpl/Temporary/TemporaryEGLImpl.cpp -// Copyright (c) 2025-2026 MobileGL-Dev -// Licensed under the GNU Lesser General Public License v3.0: -// https://www.gnu.org/licenses/gpl-3.0.txt -// https://www.gnu.org/licenses/lgpl-3.0.txt -// SPDX-License-Identifier: LGPL-3.0-only -// End of Source File Header - -#include "TemporaryEGLImpl.h" -#include - -#if !(MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES) -namespace MobileGL { - namespace MG_Impl::EGLImpl { - // TODO: implement complete EGL functionality - - EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, - const EGLint* attrib_list) { - return (EGLSurface)1; - } - - EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, - EGLint* num_config) { - *num_config = 1; - return EGL_TRUE; - } - - EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareCtx, const EGLint* attrib_list) { - return (EGLContext)1; - } - - EGLBoolean Initialize(EGLDisplay dpy, EGLint* major, EGLint* minor) { - if (major) *major = 1; - if (minor) *minor = 5; - return EGL_TRUE; - } - - EGLDisplay GetDisplay(NativeDisplayType display) { - return (EGLDisplay)1; - } - - EGLint GetError() { - return EGL_SUCCESS; - } - - EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { - return EGL_TRUE; - } - - EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx) { - return EGL_TRUE; - } - - EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface) { - return EGL_TRUE; - } - - EGLBoolean Terminate(EGLDisplay dpy) { - return EGL_TRUE; - } - - EGLBoolean ReleaseThread(void) { - return EGL_TRUE; - } - - EGLContext GetCurrentContext(void) { - return (EGLContext)1; - } - - EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value) { - if (attribute == EGL_NATIVE_VISUAL_ID) { -#if defined(ANDROID) - *value = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; - return EGL_TRUE; -#elif defined(__linux__) - *value = 0; - return EGL_TRUE; -#elif defined(_WIN32) - *value = 0; - return EGL_TRUE; -#else - *value = 0; - return EGL_FALSE; -#endif - } - return EGL_TRUE; - } - - EGLBoolean BindAPI(EGLenum api) { - return EGL_TRUE; - } - - EGLSurface GetCurrentSurface(EGLint readdraw) { - return (EGLSurface)1; - } - - EGLBoolean QuerySurface(EGLDisplay display, EGLSurface surface, EGLint attribute, EGLint* value) { - return EGL_TRUE; - } - - char const* QueryString(EGLDisplay display, EGLint name) { - return ""; - } - - EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval) { - return EGL_TRUE; - } - - EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface draw) { - return EGL_TRUE; - } - - EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list) { - return (EGLSurface)1; - } - - EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - return EGL_TRUE; - } - - EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - return EGL_TRUE; - } - - EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { - return EGL_TRUE; - } - - EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, - EGLConfig config, const EGLint* attrib_list) { - return (EGLSurface)1; - } - - EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, - const EGLint* attrib_list) { - return (EGLSurface)1; - } - - EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config) { - if (num_config) { - *num_config = 1; - } - if (configs && config_size > 0) { - configs[0] = (EGLConfig)1; - } - return EGL_TRUE; - } - - EGLDisplay GetCurrentDisplay(void) { - return (EGLDisplay)1; - } - - EGLenum QueryAPI(void) { - return EGL_OPENGL_API; - } - - EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value) { - if (value) { - *value = 0; - } - return EGL_TRUE; - } - - EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) { - return EGL_TRUE; - } - - EGLBoolean WaitClient(void) { - return EGL_TRUE; - } - - EGLBoolean WaitGL(void) { - return EGL_TRUE; - } - - EGLBoolean WaitNative(EGLint engine) { - return EGL_TRUE; - } - - __eglMustCastToProperFunctionPointerType GetProcAddress(const char* name) { - MGLOG_D("eglGetProcAddress(%s)", name); -#if !defined(WIN32) && !defined(__APPLE__) - void* proc = dlsym(RTLD_DEFAULT, (const char*)name); -#else - void* proc = NULL; -#endif - if (!proc) { - MGLOG_W("Failed to get function: %s", (const char*)name); - return nullptr; - } - return (__eglMustCastToProperFunctionPointerType)proc; - } - } // namespace MG_Impl::EGLImpl -} // namespace MobileGL -#endif diff --git a/MobileGL/MG_Impl/EGLImpl/Temporary/TemporaryEGLImpl.h b/MobileGL/MG_Impl/EGLImpl/Temporary/TemporaryEGLImpl.h deleted file mode 100644 index c1f89733..00000000 --- a/MobileGL/MG_Impl/EGLImpl/Temporary/TemporaryEGLImpl.h +++ /dev/null @@ -1,66 +0,0 @@ -// MobileGL - MobileGL/MG_Impl/EGLImpl/Temporary/TemporaryEGLImpl.h -// Copyright (c) 2025-2026 MobileGL-Dev -// Licensed under the GNU Lesser General Public License v3.0: -// https://www.gnu.org/licenses/gpl-3.0.txt -// https://www.gnu.org/licenses/lgpl-3.0.txt -// SPDX-License-Identifier: LGPL-3.0-only -// End of Source File Header - -#pragma once -#include - -namespace MobileGL { - namespace MG_Impl::EGLImpl { - EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, - const EGLint* attrib_list); - EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, - EGLint* num_config); - EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareCtx, const EGLint* attrib_list); - EGLBoolean Initialize(EGLDisplay dpy, EGLint* major, EGLint* minor); - EGLDisplay GetDisplay(NativeDisplayType display); - EGLint GetError(); - EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); - EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx); - EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface); - EGLBoolean Terminate(EGLDisplay dpy); - EGLBoolean ReleaseThread(void); - EGLContext GetCurrentContext(void); - EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value); - EGLBoolean BindAPI(EGLenum api); - EGLSurface GetCurrentSurface(EGLint readdraw); - EGLBoolean QuerySurface(EGLDisplay display, EGLSurface surface, EGLint attribute, EGLint* value); - char const* QueryString(EGLDisplay display, EGLint name); - EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval); - EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface draw); - EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list); - EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer); - EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer); - EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); - EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, - EGLConfig config, const EGLint* attrib_list); - EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, - const EGLint* attrib_list); - EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config); - EGLDisplay GetCurrentDisplay(void); - EGLenum QueryAPI(void); - EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value); - EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); - EGLBoolean WaitClient(void); - EGLBoolean WaitGL(void); - EGLBoolean WaitNative(EGLint engine); - __eglMustCastToProperFunctionPointerType GetProcAddress(const char* name); - EGLSync CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib* attrib_list); - EGLBoolean DestroySync(EGLDisplay dpy, EGLSync sync); - EGLint ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); - EGLBoolean GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib* value); - EGLImage CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, - const EGLAttrib* attrib_list); - EGLBoolean DestroyImage(EGLDisplay dpy, EGLImage image); - EGLDisplay GetPlatformDisplay(EGLenum platform, void* native_display, const EGLAttrib* attrib_list); - EGLSurface CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void* native_window, - const EGLAttrib* attrib_list); - EGLSurface CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void* native_pixmap, - const EGLAttrib* attrib_list); - EGLBoolean WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags); - } // namespace MG_Impl::EGLImpl -} // namespace MobileGL diff --git a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp index b31bfc69..70ebd6c0 100644 --- a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp +++ b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp @@ -9,272 +9,231 @@ #include "GL_Drawing.h" #include #include -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES -#include -#endif -#include +#include -namespace MobileGL { - namespace MG_Impl::GLImpl { - void Clear_Backend(GLbitfield mask) { +namespace MobileGL::MG_Impl::GLImpl { + void Clear_Backend(GLbitfield mask) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::Clear(mask); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.Clear(mask); + } - void DrawElements_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices) { + void DrawElements_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::DrawElements(mode, count, type, indices); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.DrawElements(mode, count, type, indices); + } - void MultiDrawElements_Backend(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, - GLsizei drawcount) { + void MultiDrawElements_Backend(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, + GLsizei drawcount) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::MultiDrawElements(mode, count, type, indices, drawcount); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.MultiDrawElements(mode, count, type, indices, drawcount); + } - void MultiDrawElementsBaseVertex_Backend(GLenum mode, const GLsizei* count, GLenum type, - const void* const* indices, GLsizei drawcount, - const GLint* basevertex) { + void MultiDrawElementsBaseVertex_Backend(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, + GLsizei drawcount, const GLint* basevertex) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::MultiDrawElementsBaseVertex(mode, count, type, indices, drawcount, basevertex); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.MultiDrawElementsBaseVertex(mode, count, type, indices, drawcount, + basevertex); + } - void DrawArrays_Backend(GLenum mode, GLint first, GLsizei count) { + void DrawArrays_Backend(GLenum mode, GLint first, GLsizei count) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::DrawArrays(mode, first, count); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.DrawArrays(mode, first, count); + } - void DrawElementsBaseVertex_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices, - GLint basevertex) { + void DrawElementsBaseVertex_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices, + GLint basevertex) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::DrawElementsBaseVertex(mode, count, type, indices, basevertex); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.DrawElementsBaseVertex(mode, count, type, indices, basevertex); + } - void MultiDrawElementsIndirect_Backend(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, - GLsizei stride) { + void MultiDrawElementsIndirect_Backend(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, + GLsizei stride) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::MultiDrawElementsIndirect(mode, type, indirect, drawcount, stride); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.MultiDrawElementsIndirect(mode, type, indirect, drawcount, stride); + } - void MultiDrawArraysIndirect_Backend(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride) { + void MultiDrawArraysIndirect_Backend(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::MultiDrawArraysIndirect(mode, indirect, drawcount, stride); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.MultiDrawArraysIndirect(mode, indirect, drawcount, stride); + } - void DrawRangeElementsBaseVertex_Backend(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, - const void* indices, GLint basevertex) { + void DrawRangeElementsBaseVertex_Backend(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, + const void* indices, GLint basevertex) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::DrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.DrawRangeElementsBaseVertex(mode, start, end, count, type, indices, + basevertex); + } - void DrawRangeElements_Backend(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, - const void* indices) { + void DrawRangeElements_Backend(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, + const void* indices) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::DrawRangeElements(mode, start, end, count, type, indices); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.DrawRangeElements(mode, start, end, count, type, indices); + } - void DrawElementsInstancedBaseVertexBaseInstance_Backend(GLenum mode, GLsizei count, GLenum type, - const void* indices, GLsizei instancecount, - GLint basevertex, GLuint baseinstance) { + void DrawElementsInstancedBaseVertexBaseInstance_Backend(GLenum mode, GLsizei count, GLenum type, + const void* indices, GLsizei instancecount, + GLint basevertex, GLuint baseinstance) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::DrawElementsInstancedBaseVertexBaseInstance( - mode, count, type, indices, instancecount, basevertex, baseinstance); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.DrawElementsInstancedBaseVertexBaseInstance( + mode, count, type, indices, instancecount, basevertex, baseinstance); + } - void DrawElementsInstancedBaseVertex_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices, - GLsizei instancecount, GLint basevertex) { + void DrawElementsInstancedBaseVertex_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices, + GLsizei instancecount, GLint basevertex) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::DrawElementsInstancedBaseVertex(mode, count, type, indices, instancecount, - basevertex); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.DrawElementsInstancedBaseVertex(mode, count, type, indices, instancecount, + basevertex); + } - void DrawElementsInstancedBaseInstance_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices, - GLsizei instancecount, GLuint baseinstance) { + void DrawElementsInstancedBaseInstance_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices, + GLsizei instancecount, GLuint baseinstance) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::DrawElementsInstancedBaseInstance(mode, count, type, indices, instancecount, - baseinstance); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.DrawElementsInstancedBaseInstance(mode, count, type, indices, + instancecount, baseinstance); + } - void DrawElementsInstanced_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices, - GLsizei instancecount) { + void DrawElementsInstanced_Backend(GLenum mode, GLsizei count, GLenum type, const void* indices, + GLsizei instancecount) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::DrawElementsInstanced(mode, count, type, indices, instancecount); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.DrawElementsInstanced(mode, count, type, indices, instancecount); + } - void DrawElementsIndirect_Backend(GLenum mode, GLenum type, const void* indirect) { + void DrawElementsIndirect_Backend(GLenum mode, GLenum type, const void* indirect) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::DrawElementsIndirect(mode, type, indirect); -#endif - } - void DrawArraysInstancedBaseInstance_Backend(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, - GLuint baseinstance) { + MG_Backend::gBackendFunctionsTable.GL.DrawElementsIndirect(mode, type, indirect); + } + void DrawArraysInstancedBaseInstance_Backend(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, + GLuint baseinstance) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::DrawArraysInstancedBaseInstance(mode, first, count, instancecount, baseinstance); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.DrawArraysInstancedBaseInstance(mode, first, count, instancecount, + baseinstance); + } - void DrawArraysInstanced_Backend(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) { + void DrawArraysInstanced_Backend(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::DrawArraysInstanced(mode, first, count, instancecount); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.DrawArraysInstanced(mode, first, count, instancecount); + } - void DrawArraysIndirect_Backend(GLenum mode, const void* indirect) { + void DrawArraysIndirect_Backend(GLenum mode, const void* indirect) { #ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::DrawArraysIndirect(mode, indirect); -#endif - } + MG_Backend::gBackendFunctionsTable.GL.DrawArraysIndirect(mode, indirect); + } - /* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */ - void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, - GLsizei stride) { - MultiDrawElementsIndirect_Backend(mode, type, indirect, drawcount, stride); - } + /* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */ + void MultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride) { + MultiDrawElementsIndirect_Backend(mode, type, indirect, drawcount, stride); + } - void MultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride) { - MultiDrawArraysIndirect_Backend(mode, indirect, drawcount, stride); - } + void MultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride) { + MultiDrawArraysIndirect_Backend(mode, indirect, drawcount, stride); + } - void DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, - const void* indices, GLint basevertex) { - DrawRangeElementsBaseVertex_Backend(mode, start, end, count, type, indices, basevertex); - } + void DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, + const void* indices, GLint basevertex) { + DrawRangeElementsBaseVertex_Backend(mode, start, end, count, type, indices, basevertex); + } - void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) { - DrawRangeElements_Backend(mode, start, end, count, type, indices); - } + void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) { + DrawRangeElements_Backend(mode, start, end, count, type, indices); + } - void DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, - GLsizei instancecount, GLint basevertex, GLuint baseinstance) { - DrawElementsInstancedBaseVertexBaseInstance_Backend(mode, count, type, indices, instancecount, basevertex, - baseinstance); - } + void DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, + GLsizei instancecount, GLint basevertex, GLuint baseinstance) { + DrawElementsInstancedBaseVertexBaseInstance_Backend(mode, count, type, indices, instancecount, basevertex, + baseinstance); + } - void DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, - GLsizei instancecount, GLint basevertex) { - DrawElementsInstancedBaseVertex_Backend(mode, count, type, indices, instancecount, basevertex); - } + void DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, + GLsizei instancecount, GLint basevertex) { + DrawElementsInstancedBaseVertex_Backend(mode, count, type, indices, instancecount, basevertex); + } - void DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, - GLsizei instancecount, GLuint baseinstance) { - DrawElementsInstancedBaseInstance_Backend(mode, count, type, indices, instancecount, baseinstance); - } + void DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, + GLsizei instancecount, GLuint baseinstance) { + DrawElementsInstancedBaseInstance_Backend(mode, count, type, indices, instancecount, baseinstance); + } - void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, - GLsizei instancecount) { - DrawElementsInstanced_Backend(mode, count, type, indices, instancecount); - } + void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount) { + DrawElementsInstanced_Backend(mode, count, type, indices, instancecount); + } - void DrawElementsIndirect(GLenum mode, GLenum type, const void* indirect) { - DrawElementsIndirect_Backend(mode, type, indirect); - } + void DrawElementsIndirect(GLenum mode, GLenum type, const void* indirect) { + DrawElementsIndirect_Backend(mode, type, indirect); + } - void DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, - GLuint baseinstance) { - DrawArraysInstancedBaseInstance_Backend(mode, first, count, instancecount, baseinstance); - } + void DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, + GLuint baseinstance) { + DrawArraysInstancedBaseInstance_Backend(mode, first, count, instancecount, baseinstance); + } - void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) { - DrawArraysInstanced_Backend(mode, first, count, instancecount); - } + void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) { + DrawArraysInstanced_Backend(mode, first, count, instancecount); + } - void DrawArraysIndirect(GLenum mode, const void* indirect) { - DrawArraysIndirect_Backend(mode, indirect); - } + void DrawArraysIndirect(GLenum mode, const void* indirect) { + DrawArraysIndirect_Backend(mode, indirect); + } - void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex) { - DrawElementsBaseVertex_Backend(mode, count, type, indices, basevertex); - } + void DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex) { + DrawElementsBaseVertex_Backend(mode, count, type, indices, basevertex); + } - void DrawArrays(GLenum mode, GLint first, GLsizei count) { - DrawArrays_Backend(mode, first, count); - } + void DrawArrays(GLenum mode, GLint first, GLsizei count) { + DrawArrays_Backend(mode, first, count); + } - void MultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, - GLsizei drawcount) { - MultiDrawElements_Backend(mode, count, type, indices, drawcount); - } + void MultiDrawElements(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, + GLsizei drawcount) { + MultiDrawElements_Backend(mode, count, type, indices, drawcount); + } - void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, - GLsizei drawcount, const GLint* basevertex) { - MultiDrawElementsBaseVertex_Backend(mode, count, type, indices, drawcount, basevertex); - } + void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, + GLsizei drawcount, const GLint* basevertex) { + MultiDrawElementsBaseVertex_Backend(mode, count, type, indices, drawcount, basevertex); + } - void Clear(GLbitfield mask) { - Clear_Backend(mask); - } + void Clear(GLbitfield mask) { + Clear_Backend(mask); + } - void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) { - DrawElements_Backend(mode, count, type, indices); - } + void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) { + DrawElements_Backend(mode, count, type, indices); + } - } // namespace MG_Impl::GLImpl -} // namespace MobileGL +} // namespace MobileGL::MG_Impl::GLImpl diff --git a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp index d463fca3..8c5422a8 100644 --- a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp +++ b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp @@ -9,6 +9,7 @@ #include "GL_Framebuffer.h" #include "Validators.h" #include "Config.h" +#include #include #include #include @@ -16,755 +17,721 @@ #include #include #include -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES -#include -#endif -namespace MobileGL { - namespace MG_Impl::GLImpl { - void BlitFramebuffer_Backend(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, - GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, - filter); -#endif +namespace MobileGL::MG_Impl::GLImpl { + void BlitFramebuffer_Backend(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { + MG_Backend::gBackendFunctionsTable.GL.BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, + mask, filter); + } + + void SampleMaski_State(GLuint maskNumber, GLbitfield mask) { + // TODO: implement + } + + void RenderbufferStorageMultisample_State(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, + GLsizei height) { + // TODO: implement + } + + void RenderbufferStorage_State(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { + RenderbufferTarget rbTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target); + if (!FramebufferImpl::ValidateRenderbufferTarget(rbTarget)) return; + auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(rbTarget); + auto renderbufferObject = bindingSlot.GetBoundObject(); + if (!renderbufferObject) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "RenderbufferStorage_State", + "Renderbuffer target is bound to no renderbuffer object.")); + return; + } + TextureInternalFormat format = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat); + if (!TextureImpl::ValidateTextureInternalFormat(format)) return; + if (width < 0 || height < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, MakeShared("MG_Impl/GLImpl", "RenderbufferStorage_State", + "Width and height must be non-negative.")); + return; + } + renderbufferObject->AllocateStorage({width, height}); + renderbufferObject->SetInternalFormat(format); + } + + GLboolean IsRenderbuffer_State(GLuint renderbuffer) { + return MG_State::pGLContext->ValidateRenderbufferName(renderbuffer); + } + + GLboolean IsFramebuffer_State(GLuint framebuffer) { + return MG_State::pGLContext->ValidateFramebufferName(framebuffer); + } + + void GetFramebufferAttachmentParameteriv_State(GLenum target, GLenum attachment, GLenum pname, GLint* params) { + // TODO: implement + } + + void GenRenderbuffers_State(GLsizei n, GLuint* renderbuffers) { + if (n < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", "GenRenderbuffers_State", "n must be non-negative")); + return; + } + auto renderbufferNames = MG_State::pGLContext->GenRenderbufferNames(n); + Memcpy(renderbuffers, renderbufferNames.data(), sizeof(GLuint) * static_cast(n)); + } + + void GenFramebuffers_State(GLsizei n, GLuint* framebuffers) { + if (n < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", "GenFramebuffers_State", "n must be non-negative")); + return; + } + auto framebuffersNames = MG_State::pGLContext->GenFramebufferNames(n); + Memcpy(framebuffers, framebuffersNames.data(), sizeof(GLuint) * static_cast(n)); + } + + void FramebufferTextureLayer_State(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { + // TODO: implement + } + + void FramebufferTexture3D_State(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, + GLint zoffset) { + // TODO: implement + } + + void FramebufferTexture2D_State(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { + if (target == GL_FRAMEBUFFER) { + target = GL_DRAW_FRAMEBUFFER; } - void SampleMaski_State(GLuint maskNumber, GLbitfield mask) { - // TODO: implement + if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { + FramebufferTexture2D_State(target, GL_DEPTH_ATTACHMENT, textarget, texture, level); + FramebufferTexture2D_State(target, GL_STENCIL_ATTACHMENT, textarget, texture, level); } - void RenderbufferStorageMultisample_State(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, - GLsizei height) { - // TODO: implement + FramebufferAttachmentType attachmentType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(attachment); + FramebufferTarget framebufferTarget = MG_Util::ConvertGLEnumToFramebufferTarget(target); + + if (!FramebufferImpl::ValidateFramebufferAttachmentType(attachmentType)) return; + if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return; + if (!TextureImpl::ValidateTextureName(texture, true)) return; + + auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget); + auto framebufferObject = bindingSlot.GetBoundObject(); + if (!framebufferObject) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "FramebufferTexture2D_State", + "Framebuffer target is bound to no framebuffer object.")); + return; } - void RenderbufferStorage_State(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { - RenderbufferTarget rbTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target); - if (!FramebufferImpl::ValidateRenderbufferTarget(rbTarget)) return; - auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(rbTarget); - auto renderbufferObject = bindingSlot.GetBoundObject(); - if (!renderbufferObject) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "RenderbufferStorage_State", - "Renderbuffer target is bound to no renderbuffer object.")); - return; - } - TextureInternalFormat format = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat); - if (!TextureImpl::ValidateTextureInternalFormat(format)) return; - if (width < 0 || height < 0) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, MakeShared("MG_Impl/GLImpl", "RenderbufferStorage_State", - "Width and height must be non-negative.")); - return; - } - renderbufferObject->AllocateStorage({width, height}); - renderbufferObject->SetInternalFormat(format); + if (texture == 0) { + framebufferObject->Detach(attachmentType); + return; } - GLboolean IsRenderbuffer_State(GLuint renderbuffer) { - return MG_State::pGLContext->ValidateRenderbufferName(renderbuffer); + auto textureObject = MG_State::pGLContext->GetTextureObject(texture); + if (!textureObject) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "FramebufferTexture2D_State", + std::format("Texture object {} is not valid.", texture))); + return; } - GLboolean IsFramebuffer_State(GLuint framebuffer) { - return MG_State::pGLContext->ValidateFramebufferName(framebuffer); + framebufferObject->AttachTexture(attachmentType, textureObject, textureObject ? level : 0); + } + + void FramebufferTexture1D_State(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { + // TODO: implement + } + + void FramebufferTexture_State(GLenum target, GLenum attachment, GLuint texture, GLint level) { + // TODO: implement + } + + void FramebufferRenderbuffer_State(GLenum target, GLenum attachment, GLenum renderbuffertarget, + GLuint renderbuffer) { + if (target == GL_FRAMEBUFFER) { + target = GL_DRAW_FRAMEBUFFER; } - void GetFramebufferAttachmentParameteriv_State(GLenum target, GLenum attachment, GLenum pname, GLint* params) { - // TODO: implement + FramebufferAttachmentType attachmentType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(attachment); + FramebufferTarget framebufferTarget = MG_Util::ConvertGLEnumToFramebufferTarget(target); + RenderbufferTarget rbTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(renderbuffertarget); + if (!FramebufferImpl::ValidateFramebufferAttachmentType(attachmentType)) return; + if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return; + if (!FramebufferImpl::ValidateRenderbufferName(renderbuffer)) return; + auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget); + auto framebufferObject = bindingSlot.GetBoundObject(); + if (!framebufferObject) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "FramebufferRenderbuffer_State", + "Framebuffer target is bound to no framebuffer object.")); + return; } - void GenerateMipmap_Backend(GLenum target) { -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::GenerateMipmap(target); -#endif + if (renderbuffer == 0) { + framebufferObject->Detach(attachmentType); + return; } - void GenRenderbuffers_State(GLsizei n, GLuint* renderbuffers) { - if (n < 0) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, - MakeShared("MG_Impl/GLImpl", "GenRenderbuffers_State", "n must be non-negative")); - return; - } - auto renderbufferNames = MG_State::pGLContext->GenRenderbufferNames(n); - Memcpy(renderbuffers, renderbufferNames.data(), sizeof(GLuint) * static_cast(n)); + auto renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer); + if (!renderbufferObject) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "FramebufferRenderbuffer_State", + std::format("Renderbuffer object {} is not valid.", renderbuffer))); + return; } - void GenFramebuffers_State(GLsizei n, GLuint* framebuffers) { - if (n < 0) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, - MakeShared("MG_Impl/GLImpl", "GenFramebuffers_State", "n must be non-negative")); - return; - } - auto framebuffersNames = MG_State::pGLContext->GenFramebufferNames(n); - Memcpy(framebuffers, framebuffersNames.data(), sizeof(GLuint) * static_cast(n)); + framebufferObject->AttachRenderbuffer(attachmentType, renderbufferObject); + } + + void DrawBuffers_State(GLsizei n, const GLenum* bufs) { + if (n < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", __func__, "`n` is less than 0.")); + return; + } else if (n > MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", __func__, "`n` is greater than `GL_MAX_DRAW_BUFFERS`.")); + return; } - void FramebufferTextureLayer_State(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { - // TODO: implement - } + // Get bound framebuffer + auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw); + auto fbo = bindingSlot.GetBoundObject(); + bool isDefaultFBO = (fbo == FramebufferImpl::pDefaultFramebufferInfo->defaultFBO); - void FramebufferTexture3D_State(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, - GLint zoffset) { - // TODO: implement - } + static int existenceMap[(SizeT)FramebufferAttachmentType::FramebufferAttachmentTypeCount] = {-1}; + std::fill(existenceMap, existenceMap + (SizeT)FramebufferAttachmentType::FramebufferAttachmentTypeCount, -1); - void FramebufferTexture2D_State(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, - GLint level) { - if (target == GL_FRAMEBUFFER) { - target = GL_DRAW_FRAMEBUFFER; - } - - if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { - FramebufferTexture2D_State(target, GL_DEPTH_ATTACHMENT, textarget, texture, level); - FramebufferTexture2D_State(target, GL_STENCIL_ATTACHMENT, textarget, texture, level); - } - - FramebufferAttachmentType attachmentType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(attachment); - FramebufferTarget framebufferTarget = MG_Util::ConvertGLEnumToFramebufferTarget(target); - - if (!FramebufferImpl::ValidateFramebufferAttachmentType(attachmentType)) return; - if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return; - if (!TextureImpl::ValidateTextureName(texture, true)) return; - - auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget); - auto framebufferObject = bindingSlot.GetBoundObject(); - if (!framebufferObject) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "FramebufferTexture2D_State", - "Framebuffer target is bound to no framebuffer object.")); - return; - } - - if (texture == 0) { - framebufferObject->Detach(attachmentType); - return; - } - - auto textureObject = MG_State::pGLContext->GetTextureObject(texture); - if (!textureObject) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "FramebufferTexture2D_State", - std::format("Texture object {} is not valid.", texture))); - return; - } - - framebufferObject->AttachTexture(attachmentType, textureObject, textureObject ? level : 0); - } - - void FramebufferTexture1D_State(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, - GLint level) { - // TODO: implement - } - - void FramebufferTexture_State(GLenum target, GLenum attachment, GLuint texture, GLint level) { - // TODO: implement - } - - void FramebufferRenderbuffer_State(GLenum target, GLenum attachment, GLenum renderbuffertarget, - GLuint renderbuffer) { - if (target == GL_FRAMEBUFFER) { - target = GL_DRAW_FRAMEBUFFER; - } - - FramebufferAttachmentType attachmentType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(attachment); - FramebufferTarget framebufferTarget = MG_Util::ConvertGLEnumToFramebufferTarget(target); - RenderbufferTarget rbTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(renderbuffertarget); - if (!FramebufferImpl::ValidateFramebufferAttachmentType(attachmentType)) return; - if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return; - if (!FramebufferImpl::ValidateRenderbufferName(renderbuffer)) return; - auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget); - auto framebufferObject = bindingSlot.GetBoundObject(); - if (!framebufferObject) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "FramebufferRenderbuffer_State", - "Framebuffer target is bound to no framebuffer object.")); - return; - } - - if (renderbuffer == 0) { - framebufferObject->Detach(attachmentType); - return; - } - - auto renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer); - if (!renderbufferObject) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "FramebufferRenderbuffer_State", - std::format("Renderbuffer object {} is not valid.", renderbuffer))); - return; - } - - framebufferObject->AttachRenderbuffer(attachmentType, renderbufferObject); - } - - void DrawBuffers_State(GLsizei n, const GLenum* bufs) { - if (n < 0) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, - MakeShared("MG_Impl/GLImpl", __func__, "`n` is less than 0.")); - return; - } else if (n > MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, - MakeShared("MG_Impl/GLImpl", __func__, - "`n` is greater than `GL_MAX_DRAW_BUFFERS`.")); - return; - } - - // Get bound framebuffer - auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw); - auto fbo = bindingSlot.GetBoundObject(); - bool isDefaultFBO = (fbo == FramebufferImpl::pDefaultFramebufferInfo->defaultFBO); - - static int existenceMap[(SizeT)FramebufferAttachmentType::FramebufferAttachmentTypeCount] = {-1}; - std::fill(existenceMap, existenceMap + (SizeT)FramebufferAttachmentType::FramebufferAttachmentTypeCount, - -1); - - for (GLsizei i = 0; i < n; ++i) { - auto attType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(bufs[i]); - - // ------------------- Check validity begin ------------------------ - if (attType == FramebufferAttachmentType::Unknown) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", __func__, - std::format("bufs[{}] = {} is not an accepted value.", i, - MG_Util::ConvertGLEnumToString(bufs[i])))); - return; - } - - if (isDefaultFBO && attType >= FramebufferAttachmentType::Color0 && - attType <= FramebufferAttachmentType::Color31) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared( - "MG_Impl/GLImpl", __func__, - std::format( - "FBO is default FBO, but bufs[{}] = {} is one of the `GL_COLOR_ATTACHMENTn` tokens.", i, - MG_Util::ConvertGLEnumToString(bufs[i])))); - return; - } - - if (!isDefaultFBO && attType >= FramebufferAttachmentType::FrontLeft && - attType <= FramebufferAttachmentType::BackRight) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared( - "MG_Impl/GLImpl", __func__, - std::format("FBO is not default FBO, but bufs[{}] = {} is anything other than `GL_NONE` or " - "one of the `GL_COLOR_ATTACHMENTn` tokens.", - i, MG_Util::ConvertGLEnumToString(bufs[i])))); - return; - } - - if (attType != FramebufferAttachmentType::None && existenceMap[(SizeT)attType] >= 0) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", __func__, - std::format("a symbolic constant other than `GL_NONE` appears " - "more than once in bufs. bufs[{}] == bufs[{}] == {}.", - i, existenceMap[(SizeT)attType], - MG_Util::ConvertGLEnumToString(bufs[i])))); - return; - } - - existenceMap[(SizeT)attType] = i; - - if ((SizeT)attType > - (SizeT)FramebufferAttachmentType::Color0 + MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", __func__, - std::format("bufs[{}] == {} indicates a color buffer that does " - "not exist in the current GL context.", - i, MG_Util::ConvertGLEnumToString(bufs[i])))); - return; - } - // ------------------------- Check validity end ---------------------------------- - fbo->SetDrawBuffer(i, attType); - } - for (GLsizei i = n; i < MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; ++i) { - fbo->SetDrawBuffer(i, FramebufferAttachmentType::None); - } - } - - void DrawBuffer_State(GLenum buf) { - if (buf == GL_NONE) { - DrawBuffers_State(0, nullptr); - } else { - static GLenum bufs[] = {buf}; - DrawBuffers_State(1, bufs); - } - } - - void ReadBuffer_State(GLenum mode) { - auto attType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(mode); + for (GLsizei i = 0; i < n; ++i) { + auto attType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(bufs[i]); // ------------------- Check validity begin ------------------------ if (attType == FramebufferAttachmentType::Unknown) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", __func__, + std::format("bufs[{}] = {} is not an accepted value.", i, + MG_Util::ConvertGLEnumToString(bufs[i])))); + return; + } + + if (isDefaultFBO && attType >= FramebufferAttachmentType::Color0 && + attType <= FramebufferAttachmentType::Color31) { MG_State::pGLContext->RecordError( ErrorCode::InvalidEnum, MakeShared( "MG_Impl/GLImpl", __func__, - std::format("`mode` = {} is not an accepted value.", MG_Util::ConvertGLEnumToString(mode)))); + std::format( + "FBO is default FBO, but bufs[{}] = {} is one of the `GL_COLOR_ATTACHMENTn` tokens.", i, + MG_Util::ConvertGLEnumToString(bufs[i])))); return; } - // Get bound framebuffer - auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read); - auto fbo = bindingSlot.GetBoundObject(); - fbo->SetReadBuffer(attType); - } - - void DeleteRenderbuffers_State(GLsizei n, const GLuint* renderbuffers) { - if (n < 0) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, MakeShared("MG_Impl/GLImpl", "DeleteRenderbuffers_State", - "n must be non-negative.")); - return; - } - - if (!renderbuffers) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, MakeShared("MG_Impl/GLImpl", "DeleteRenderbuffers_State", - "Renderbuffer names array cannot be null.")); - return; - } - - for (SizeT i = 0; i < static_cast(n); ++i) { - Uint bufferName = renderbuffers[i]; - if (bufferName == 0) continue; - if (!FramebufferImpl::ValidateRenderbufferName(bufferName)) continue; - MG_State::pGLContext->MarkRenderbufferObjectForDeletion(bufferName); - } - } - - void DeleteFramebuffers_State(GLsizei n, const GLuint* framebuffers) { - if (n < 0) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, MakeShared("MG_Impl/GLImpl", "DeleteFramebuffers_State", - "n must be non-negative.")); - return; - } - - if (!framebuffers) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, MakeShared("MG_Impl/GLImpl", "DeleteFramebuffers_State", - "Framebuffer names array cannot be null.")); - return; - } - - for (SizeT i = 0; i < static_cast(n); ++i) { - Uint bufferName = framebuffers[i]; - if (bufferName == 0) continue; - if (!FramebufferImpl::ValidateFramebufferName(bufferName)) continue; - MG_State::pGLContext->MarkFramebufferObjectForDeletion(bufferName); - } - } - - GLenum CheckFramebufferStatus_State(GLenum target) { - FramebufferTarget framebufferTarget = MG_Util::ConvertGLEnumToFramebufferTarget(target); - if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return GL_FRAMEBUFFER_UNDEFINED; - - auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget); - auto framebufferObject = bindingSlot.GetBoundObject(); - if (!framebufferObject) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "CheckFramebufferStatus_State", - "Framebuffer target is bound to no framebuffer object.")); - return GL_FRAMEBUFFER_UNDEFINED; - } - - // TODO: distinguish GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT and GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT - // TODO: GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER, GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER, - // GL_FRAMEBUFFER_UNSUPPORTED, GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, - // GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS - return framebufferObject->CheckCompleteness() ? GL_FRAMEBUFFER_COMPLETE - : GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; - } - - void BindRenderbuffer_State(GLenum target, GLuint renderbuffer) { - if (!FramebufferImpl::ValidateRenderbufferName(renderbuffer)) return; - RenderbufferTarget renderbufferTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target); - if (!FramebufferImpl::ValidateRenderbufferTarget(renderbufferTarget)) return; - - auto renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer); - if (!renderbufferObject) { - MG_State::pGLContext->CreateRenderbufferObject(renderbuffer); - renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer); - } - - auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(renderbufferTarget); - bindingSlot.Bind(renderbufferObject); - } - - void BindFramebuffer_State(GLenum target, GLuint framebuffer) { - if (target == GL_FRAMEBUFFER) { - BindFramebuffer_State(GL_DRAW_FRAMEBUFFER, framebuffer); - BindFramebuffer_State(GL_READ_FRAMEBUFFER, framebuffer); - return; - } - - if (!FramebufferImpl::ValidateFramebufferName(framebuffer)) return; - FramebufferTarget framebufferTarget = MG_Util::ConvertGLEnumToFramebufferTarget(target); - if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return; - - auto framebufferObject = MG_State::pGLContext->GetFramebufferObject(framebuffer); - if (!framebufferObject) { - MG_State::pGLContext->CreateFramebufferObject(framebuffer); - framebufferObject = MG_State::pGLContext->GetFramebufferObject(framebuffer); - } - - auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget); - bindingSlot.Bind(framebufferObject); - } - - void GetRenderbufferParameteriv_State(GLenum target, GLenum pname, GLint* params) { - if (!params) return; - - RenderbufferTarget renderbufferTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target); - if (!FramebufferImpl::ValidateRenderbufferTarget(renderbufferTarget)) return; - auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(renderbufferTarget); - auto renderbufferObject = bindingSlot.GetBoundObject(); - if (!renderbufferObject) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "GetRenderbufferParameteriv_State", - "Renderbuffer target is bound to no renderbuffer object.")); - return; - } - - switch (pname) { - case GL_RENDERBUFFER_WIDTH: - *params = static_cast(renderbufferObject->GetWidth()); - break; - case GL_RENDERBUFFER_HEIGHT: - *params = static_cast(renderbufferObject->GetHeight()); - break; - case GL_RENDERBUFFER_INTERNAL_FORMAT: - *params = MG_Util::ConvertTextureInternalFormatToGLEnum(renderbufferObject->GetInternalFormat()); - break; - case GL_RENDERBUFFER_RED_SIZE: - *params = static_cast(renderbufferObject->GetRedSize()); - break; - case GL_RENDERBUFFER_GREEN_SIZE: - *params = static_cast(renderbufferObject->GetGreenSize()); - break; - case GL_RENDERBUFFER_BLUE_SIZE: - *params = static_cast(renderbufferObject->GetBlueSize()); - break; - case GL_RENDERBUFFER_ALPHA_SIZE: - *params = static_cast(renderbufferObject->GetAlphaSize()); - break; - case GL_RENDERBUFFER_DEPTH_SIZE: - *params = static_cast(renderbufferObject->GetDepthSize()); - break; - case GL_RENDERBUFFER_STENCIL_SIZE: - *params = static_cast(renderbufferObject->GetStencilSize()); - break; - case GL_RENDERBUFFER_SAMPLES: - *params = static_cast(renderbufferObject->GetSamples()); - break; - default: + if (!isDefaultFBO && attType >= FramebufferAttachmentType::FrontLeft && + attType <= FramebufferAttachmentType::BackRight) { MG_State::pGLContext->RecordError( ErrorCode::InvalidEnum, MakeShared( - "MG_Impl/GLImpl", "GetRenderbufferParameteriv_State", - std::format("pname {} is not an accepted value.", MG_Util::ConvertGLEnumToString(pname)))); + "MG_Impl/GLImpl", __func__, + std::format("FBO is not default FBO, but bufs[{}] = {} is anything other than `GL_NONE` or " + "one of the `GL_COLOR_ATTACHMENTn` tokens.", + i, MG_Util::ConvertGLEnumToString(bufs[i])))); return; } - } - void ClearBufferfi_Backend(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::ClearBufferfi(buffer, drawbuffer, depth, stencil); -#endif - } - - void ClearBufferfv_Backend(GLenum buffer, GLint drawbuffer, const GLfloat* value) { -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::ClearBufferfv(buffer, drawbuffer, value); -#endif - } - - void ClearBufferuiv_Backend(GLenum buffer, GLint drawbuffer, const GLuint* value) { -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::ClearBufferuiv(buffer, drawbuffer, value); -#endif - } - - void ClearBufferiv_Backend(GLenum buffer, GLint drawbuffer, const GLint* value) { -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::ClearBufferiv(buffer, drawbuffer, value); -#endif - } - - void ReadPixels_State(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - void* pixels) { - TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format); - TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type); - - // Check width/height - if (width < 0 || height < 0) { + if (attType != FramebufferAttachmentType::None && existenceMap[(SizeT)attType] >= 0) { MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, MakeShared("MG_Impl/GLImpl", "ReadPixels_State", - "Width and height must be non-negative")); + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", __func__, + std::format("a symbolic constant other than `GL_NONE` appears " + "more than once in bufs. bufs[{}] == bufs[{}] == {}.", + i, existenceMap[(SizeT)attType], + MG_Util::ConvertGLEnumToString(bufs[i])))); return; } - // Validate format - if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) { + existenceMap[(SizeT)attType] = i; + + if ((SizeT)attType > + (SizeT)FramebufferAttachmentType::Color0 + MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) { MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", "ReadPixels_State", "Invalid format")); + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", __func__, + std::format("bufs[{}] == {} indicates a color buffer that does " + "not exist in the current GL context.", + i, MG_Util::ConvertGLEnumToString(bufs[i])))); return; } + // ------------------------- Check validity end ---------------------------------- + fbo->SetDrawBuffer(i, attType); + } + for (GLsizei i = n; i < MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; ++i) { + fbo->SetDrawBuffer(i, FramebufferAttachmentType::None); + } + } - // Validate type - if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) { + void DrawBuffer_State(GLenum buf) { + if (buf == GL_NONE) { + DrawBuffers_State(0, nullptr); + } else { + static GLenum bufs[] = {buf}; + DrawBuffers_State(1, bufs); + } + } + + void ReadBuffer_State(GLenum mode) { + auto attType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(mode); + + // ------------------- Check validity begin ------------------------ + if (attType == FramebufferAttachmentType::Unknown) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared( + "MG_Impl/GLImpl", __func__, + std::format("`mode` = {} is not an accepted value.", MG_Util::ConvertGLEnumToString(mode)))); + return; + } + + // Get bound framebuffer + auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read); + auto fbo = bindingSlot.GetBoundObject(); + fbo->SetReadBuffer(attType); + } + + void DeleteRenderbuffers_State(GLsizei n, const GLuint* renderbuffers) { + if (n < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", "DeleteRenderbuffers_State", "n must be non-negative.")); + return; + } + + if (!renderbuffers) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, MakeShared("MG_Impl/GLImpl", "DeleteRenderbuffers_State", + "Renderbuffer names array cannot be null.")); + return; + } + + for (SizeT i = 0; i < static_cast(n); ++i) { + Uint bufferName = renderbuffers[i]; + if (bufferName == 0) continue; + if (!FramebufferImpl::ValidateRenderbufferName(bufferName)) continue; + MG_State::pGLContext->MarkRenderbufferObjectForDeletion(bufferName); + } + } + + void DeleteFramebuffers_State(GLsizei n, const GLuint* framebuffers) { + if (n < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", "DeleteFramebuffers_State", "n must be non-negative.")); + return; + } + + if (!framebuffers) { + MG_State::pGLContext->RecordError(ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", "DeleteFramebuffers_State", + "Framebuffer names array cannot be null.")); + return; + } + + for (SizeT i = 0; i < static_cast(n); ++i) { + Uint bufferName = framebuffers[i]; + if (bufferName == 0) continue; + if (!FramebufferImpl::ValidateFramebufferName(bufferName)) continue; + MG_State::pGLContext->MarkFramebufferObjectForDeletion(bufferName); + } + } + + GLenum CheckFramebufferStatus_State(GLenum target) { + FramebufferTarget framebufferTarget = MG_Util::ConvertGLEnumToFramebufferTarget(target); + if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return GL_FRAMEBUFFER_UNDEFINED; + + auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget); + auto framebufferObject = bindingSlot.GetBoundObject(); + if (!framebufferObject) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "CheckFramebufferStatus_State", + "Framebuffer target is bound to no framebuffer object.")); + return GL_FRAMEBUFFER_UNDEFINED; + } + + // TODO: distinguish GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT and GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT + // TODO: GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER, GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER, + // GL_FRAMEBUFFER_UNSUPPORTED, GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, + // GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS + return framebufferObject->CheckCompleteness() ? GL_FRAMEBUFFER_COMPLETE + : GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; + } + + void BindRenderbuffer_State(GLenum target, GLuint renderbuffer) { + if (!FramebufferImpl::ValidateRenderbufferName(renderbuffer)) return; + RenderbufferTarget renderbufferTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target); + if (!FramebufferImpl::ValidateRenderbufferTarget(renderbufferTarget)) return; + + auto renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer); + if (!renderbufferObject) { + MG_State::pGLContext->CreateRenderbufferObject(renderbuffer); + renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer); + } + + auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(renderbufferTarget); + bindingSlot.Bind(renderbufferObject); + } + + void BindFramebuffer_State(GLenum target, GLuint framebuffer) { + if (target == GL_FRAMEBUFFER) { + BindFramebuffer_State(GL_DRAW_FRAMEBUFFER, framebuffer); + BindFramebuffer_State(GL_READ_FRAMEBUFFER, framebuffer); + return; + } + + if (!FramebufferImpl::ValidateFramebufferName(framebuffer)) return; + FramebufferTarget framebufferTarget = MG_Util::ConvertGLEnumToFramebufferTarget(target); + if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return; + + auto framebufferObject = MG_State::pGLContext->GetFramebufferObject(framebuffer); + if (!framebufferObject) { + MG_State::pGLContext->CreateFramebufferObject(framebuffer); + framebufferObject = MG_State::pGLContext->GetFramebufferObject(framebuffer); + } + + auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget); + bindingSlot.Bind(framebufferObject); + } + + void GetRenderbufferParameteriv_State(GLenum target, GLenum pname, GLint* params) { + if (!params) return; + + RenderbufferTarget renderbufferTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target); + if (!FramebufferImpl::ValidateRenderbufferTarget(renderbufferTarget)) return; + auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(renderbufferTarget); + auto renderbufferObject = bindingSlot.GetBoundObject(); + if (!renderbufferObject) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "GetRenderbufferParameteriv_State", + "Renderbuffer target is bound to no renderbuffer object.")); + return; + } + + switch (pname) { + case GL_RENDERBUFFER_WIDTH: + *params = static_cast(renderbufferObject->GetWidth()); + break; + case GL_RENDERBUFFER_HEIGHT: + *params = static_cast(renderbufferObject->GetHeight()); + break; + case GL_RENDERBUFFER_INTERNAL_FORMAT: + *params = MG_Util::ConvertTextureInternalFormatToGLEnum(renderbufferObject->GetInternalFormat()); + break; + case GL_RENDERBUFFER_RED_SIZE: + *params = static_cast(renderbufferObject->GetRedSize()); + break; + case GL_RENDERBUFFER_GREEN_SIZE: + *params = static_cast(renderbufferObject->GetGreenSize()); + break; + case GL_RENDERBUFFER_BLUE_SIZE: + *params = static_cast(renderbufferObject->GetBlueSize()); + break; + case GL_RENDERBUFFER_ALPHA_SIZE: + *params = static_cast(renderbufferObject->GetAlphaSize()); + break; + case GL_RENDERBUFFER_DEPTH_SIZE: + *params = static_cast(renderbufferObject->GetDepthSize()); + break; + case GL_RENDERBUFFER_STENCIL_SIZE: + *params = static_cast(renderbufferObject->GetStencilSize()); + break; + case GL_RENDERBUFFER_SAMPLES: + *params = static_cast(renderbufferObject->GetSamples()); + break; + default: + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared( + "MG_Impl/GLImpl", "GetRenderbufferParameteriv_State", + std::format("pname {} is not an accepted value.", MG_Util::ConvertGLEnumToString(pname)))); + return; + } + } + + void ClearBufferfi_Backend(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { + MG_Backend::gBackendFunctionsTable.GL.ClearBufferfi(buffer, drawbuffer, depth, stencil); + } + + void ClearBufferfv_Backend(GLenum buffer, GLint drawbuffer, const GLfloat* value) { + MG_Backend::gBackendFunctionsTable.GL.ClearBufferfv(buffer, drawbuffer, value); + } + + void ClearBufferuiv_Backend(GLenum buffer, GLint drawbuffer, const GLuint* value) { + MG_Backend::gBackendFunctionsTable.GL.ClearBufferuiv(buffer, drawbuffer, value); + } + + void ClearBufferiv_Backend(GLenum buffer, GLint drawbuffer, const GLint* value) { + MG_Backend::gBackendFunctionsTable.GL.ClearBufferiv(buffer, drawbuffer, value); + } + + void ReadPixels_State(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) { + TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format); + TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type); + + // Check width/height + if (width < 0 || height < 0) { + MG_State::pGLContext->RecordError(ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", "ReadPixels_State", + "Width and height must be non-negative")); + return; + } + + // Validate format + if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", "ReadPixels_State", "Invalid format")); + return; + } + + // Validate type + if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", "ReadPixels_State", "Invalid pixel data type")); + return; + } + + // Get bound framebuffer + auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read); + auto framebufferObject = bindingSlot.GetBoundObject(); + + if (!framebufferObject) { + MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "ReadPixels_State", + "No framebuffer bound to read target")); + return; + } + + // Check framebuffer completeness + if (!framebufferObject->CheckCompleteness()) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidFramebufferOperation, + MakeShared("MG_Impl/GLImpl", "ReadPixels_State", "Framebuffer is incomplete")); + return; + } + + // Check for required buffers + if (textureInputFormat == TextureInputFormat::StencilIndex) { + if (!framebufferObject->GetAttachment(FramebufferAttachmentType::Stencil).IsValid()) { MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", "ReadPixels_State", "Invalid pixel data type")); + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "ReadPixels_State", + "No stencil buffer for stencil index format")); return; } - - // Get bound framebuffer - auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read); - auto framebufferObject = bindingSlot.GetBoundObject(); - - if (!framebufferObject) { - MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "ReadPixels_State", - "No framebuffer bound to read target")); - return; - } - - // Check framebuffer completeness - if (!framebufferObject->CheckCompleteness()) { + } else if (textureInputFormat == TextureInputFormat::DepthComponent) { + if (!framebufferObject->GetAttachment(FramebufferAttachmentType::Depth).IsValid()) { MG_State::pGLContext->RecordError( - ErrorCode::InvalidFramebufferOperation, - MakeShared("MG_Impl/GLImpl", "ReadPixels_State", "Framebuffer is incomplete")); + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "ReadPixels_State", + "No depth buffer for depth component format")); + return; + } + } else if (textureInputFormat == TextureInputFormat::DepthStencil) { + if (!framebufferObject->GetAttachment(FramebufferAttachmentType::Depth).IsValid() || + !framebufferObject->GetAttachment(FramebufferAttachmentType::Stencil).IsValid()) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "ReadPixels_State", + "No depth/stencil buffer for depth-stencil format")); return; } - // Check for required buffers - if (textureInputFormat == TextureInputFormat::StencilIndex) { - if (!framebufferObject->GetAttachment(FramebufferAttachmentType::Stencil).IsValid()) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "ReadPixels_State", - "No stencil buffer for stencil index format")); - return; - } - } else if (textureInputFormat == TextureInputFormat::DepthComponent) { - if (!framebufferObject->GetAttachment(FramebufferAttachmentType::Depth).IsValid()) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "ReadPixels_State", - "No depth buffer for depth component format")); - return; - } - } else if (textureInputFormat == TextureInputFormat::DepthStencil) { - if (!framebufferObject->GetAttachment(FramebufferAttachmentType::Depth).IsValid() || - !framebufferObject->GetAttachment(FramebufferAttachmentType::Stencil).IsValid()) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "ReadPixels_State", - "No depth/stencil buffer for depth-stencil format")); - return; - } - - // Validate type for depth/stencil - if (texturePixelDataType != TexturePixelDataType::UnsignedInt248 && - texturePixelDataType != TexturePixelDataType::Float32UnsignedInt248Rev) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, MakeShared("MG_Impl/GLImpl", "ReadPixels_State", - "Invalid type for depth-stencil format")); - return; - } - } - - // Check PBO state - const auto& pixelPackBufferObject = - MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); - - if (pixelPackBufferObject) { - // Check if PBO is mapped - if (pixelPackBufferObject->IsMapped()) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "ReadPixels_State", - "Pixel pack buffer is currently mapped")); - return; - } - - // Check alignment - const SizeT typeSize = MG_Util::GetTexturePixelDataTypeSize(texturePixelDataType); - if (reinterpret_cast(pixels) % typeSize != 0) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "ReadPixels_State", - "Pixel data not aligned for pixel pack buffer")); - return; - } - } - - // Check multisampling - if (framebufferObject->GetAttachment(FramebufferAttachmentType::Color0).IsRenderbuffer()) { - auto rbo = framebufferObject->GetAttachment(FramebufferAttachmentType::Color0).GetRenderbuffer(); - if (rbo && rbo->GetSamples() > 1) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "ReadPixels_State", - "ReadPixels not supported for multisampled framebuffers")); - return; - } + // Validate type for depth/stencil + if (texturePixelDataType != TexturePixelDataType::UnsignedInt248 && + texturePixelDataType != TexturePixelDataType::Float32UnsignedInt248Rev) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, MakeShared("MG_Impl/GLImpl", "ReadPixels_State", + "Invalid type for depth-stencil format")); + return; } } - void ReadPixels_Backend(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - void* pixels) { -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::ReadPixels(x, y, width, height, format, type, pixels); -#endif + // Check PBO state + const auto& pixelPackBufferObject = + MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); + + if (pixelPackBufferObject) { + // Check if PBO is mapped + if (pixelPackBufferObject->IsMapped()) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, MakeShared("MG_Impl/GLImpl", "ReadPixels_State", + "Pixel pack buffer is currently mapped")); + return; + } + + // Check alignment + const SizeT typeSize = MG_Util::GetTexturePixelDataTypeSize(texturePixelDataType); + if (reinterpret_cast(pixels) % typeSize != 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "ReadPixels_State", + "Pixel data not aligned for pixel pack buffer")); + return; + } } - /* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */ - void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) { - ReadPixels_State(x, y, width, height, format, type, pixels); - ReadPixels_Backend(x, y, width, height, format, type, pixels); + // Check multisampling + if (framebufferObject->GetAttachment(FramebufferAttachmentType::Color0).IsRenderbuffer()) { + auto rbo = framebufferObject->GetAttachment(FramebufferAttachmentType::Color0).GetRenderbuffer(); + if (rbo && rbo->GetSamples() > 1) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "ReadPixels_State", + "ReadPixels not supported for multisampled framebuffers")); + return; + } } + } - void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { - ClearBufferfi_Backend(buffer, drawbuffer, depth, stencil); - } + void ReadPixels_Backend(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) { + MG_Backend::gBackendFunctionsTable.GL.ReadPixels(x, y, width, height, format, type, pixels); + } - void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) { - ClearBufferfv_Backend(buffer, drawbuffer, value); - } + /* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */ + void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) { + ReadPixels_State(x, y, width, height, format, type, pixels); + ReadPixels_Backend(x, y, width, height, format, type, pixels); + } - void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) { - ClearBufferuiv_Backend(buffer, drawbuffer, value); - } + void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { + ClearBufferfi_Backend(buffer, drawbuffer, depth, stencil); + } - void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) { - ClearBufferiv_Backend(buffer, drawbuffer, value); - } + void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) { + ClearBufferfv_Backend(buffer, drawbuffer, value); + } - void SampleMaski(GLuint maskNumber, GLbitfield mask) { - SampleMaski_State(maskNumber, mask); - } + void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) { + ClearBufferuiv_Backend(buffer, drawbuffer, value); + } - void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, - GLsizei height) { - RenderbufferStorageMultisample_State(target, samples, internalformat, width, height); - } + void ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) { + ClearBufferiv_Backend(buffer, drawbuffer, value); + } - void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { - RenderbufferStorage_State(target, internalformat, width, height); - } + void SampleMaski(GLuint maskNumber, GLbitfield mask) { + SampleMaski_State(maskNumber, mask); + } - GLboolean IsRenderbuffer(GLuint renderbuffer) { - return IsRenderbuffer_State(renderbuffer); - } + void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, + GLsizei height) { + RenderbufferStorageMultisample_State(target, samples, internalformat, width, height); + } - GLboolean IsFramebuffer(GLuint framebuffer) { - return IsFramebuffer_State(framebuffer); - } + void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { + RenderbufferStorage_State(target, internalformat, width, height); + } - void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) { - GetFramebufferAttachmentParameteriv_State(target, attachment, pname, params); - } + GLboolean IsRenderbuffer(GLuint renderbuffer) { + return IsRenderbuffer_State(renderbuffer); + } - void GenerateMipmap(GLenum target) { - GenerateMipmap_Backend(target); - } + GLboolean IsFramebuffer(GLuint framebuffer) { + return IsFramebuffer_State(framebuffer); + } - void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) { - GenRenderbuffers_State(n, renderbuffers); - } + void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) { + GetFramebufferAttachmentParameteriv_State(target, attachment, pname, params); + } - void GenFramebuffers(GLsizei n, GLuint* framebuffers) { - GenFramebuffers_State(n, framebuffers); - } + void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) { + GenRenderbuffers_State(n, renderbuffers); + } - void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { - FramebufferTextureLayer_State(target, attachment, texture, level, layer); - } + void GenFramebuffers(GLsizei n, GLuint* framebuffers) { + GenFramebuffers_State(n, framebuffers); + } - void FramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, - GLint zoffset) { - FramebufferTexture3D_State(target, attachment, textarget, texture, level, zoffset); - } + void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { + FramebufferTextureLayer_State(target, attachment, texture, level, layer); + } - void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { - FramebufferTexture2D_State(target, attachment, textarget, texture, level); - } + void FramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, + GLint zoffset) { + FramebufferTexture3D_State(target, attachment, textarget, texture, level, zoffset); + } - void FramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { - FramebufferTexture1D_State(target, attachment, textarget, texture, level); - } + void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { + FramebufferTexture2D_State(target, attachment, textarget, texture, level); + } - void FramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level) { - FramebufferTexture_State(target, attachment, texture, level); - } + void FramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { + FramebufferTexture1D_State(target, attachment, textarget, texture, level); + } - void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { - FramebufferRenderbuffer_State(target, attachment, renderbuffertarget, renderbuffer); - } + void FramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level) { + FramebufferTexture_State(target, attachment, texture, level); + } - void DrawBuffer(GLenum buf) { - DrawBuffer_State(buf); - } + void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { + FramebufferRenderbuffer_State(target, attachment, renderbuffertarget, renderbuffer); + } - void DrawBuffers(GLsizei n, const GLenum* bufs) { - DrawBuffers_State(n, bufs); - } + void DrawBuffer(GLenum buf) { + DrawBuffer_State(buf); + } - void ReadBuffer(GLenum src) { - ReadBuffer_State(src); - } + void DrawBuffers(GLsizei n, const GLenum* bufs) { + DrawBuffers_State(n, bufs); + } - void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) { - DeleteRenderbuffers_State(n, renderbuffers); - } + void ReadBuffer(GLenum src) { + ReadBuffer_State(src); + } - void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) { - DeleteFramebuffers_State(n, framebuffers); - } + void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) { + DeleteRenderbuffers_State(n, renderbuffers); + } - GLenum CheckFramebufferStatus(GLenum target) { - return CheckFramebufferStatus_State(target); - } + void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) { + DeleteFramebuffers_State(n, framebuffers); + } - void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, - GLint dstY1, GLbitfield mask, GLenum filter) { - BlitFramebuffer_Backend(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - } + GLenum CheckFramebufferStatus(GLenum target) { + return CheckFramebufferStatus_State(target); + } - void BindRenderbuffer(GLenum target, GLuint renderbuffer) { - BindRenderbuffer_State(target, renderbuffer); - } + void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, + GLint dstY1, GLbitfield mask, GLenum filter) { + BlitFramebuffer_Backend(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + } - void BindFramebuffer(GLenum target, GLuint framebuffer) { - BindFramebuffer_State(target, framebuffer); - } + void BindRenderbuffer(GLenum target, GLuint renderbuffer) { + BindRenderbuffer_State(target, renderbuffer); + } - void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) { - GetRenderbufferParameteriv_State(target, pname, params); - } + void BindFramebuffer(GLenum target, GLuint framebuffer) { + BindFramebuffer_State(target, framebuffer); + } - namespace FramebufferImpl { - DefaultFramebufferInfo* pDefaultFramebufferInfo; - } - } // namespace MG_Impl::GLImpl -} // namespace MobileGL + void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) { + GetRenderbufferParameteriv_State(target, pname, params); + } + + namespace FramebufferImpl { + DefaultFramebufferInfo* pDefaultFramebufferInfo; + } // namespace FramebufferImpl +} // namespace MobileGL::MG_Impl::GLImpl diff --git a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h index 9b34e637..c1263355 100644 --- a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h +++ b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h @@ -29,14 +29,8 @@ namespace MobileGL { void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers); void BindRenderbuffer(GLenum target, GLuint renderbuffer); void SampleMaski(GLuint maskNumber, GLbitfield mask); - void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, - GLsizei height); - void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); - GLboolean IsRenderbuffer(GLuint renderbuffer); GLboolean IsFramebuffer(GLuint framebuffer); void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params); - void GenerateMipmap(GLenum target); - void GenRenderbuffers(GLsizei n, GLuint* renderbuffers); void GenFramebuffers(GLsizei n, GLuint* framebuffers); void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); void FramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, @@ -44,16 +38,13 @@ namespace MobileGL { void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); void FramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); void FramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level); - void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); void DrawBuffer(GLenum buf); void DrawBuffers(GLsizei n, const GLenum* bufs); void ReadBuffer(GLenum src); - void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers); void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers); GLenum CheckFramebufferStatus(GLenum target); void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); - void BindRenderbuffer(GLenum target, GLuint renderbuffer); void BindFramebuffer(GLenum target, GLuint framebuffer); namespace FramebufferImpl { diff --git a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp index d9bc6ebb..a4233874 100644 --- a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp +++ b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp @@ -7,6 +7,8 @@ // End of Source File Header #include "GL_Getter.h" +#include "GL/gl.h" +#include "MG_Util/Debug/Log.h" #include #include #include @@ -16,909 +18,883 @@ #include #include #include -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES -#include -#include "MG_Util/BackendLoaders/OpenGL/Loader.h" -#endif +#include -namespace MobileGL { - namespace MG_Impl::GLImpl { - const GLubyte* GetString_Backend(GLenum name) { -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - return MG_Backend::DirectGLES::GetString(name); -#endif +namespace MobileGL::MG_Impl::GLImpl { + /* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */ + const GLubyte* GetString(GLenum name) { + static String vendorString; + static String versionStr; + static String rendererString; + static String shadingLanguageVersion; + static String extensionsString; + const auto& activeBackendObject = MG_Backend::pActiveBackendObject; + + MGLOG_D("glGetString, name: %s", MG_Util::ConvertGLEnumToString(name).c_str()); + if (!activeBackendObject) { + MGLOG_E("activeBackendObject is not initialized!"); + return (GLubyte*)"Unknown"; } - inline String GetFormattedBackendGLVersion() { - const char* raw = reinterpret_cast(GetString_Backend(GL_VERSION)); - if (!raw || raw[0] == '\0') { - return "Unknown"; - } + const auto& rendererInfo = activeBackendObject->GetRendererInfo(); - constexpr SizeT kOpenGLESLen = 9; // "OpenGL ES" - if (std::strncmp(raw, "OpenGL ES", kOpenGLESLen) == 0) { - std::istringstream iss(raw); - String a, b, c; - if (iss >> a >> b >> c) { - return a + " " + b + " " + c; // e.g. "OpenGL ES 3.2" + switch (name) { + case GL_VENDOR: + if (vendorString.empty()) { + if (rendererInfo.ExtraVendor.has_value()) { + vendorString = std::format("{}{}", MG_Config::CoreVendor, rendererInfo.ExtraVendor.value()); } else { - return "OpenGL ES ?"; + vendorString = MG_Config::CoreVendor; } } - - { - std::istringstream iss(raw); - String ver; - if (iss >> ver) { - return String("OpenGL ") + ver; // e.g. "OpenGL 4.6" - } + MGLOG_D("vendorString: %s", vendorString.c_str()); + return (const GLubyte*)vendorString.c_str(); + case GL_VERSION: { + if (versionStr.empty()) { + versionStr = + std::format("{} {} {}, {} Backend, GIT@" GIT_COMMIT_HASH_SHORT, + rendererInfo.RendererGLInfo.TargetGLVersion.toString(), MG_Config::ProjectName, + MG_Config::CoreVersion.toFormattedString(MG_Config::DefaultVersionStringFormatAttrib), + rendererInfo.BackendName); } + MGLOG_D("versionStr: %s", versionStr.c_str()); + return (const GLubyte*)versionStr.c_str(); + } + case GL_RENDERER: { + if (rendererString.empty()) { + String backendVersionStr = activeBackendObject->GetBackendAPIVersionString(); + rendererString = + std::format("{} ({}) ({})", rendererInfo.RendererName, MG_Config::CoreName, backendVersionStr); + } + MGLOG_D("rendererString: %s", rendererString.c_str()); + return (const GLubyte*)rendererString.c_str(); + } + case GL_SHADING_LANGUAGE_VERSION: + if (shadingLanguageVersion.empty()) { + shadingLanguageVersion = + std::format("{} {}", rendererInfo.RendererGLInfo.TargetGLSLVersion.toString({true, false}), + MG_Config::ProjectName); + } + MGLOG_D("shadingLanguageVersion: %s", shadingLanguageVersion.c_str()); + return (const GLubyte*)shadingLanguageVersion.c_str(); + case GL_EXTENSIONS: + if (extensionsString.empty()) { + for (auto& ext : rendererInfo.RendererGLInfo.Extensions) { + extensionsString += MG_Util::ConvertGLExtToString(ext); + extensionsString += " "; + } + extensionsString.pop_back(); + } + return (const GLubyte*)extensionsString.c_str(); + default: + return (const GLubyte*)"Unknown Enum"; + } + } - return "Unknown"; + const GLubyte* GetStringi(GLenum name, GLuint index) { + MGLOG_D("glGetStringi, name: %s, index: %u", MG_Util::ConvertGLEnumToString(name).c_str(), index); + if (name != GL_EXTENSIONS) { + return (const GLubyte*)""; } - /* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */ - const GLubyte* GetString(GLenum name) { - static String vendorString; - static String versionStr; - static String rendererString; - static String shadingLanguageVersion; - static String extensionsString; - MGLOG_D("glGetString, name: %s", MG_Util::ConvertGLEnumToString(name).c_str()); - switch (name) { - case GL_VENDOR: - if (vendorString.empty()) { - if (MG_Config::RendererInfoPtr->ExtraVendor.has_value()) { - vendorString = - std::format("{}{}", MG_Config::CoreVendor, MG_Config::RendererInfoPtr->ExtraVendor.value()); - } else { - vendorString = MG_Config::CoreVendor; - } - } - return (const GLubyte*)vendorString.c_str(); - case GL_VERSION: { - if (versionStr.empty()) { - versionStr = std::format( - "{} {} {}, {} Backend, GIT@" GIT_COMMIT_HASH_SHORT, - MG_Config::RendererInfoPtr->RendererGLInfo.TargetGLVersion.toString().c_str(), - MG_Config::ProjectName.c_str(), - MG_Config::CoreVersion.toFormattedString(MG_Config::DefaultVersionStringFormatAttrib).c_str(), - MG_Config::RendererInfoPtr->BackendName.c_str()); - } - return (const GLubyte*)versionStr.c_str(); - } - case GL_RENDERER: { - if (rendererString.empty()) { - const char* backendStr = (const char*)GetString_Backend(GL_RENDERER); - String backendVersionStr = GetFormattedBackendGLVersion(); - rendererString = std::format("{} ({}) ({}, {})", MG_Config::RendererInfoPtr->RendererName.c_str(), - MG_Config::CoreName.c_str(), backendStr ? backendStr : "", - !backendVersionStr.empty() ? backendVersionStr : ""); - } - return (const GLubyte*)rendererString.c_str(); - } - case GL_SHADING_LANGUAGE_VERSION: - if (shadingLanguageVersion.empty()) { - shadingLanguageVersion = std::format( - "{} {}", - MG_Config::RendererInfoPtr->RendererGLInfo.TargetGLSLVersion.toString({true, false}).c_str(), - MG_Config::ProjectName.c_str()); - } - return (const GLubyte*)shadingLanguageVersion.c_str(); - case GL_EXTENSIONS: - if (extensionsString.empty()) { - for (auto& ext : MG_Config::RendererInfoPtr->RendererGLInfo.Extensions) { - extensionsString += MG_Util::ConvertGLExtToString(ext); - extensionsString += " "; - } - extensionsString.pop_back(); - } - return (const GLubyte*)extensionsString.c_str(); - default: - return (const GLubyte*)"Unknown Enum"; - } + const auto& activeBackendObject = MG_Backend::pActiveBackendObject; + if (!activeBackendObject) { + MGLOG_E("activeBackendObject is not initialized!"); + return (GLubyte*)"Unknown"; + } + const auto& rendererInfo = activeBackendObject->GetRendererInfo(); + + const auto& exts = rendererInfo.RendererGLInfo.Extensions; + if (index >= exts.size()) { + return nullptr; } - const GLubyte* GetStringi(GLenum name, GLuint index) { - MGLOG_D("glGetStringi, name: %s, index: %u", MG_Util::ConvertGLEnumToString(name).c_str(), index); - if (name != GL_EXTENSIONS) { - return (const GLubyte*)""; + static Vector extStrings; + static Bool initialized = false; + if (!initialized) { + extStrings.reserve(exts.size()); + for (const auto& ext : exts) { + extStrings.emplace_back(MG_Util::ConvertGLExtToString(ext)); } - - const auto& exts = MG_Config::RendererInfoPtr->RendererGLInfo.Extensions; - if (index >= exts.size()) { - return nullptr; - } - - static Vector extStrings; - static Bool initialized = false; - if (!initialized) { - extStrings.reserve(exts.size()); - for (const auto& ext : exts) { - extStrings.emplace_back(MG_Util::ConvertGLExtToString(ext)); - } - initialized = true; - } - - return (const GLubyte*)extStrings[index].c_str(); + initialized = true; } - void GetIntegerv(GLenum pname, GLint* params) { - MGLOG_D("glGetIntegerv, pname: %s", MG_Util::ConvertGLEnumToString(pname).c_str()); - if (!params) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, - MakeShared("MG_Impl/GLImpl", "GetIntegerv", "params pointer cannot be null")); - return; - } + return (const GLubyte*)extStrings[index].c_str(); + } - switch (pname) { - case GL_ACTIVE_TEXTURE: - *params = MG_State::pGLContext->GetActiveTextureUnit() + GL_TEXTURE0; - break; - case GL_ALIASED_LINE_WIDTH_RANGE: - *params = 0; // TODO - break; - case GL_ARRAY_BUFFER_BINDING: { - auto obj = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Vertex).GetBoundObject(); - if (obj) - *params = obj->GetExternalIndex(); - else - *params = 0; - break; - } - case GL_BLEND: - *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::Blend) ? GL_TRUE : GL_FALSE; - break; - case GL_BLEND_COLOR: - *params = 0; // TODO - break; - case GL_BLEND_DST_ALPHA: { - BlendFactor srcRGB, dstRGB, srcAlpha, dstAlpha; - MG_State::pGLContext->GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha); - *params = static_cast(dstAlpha); - break; - } - case GL_BLEND_DST_RGB: { - BlendFactor srcRGB, dstRGB, srcAlpha, dstAlpha; - MG_State::pGLContext->GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha); - *params = static_cast(dstRGB); - break; - } - case GL_BLEND_EQUATION_RGB: - *params = 0; // TODO - break; - case GL_BLEND_EQUATION_ALPHA: - *params = 0; // TODO - break; - case GL_BLEND_SRC_ALPHA: { - BlendFactor srcRGB, dstRGB, srcAlpha, dstAlpha; - MG_State::pGLContext->GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha); - *params = static_cast(srcAlpha); - break; - } - case GL_BLEND_SRC_RGB: { - BlendFactor srcRGB, dstRGB, srcAlpha, dstAlpha; - MG_State::pGLContext->GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha); - *params = static_cast(srcRGB); - break; - } - case GL_COLOR_CLEAR_VALUE: - *params = 0; // TODO - break; - case GL_COLOR_LOGIC_OP: - *params = 0; // TODO - break; - case GL_COLOR_WRITEMASK: { - BoolVec4 mask = MG_State::pGLContext->GetColorMask(); - params[0] = mask.x() ? GL_TRUE : GL_FALSE; - params[1] = mask.y() ? GL_TRUE : GL_FALSE; - params[2] = mask.z() ? GL_TRUE : GL_FALSE; - params[3] = mask.w() ? GL_TRUE : GL_FALSE; - break; - } - case GL_COMPRESSED_TEXTURE_FORMATS: - *params = 0; // TODO - break; - case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: - *params = 0; // TODO - break; - case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: - *params = 0; // TODO - break; - case GL_MAX_COMPUTE_UNIFORM_BLOCKS: - *params = 0; // TODO - break; - case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS: - *params = 0; // TODO - break; - case GL_MAX_COMPUTE_UNIFORM_COMPONENTS: - *params = 0; // TODO - break; - case GL_MAX_COMPUTE_ATOMIC_COUNTERS: - *params = 0; // TODO - break; - case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS: - *params = 0; // TODO - break; - case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS: - *params = 0; // TODO - break; - case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: - *params = 0; // TODO - break; - case GL_MAX_COMPUTE_WORK_GROUP_COUNT: - *params = 0; // TODO - break; - case GL_MAX_COMPUTE_WORK_GROUP_SIZE: - *params = 0; // TODO - break; - case GL_DISPATCH_INDIRECT_BUFFER_BINDING: - *params = 0; // TODO - break; - case GL_MAX_DEBUG_GROUP_STACK_DEPTH: - *params = 0; // TODO - break; - case GL_DEBUG_GROUP_STACK_DEPTH: - *params = 0; // TODO - break; - case GL_CONTEXT_FLAGS: - *params = 0; // TODO - break; - case GL_CULL_FACE: - *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::CullFace) ? GL_TRUE : GL_FALSE; - break; - case GL_CURRENT_PROGRAM: { - const auto& currentProgram = MG_State::pGLContext->GetCurrentProgram(); - *params = currentProgram ? currentProgram->GetExternalIndex() : 0; - break; - } - case GL_DEPTH_CLEAR_VALUE: - *params = MG_State::pGLContext->GetClearDepth(); - break; - case GL_DEPTH_FUNC: - *params = MG_Util::ConvertDepthTestFuncToGLEnum(MG_State::pGLContext->GetDepthFunc()); - break; - case GL_DEPTH_RANGE: - *params = 0; // TODO - break; - case GL_DEPTH_TEST: - *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::DepthTest) ? GL_TRUE : GL_FALSE; - break; - case GL_DEPTH_WRITEMASK: - *params = MG_State::pGLContext->GetDepthMask() ? GL_TRUE : GL_FALSE; - break; - case GL_DITHER: - *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::Dither) ? GL_TRUE : GL_FALSE; - break; - case GL_DOUBLEBUFFER: - *params = 0; // TODO - break; - case GL_DRAW_BUFFER: - *params = 0; // TODO - break; - case GL_DRAW_BUFFER0: - *params = 0; // TODO - break; - case GL_DRAW_FRAMEBUFFER_BINDING: { - const auto& FBO = - MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); - *params = FBO ? FBO->GetExternalIndex() : 0; - break; - } - case GL_READ_FRAMEBUFFER_BINDING: { - const auto& FBO = - MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); - *params = FBO ? FBO->GetExternalIndex() : 0; - break; - } - case GL_ELEMENT_ARRAY_BUFFER_BINDING: { - if (!MG_State::pGLContext->GetBoundVertexArray()) { - *params = 0; - break; - } - const auto& bufferObject = - MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Index).GetBoundObject(); - *params = bufferObject ? bufferObject->GetExternalIndex() : 0; - break; - } - case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: - *params = 0; // TODO - break; - case GL_IMPLEMENTATION_COLOR_READ_FORMAT: - *params = 0; // TODO - break; - case GL_IMPLEMENTATION_COLOR_READ_TYPE: - *params = 0; // TODO - break; - case GL_LINE_SMOOTH: - *params = 0; // TODO - break; - case GL_LINE_SMOOTH_HINT: - *params = 0; // TODO - break; - case GL_LINE_WIDTH: - *params = 0; // TODO - break; - case GL_LAYER_PROVOKING_VERTEX: - *params = 0; // TODO - break; - case GL_LOGIC_OP_MODE: - *params = 0; // TODO - break; - case GL_MAJOR_VERSION: - *params = MG_Config::RendererInfoPtr->RendererGLInfo.TargetGLVersion.Major; - break; - case GL_MAX_3D_TEXTURE_SIZE: - *params = 1024 * 16; // TODO - break; - case GL_MAX_ARRAY_TEXTURE_LAYERS: - *params = 2048; // TODO - break; - case GL_MAX_CLIP_DISTANCES: - *params = 8; // TODO - break; - case GL_MAX_COLOR_TEXTURE_SAMPLES: - *params = 16; // TODO - break; - case GL_MAX_COMBINED_ATOMIC_COUNTERS: - *params = 16; // TODO - break; - case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: - *params = 1024 * 228; // TODO - break; - case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS: - *params = 1024 * 228; // TODO - break; - case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: - *params = 192; // TODO - break; - case GL_MAX_COMBINED_UNIFORM_BLOCKS: - *params = 70; // TODO - break; - case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: - *params = 1024 * 228; // TODO - break; - case GL_MAX_CUBE_MAP_TEXTURE_SIZE: - *params = 1024 * 16; // TODO - break; - case GL_MAX_DEPTH_TEXTURE_SAMPLES: - *params = 16; // TODO - break; - case GL_MAX_DUAL_SOURCE_DRAW_BUFFERS: - *params = 1; // TODO - break; - case GL_MAX_ELEMENTS_INDICES: - *params = 1024 * 1024; // TODO - break; - case GL_MAX_ELEMENTS_VERTICES: - *params = 1024 * 1024; // TODO - break; - case GL_MAX_FRAGMENT_ATOMIC_COUNTERS: - *params = 1024 * 4; // TODO - break; - case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: - *params = 16; // TODO - break; - case GL_MAX_FRAGMENT_INPUT_COMPONENTS: - *params = 128; // TODO - break; - case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: - *params = 1024 * 4; // TODO - break; - case GL_MAX_FRAGMENT_UNIFORM_VECTORS: - *params = 256; // TODO - break; - case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: - *params = 14; // TODO - break; - case GL_MAX_FRAMEBUFFER_WIDTH: - *params = 1024 * 16; // TODO - break; - case GL_MAX_FRAMEBUFFER_HEIGHT: - *params = 1024 * 16; // TODO - break; - case GL_MAX_FRAMEBUFFER_LAYERS: - *params = 1024 * 2; // TODO - break; - case GL_MAX_FRAMEBUFFER_SAMPLES: - *params = 16; // TODO - break; - case GL_MAX_GEOMETRY_ATOMIC_COUNTERS: - *params = 14; // TODO - break; - case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS: - *params = 16; // TODO - break; - case GL_MAX_GEOMETRY_INPUT_COMPONENTS: - *params = 128; // TODO - break; - case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS: - *params = 128; // TODO - break; - case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: - *params = 8; // TODO - break; - case GL_MAX_GEOMETRY_UNIFORM_BLOCKS: - *params = 14; // TODO - break; - case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS: - *params = 1024 * 4; // TODO - break; - case GL_MAX_INTEGER_SAMPLES: - *params = 16; // TODO - break; - case GL_MIN_MAP_BUFFER_ALIGNMENT: - *params = 64; // TODO - break; - case GL_MAX_LABEL_LENGTH: - *params = 256; // TODO - break; - case GL_MAX_PROGRAM_TEXEL_OFFSET: - *params = 7; // TODO - break; - case GL_MIN_PROGRAM_TEXEL_OFFSET: - *params = -8; // TODO - break; - case GL_MAX_RECTANGLE_TEXTURE_SIZE: - *params = 16 * 1024; // TODO - break; - case GL_MAX_RENDERBUFFER_SIZE: - *params = 16 * 1024; // TODO - break; - case GL_MAX_SAMPLE_MASK_WORDS: - *params = 1; // TODO - break; - case GL_MAX_SERVER_WAIT_TIMEOUT: - *params = INT_MAX; // TODO - break; - case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: - *params = 16; // TODO - break; - case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS: - *params = 1024 * 4; // TODO - break; - case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS: - *params = 1024 * 4; // TODO - break; - case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS: - *params = 16; // TODO - break; - case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS: - *params = 16; // TODO - break; - case GL_MAX_TEXTURE_BUFFER_SIZE: - *params = 1024 * 1024 * 128; // TODO - break; - case GL_MAX_TEXTURE_IMAGE_UNITS: - *params = 32; // TODO - break; - case GL_MAX_TEXTURE_LOD_BIAS: - *params = 15; // TODO - break; - case GL_MAX_TEXTURE_SIZE: - *params = 1024 * 16; // TODO - break; - case GL_MAX_UNIFORM_BUFFER_BINDINGS: - *params = 84; // TODO - break; - case GL_MAX_UNIFORM_BLOCK_SIZE: - *params = 1024 * 24; // TODO - break; - case GL_MAX_UNIFORM_LOCATIONS: - *params = 1024 * 4; // TODO - break; - case GL_MAX_VARYING_COMPONENTS: - *params = 16; // TODO - break; - case GL_MAX_VARYING_VECTORS: - *params = 16; // TODO - break; - case GL_MAX_VERTEX_ATOMIC_COUNTERS: - *params = 1024 * 4; // TODO - break; - case GL_MAX_VERTEX_ATTRIBS: - *params = 16; // TODO - break; - case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: - *params = 16; // TODO - break; - case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: - *params = 32; // TODO - break; - case GL_MAX_VERTEX_UNIFORM_COMPONENTS: - *params = 1024 * 4; // TODO - break; - case GL_MAX_VERTEX_UNIFORM_VECTORS: - *params = 1024; // TODO - break; - case GL_MAX_VERTEX_OUTPUT_COMPONENTS: - *params = 128; // TODO - break; - case GL_MAX_VERTEX_UNIFORM_BLOCKS: - *params = 14; // TODO - break; - case GL_MAX_VIEWPORT_DIMS: - params[0] = 1024 * 16; // TODO - params[1] = 1024 * 16; // TODO - break; - case GL_MAX_VIEWPORTS: - *params = 16; // TODO - break; - case GL_MINOR_VERSION: - *params = MG_Config::RendererInfoPtr->RendererGLInfo.TargetGLVersion.Minor; - break; - case GL_NUM_COMPRESSED_TEXTURE_FORMATS: - *params = 18; // TODO - break; - case GL_NUM_EXTENSIONS: - *params = static_cast(MG_Config::RendererInfoPtr->RendererGLInfo.Extensions.size()); - break; - case GL_NUM_PROGRAM_BINARY_FORMATS: - *params = 2; // TODO - break; - case GL_NUM_SHADER_BINARY_FORMATS: - *params = 0; // TODO - break; - case GL_PACK_ALIGNMENT: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackAlignment); - break; - case GL_PACK_IMAGE_HEIGHT: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackImageHeight); - break; - case GL_PACK_LSB_FIRST: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackLSBFirst); - break; - case GL_PACK_ROW_LENGTH: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackRowLength); - break; - case GL_PACK_SKIP_IMAGES: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackSkipImages); - break; - case GL_PACK_SKIP_PIXELS: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackSkipPixels); - break; - case GL_PACK_SKIP_ROWS: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackSkipRows); - break; - case GL_PACK_SWAP_BYTES: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackSwapBytes); - break; - case GL_PIXEL_PACK_BUFFER_BINDING: - *params = 0; // TODO - break; - case GL_PIXEL_UNPACK_BUFFER_BINDING: - *params = 0; // TODO - break; - case GL_POINT_FADE_THRESHOLD_SIZE: - *params = 0; // TODO - break; - case GL_PRIMITIVE_RESTART_INDEX: - *params = 0; // TODO - break; - case GL_PROGRAM_BINARY_FORMATS: - *params = 0; // TODO - break; - case GL_PROGRAM_PIPELINE_BINDING: - *params = 0; // TODO - break; - case GL_PROGRAM_POINT_SIZE: - *params = - MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::ProgramPointSize) ? GL_TRUE : GL_FALSE; - break; - case GL_PROVOKING_VERTEX: - *params = 0; // TODO - break; - case GL_POINT_SIZE: - *params = 0; // TODO - break; - case GL_POINT_SIZE_GRANULARITY: - *params = 0; // TODO - break; - case GL_POINT_SIZE_RANGE: - *params = 0; // TODO - break; - case GL_POLYGON_OFFSET_FACTOR: - *params = 0; // TODO - break; - case GL_POLYGON_OFFSET_UNITS: - *params = 0; // TODO - break; - case GL_POLYGON_OFFSET_FILL: - *params = - MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::PolygonOffsetFill) ? GL_TRUE : GL_FALSE; - break; - case GL_POLYGON_OFFSET_LINE: - *params = - MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::PolygonOffsetLine) ? GL_TRUE : GL_FALSE; - break; - case GL_POLYGON_OFFSET_POINT: - *params = - MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::PolygonOffsetPoint) ? GL_TRUE : GL_FALSE; - break; - case GL_POLYGON_SMOOTH: - *params = - MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::PolygonSmooth) ? GL_TRUE : GL_FALSE; - break; - case GL_POLYGON_SMOOTH_HINT: - *params = 0; // TODO - break; - case GL_READ_BUFFER: - *params = 0; // TODO - break; - case GL_RENDERBUFFER_BINDING: - *params = 0; // TODO - break; - case GL_SAMPLE_BUFFERS: - *params = 0; // TODO - break; - case GL_SAMPLE_COVERAGE_VALUE: - *params = 0; // TODO - break; - case GL_SAMPLE_COVERAGE_INVERT: - *params = 0; // TODO - break; - case GL_SAMPLE_MASK_VALUE: - *params = 0; // TODO - break; - case GL_SAMPLER_BINDING: { - Int unit = MG_State::pGLContext->GetActiveTextureUnit(); - const auto& tu = MG_State::pGLContext->GetTextureUnitObject(unit); - const auto& sampler = tu.GetSamplerObject(); - *params = sampler ? static_cast(sampler->GetExternalIndex()) : 0; - break; - } - case GL_SAMPLES: - *params = 0; // TODO - break; - case GL_SCISSOR_BOX: - *params = 0; // TODO - break; - case GL_SCISSOR_TEST: - *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::ScissorTest) ? GL_TRUE : GL_FALSE; - break; - case GL_SHADER_COMPILER: - *params = 0; // TODO - break; - case GL_SHADER_STORAGE_BUFFER_BINDING: - *params = 0; // TODO - break; - case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT: - *params = 0; // TODO - break; - case GL_SHADER_STORAGE_BUFFER_START: - *params = 0; // TODO - break; - case GL_SHADER_STORAGE_BUFFER_SIZE: - *params = 0; // TODO - break; - case GL_SMOOTH_LINE_WIDTH_RANGE: - *params = 0; // TODO - break; - case GL_SMOOTH_LINE_WIDTH_GRANULARITY: - *params = 0; // TODO - break; - case GL_STENCIL_BACK_FAIL: - *params = 0; // TODO - break; - case GL_STENCIL_BACK_FUNC: - *params = 0; // TODO - break; - case GL_STENCIL_BACK_PASS_DEPTH_FAIL: - *params = 0; // TODO - break; - case GL_STENCIL_BACK_PASS_DEPTH_PASS: - *params = 0; // TODO - break; - case GL_STENCIL_BACK_REF: - *params = 0; // TODO - break; - case GL_STENCIL_BACK_VALUE_MASK: - *params = 0; // TODO - break; - case GL_STENCIL_BACK_WRITEMASK: - *params = 0; // TODO - break; - case GL_STENCIL_CLEAR_VALUE: - *params = 0; // TODO - break; - case GL_STENCIL_FAIL: - *params = 0; // TODO - break; - case GL_STENCIL_FUNC: - *params = 0; // TODO - break; - case GL_STENCIL_PASS_DEPTH_FAIL: - *params = 0; // TODO - break; - case GL_STENCIL_PASS_DEPTH_PASS: - *params = 0; // TODO - break; - case GL_STENCIL_REF: - *params = 0; // TODO - break; - case GL_STENCIL_TEST: - *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::StencilTest) ? GL_TRUE : GL_FALSE; - break; - case GL_STENCIL_VALUE_MASK: - *params = 0; // TODO - break; - case GL_STENCIL_WRITEMASK: - *params = 0; // TODO - break; - case GL_STEREO: - *params = 0; // TODO - break; - case GL_SUBPIXEL_BITS: - *params = 0; // TODO - break; - case GL_TEXTURE_BINDING_1D: - *params = 0; // TODO - break; - case GL_TEXTURE_BINDING_1D_ARRAY: - *params = 0; // TODO - break; - case GL_TEXTURE_BINDING_2D: { - Int unit = MG_State::pGLContext->GetActiveTextureUnit(); - auto& tu = MG_State::pGLContext->GetTextureUnitObject(unit); - const auto& slot = tu.GetBindingSlot(TextureTarget::Texture2D); - const auto& obj = slot.GetBoundObject(); - *params = obj ? static_cast(obj->GetExternalIndex()) : 0; - MGLOG_D("Get GL_TEXTURE_BINDING_2D: %d", *params); - break; - } - case GL_TEXTURE_BINDING_2D_ARRAY: - *params = 0; // TODO - break; - case GL_TEXTURE_BINDING_2D_MULTISAMPLE: - *params = 0; // TODO - break; - case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY: - *params = 0; // TODO - break; - case GL_TEXTURE_BINDING_3D: { - Int unit = MG_State::pGLContext->GetActiveTextureUnit(); - auto& tu = MG_State::pGLContext->GetTextureUnitObject(unit); - const auto& slot = tu.GetBindingSlot(TextureTarget::Texture3D); - const auto& obj = slot.GetBoundObject(); - *params = obj ? static_cast(obj->GetExternalIndex()) : 0; - break; - } - case GL_TEXTURE_BINDING_BUFFER: - *params = 0; // TODO - break; - case GL_TEXTURE_BINDING_CUBE_MAP: { - Int unit = MG_State::pGLContext->GetActiveTextureUnit(); - auto& tu = MG_State::pGLContext->GetTextureUnitObject(unit); - const auto& slot = tu.GetBindingSlot(TextureTarget::TextureCubeMap); - const auto& obj = slot.GetBoundObject(); - *params = obj ? static_cast(obj->GetExternalIndex()) : 0; - break; - } - case GL_TEXTURE_BINDING_RECTANGLE: - *params = 0; // TODO - break; - case GL_TEXTURE_COMPRESSION_HINT: - *params = 0; // TODO - break; - case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT: - *params = 0; // TODO - break; - case GL_TIMESTAMP: - *params = 0; // TODO - break; - case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: - *params = 0; // TODO - break; - case GL_TRANSFORM_FEEDBACK_BUFFER_START: - *params = 0; // TODO - break; - case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: - *params = 0; // TODO - break; - case GL_UNIFORM_BUFFER_BINDING: - *params = 0; // TODO - break; - case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - *params = MG_External::GLES::g_glesCaps.uniformBufferOffsetAlignment; -#else - *params = 256; -#endif - break; - case GL_UNIFORM_BUFFER_SIZE: - *params = 0; // TODO - break; - case GL_UNIFORM_BUFFER_START: - *params = 0; // TODO - break; - case GL_UNPACK_ALIGNMENT: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackAlignment); - break; - case GL_UNPACK_IMAGE_HEIGHT: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackImageHeight); - break; - case GL_UNPACK_LSB_FIRST: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackLSBFirst); - break; - case GL_UNPACK_ROW_LENGTH: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackRowLength); - break; - case GL_UNPACK_SKIP_IMAGES: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackSkipImages); - break; - case GL_UNPACK_SKIP_PIXELS: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackSkipPixels); - break; - case GL_UNPACK_SKIP_ROWS: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackSkipRows); - break; - case GL_UNPACK_SWAP_BYTES: - *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackSwapBytes); - break; - case GL_VERTEX_ARRAY_BINDING: { - const auto& vao = MG_State::pGLContext->GetBoundVertexArray(); - *params = vao ? static_cast(vao->GetExternalIndex()) : 0; - break; - } - case GL_VERTEX_BINDING_DIVISOR: - *params = 0; // TODO - break; - case GL_VERTEX_BINDING_OFFSET: - *params = 0; // TODO - break; - case GL_VERTEX_BINDING_STRIDE: - *params = 0; // TODO - break; - case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET: - *params = 0; // TODO - break; - case GL_MAX_VERTEX_ATTRIB_BINDINGS: - *params = 0; // TODO - break; - case GL_VIEWPORT: { - const auto& vp = MG_State::pGLContext->GetViewport(); - params[0] = vp.x(); - params[1] = vp.y(); - params[2] = vp.z(); - params[3] = vp.w(); - break; - } - case GL_VIEWPORT_BOUNDS_RANGE: - *params = 0; // TODO - break; - case GL_VIEWPORT_INDEX_PROVOKING_VERTEX: - *params = 0; // TODO - break; - case GL_VIEWPORT_SUBPIXEL_BITS: - *params = 0; // TODO - break; - case GL_MAX_ELEMENT_INDEX: - *params = 1024 * 1024; // TODO - break; - case GL_CONTEXT_PROFILE_MASK: - *params = GL_CONTEXT_CORE_PROFILE_BIT; - break; - case GL_MAX_COLOR_ATTACHMENTS: - case GL_MAX_DRAW_BUFFERS: - *params = MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; // TODO: use backend value - break; - case GL_MAX_SAMPLES: - *params = 16; // TODO - break; - default: - MGLOG_E("glGetIntegerv: Invalid enum %s (0x%X)", MG_Util::ConvertGLEnumToString(pname).c_str(), pname); - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, MakeShared("MG_Impl/GLImpl", "GetIntegerv", - std::format("Invalid enum: 0x{:X}", pname))); - - break; - } + void GetIntegerv(GLenum pname, GLint* params) { + MGLOG_D("glGetIntegerv, pname: %s", MG_Util::ConvertGLEnumToString(pname).c_str()); + if (!params) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", "GetIntegerv", "params pointer cannot be null")); + return; } - GLenum GetError() { - ErrorCode errorCode = MG_State::pGLContext->PopGLError().value_or(Error{ErrorCode::NoError, nullptr}).code; - return MG_Util::ConvertErrorCodeToGLEnum(errorCode); + const auto& activeBackendObject = MG_Backend::pActiveBackendObject; + if (!activeBackendObject) { + MGLOG_E("activeBackendObject is not initialized!"); + return; } - } // namespace MG_Impl::GLImpl -} // namespace MobileGL \ No newline at end of file + const auto& rendererInfo = activeBackendObject->GetRendererInfo(); + + switch (pname) { + case GL_ACTIVE_TEXTURE: + *params = MG_State::pGLContext->GetActiveTextureUnit() + GL_TEXTURE0; + break; + case GL_ALIASED_LINE_WIDTH_RANGE: + *params = 0; // TODO + break; + case GL_ARRAY_BUFFER_BINDING: { + auto obj = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Vertex).GetBoundObject(); + if (obj) + *params = obj->GetExternalIndex(); + else + *params = 0; + break; + } + case GL_BLEND: + *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::Blend) ? GL_TRUE : GL_FALSE; + break; + case GL_BLEND_COLOR: + *params = 0; // TODO + break; + case GL_BLEND_DST_ALPHA: { + BlendFactor srcRGB, dstRGB, srcAlpha, dstAlpha; + MG_State::pGLContext->GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha); + *params = static_cast(dstAlpha); + break; + } + case GL_BLEND_DST_RGB: { + BlendFactor srcRGB, dstRGB, srcAlpha, dstAlpha; + MG_State::pGLContext->GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha); + *params = static_cast(dstRGB); + break; + } + case GL_BLEND_EQUATION_RGB: + *params = 0; // TODO + break; + case GL_BLEND_EQUATION_ALPHA: + *params = 0; // TODO + break; + case GL_BLEND_SRC_ALPHA: { + BlendFactor srcRGB, dstRGB, srcAlpha, dstAlpha; + MG_State::pGLContext->GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha); + *params = static_cast(srcAlpha); + break; + } + case GL_BLEND_SRC_RGB: { + BlendFactor srcRGB, dstRGB, srcAlpha, dstAlpha; + MG_State::pGLContext->GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha); + *params = static_cast(srcRGB); + break; + } + case GL_COLOR_CLEAR_VALUE: + *params = 0; // TODO + break; + case GL_COLOR_LOGIC_OP: + *params = 0; // TODO + break; + case GL_COLOR_WRITEMASK: { + BoolVec4 mask = MG_State::pGLContext->GetColorMask(); + params[0] = mask.x() ? GL_TRUE : GL_FALSE; + params[1] = mask.y() ? GL_TRUE : GL_FALSE; + params[2] = mask.z() ? GL_TRUE : GL_FALSE; + params[3] = mask.w() ? GL_TRUE : GL_FALSE; + break; + } + case GL_COMPRESSED_TEXTURE_FORMATS: + *params = 0; // TODO + break; + case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: + *params = 0; // TODO + break; + case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: + *params = 0; // TODO + break; + case GL_MAX_COMPUTE_UNIFORM_BLOCKS: + *params = 0; // TODO + break; + case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS: + *params = 0; // TODO + break; + case GL_MAX_COMPUTE_UNIFORM_COMPONENTS: + *params = 0; // TODO + break; + case GL_MAX_COMPUTE_ATOMIC_COUNTERS: + *params = 0; // TODO + break; + case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS: + *params = 0; // TODO + break; + case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS: + *params = 0; // TODO + break; + case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: + *params = 0; // TODO + break; + case GL_MAX_COMPUTE_WORK_GROUP_COUNT: + *params = 0; // TODO + break; + case GL_MAX_COMPUTE_WORK_GROUP_SIZE: + *params = 0; // TODO + break; + case GL_DISPATCH_INDIRECT_BUFFER_BINDING: + *params = 0; // TODO + break; + case GL_MAX_DEBUG_GROUP_STACK_DEPTH: + *params = 0; // TODO + break; + case GL_DEBUG_GROUP_STACK_DEPTH: + *params = 0; // TODO + break; + case GL_CONTEXT_FLAGS: + *params = 0; // TODO + break; + case GL_CULL_FACE: + *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::CullFace) ? GL_TRUE : GL_FALSE; + break; + case GL_CURRENT_PROGRAM: { + const auto& currentProgram = MG_State::pGLContext->GetCurrentProgram(); + *params = currentProgram ? currentProgram->GetExternalIndex() : 0; + break; + } + case GL_DEPTH_CLEAR_VALUE: + *params = MG_State::pGLContext->GetClearDepth(); + break; + case GL_DEPTH_FUNC: + *params = MG_Util::ConvertDepthTestFuncToGLEnum(MG_State::pGLContext->GetDepthFunc()); + break; + case GL_DEPTH_RANGE: + *params = 0; // TODO + break; + case GL_DEPTH_TEST: + *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::DepthTest) ? GL_TRUE : GL_FALSE; + break; + case GL_DEPTH_WRITEMASK: + *params = MG_State::pGLContext->GetDepthMask() ? GL_TRUE : GL_FALSE; + break; + case GL_DITHER: + *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::Dither) ? GL_TRUE : GL_FALSE; + break; + case GL_DOUBLEBUFFER: + *params = 0; // TODO + break; + case GL_DRAW_BUFFER: + *params = 0; // TODO + break; + case GL_DRAW_BUFFER0: + *params = 0; // TODO + break; + case GL_DRAW_FRAMEBUFFER_BINDING: { + const auto& FBO = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + *params = FBO ? FBO->GetExternalIndex() : 0; + break; + } + case GL_READ_FRAMEBUFFER_BINDING: { + const auto& FBO = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); + *params = FBO ? FBO->GetExternalIndex() : 0; + break; + } + case GL_ELEMENT_ARRAY_BUFFER_BINDING: { + if (!MG_State::pGLContext->GetBoundVertexArray()) { + *params = 0; + break; + } + const auto& bufferObject = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Index).GetBoundObject(); + *params = bufferObject ? bufferObject->GetExternalIndex() : 0; + break; + } + case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: + *params = 0; // TODO + break; + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + *params = 0; // TODO + break; + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + *params = 0; // TODO + break; + case GL_LINE_SMOOTH: + *params = 0; // TODO + break; + case GL_LINE_SMOOTH_HINT: + *params = 0; // TODO + break; + case GL_LINE_WIDTH: + *params = 0; // TODO + break; + case GL_LAYER_PROVOKING_VERTEX: + *params = 0; // TODO + break; + case GL_LOGIC_OP_MODE: + *params = 0; // TODO + break; + case GL_MAJOR_VERSION: + *params = rendererInfo.RendererGLInfo.TargetGLVersion.Major; + break; + case GL_MAX_3D_TEXTURE_SIZE: + *params = 1024 * 16; // TODO + break; + case GL_MAX_ARRAY_TEXTURE_LAYERS: + *params = 2048; // TODO + break; + case GL_MAX_CLIP_DISTANCES: + *params = 8; // TODO + break; + case GL_MAX_COLOR_TEXTURE_SAMPLES: + *params = 16; // TODO + break; + case GL_MAX_COMBINED_ATOMIC_COUNTERS: + *params = 16; // TODO + break; + case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: + *params = 1024 * 228; // TODO + break; + case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS: + *params = 1024 * 228; // TODO + break; + case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + *params = 192; // TODO + break; + case GL_MAX_COMBINED_UNIFORM_BLOCKS: + *params = 70; // TODO + break; + case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: + *params = 1024 * 228; // TODO + break; + case GL_MAX_CUBE_MAP_TEXTURE_SIZE: + *params = 1024 * 16; // TODO + break; + case GL_MAX_DEPTH_TEXTURE_SAMPLES: + *params = 16; // TODO + break; + case GL_MAX_DUAL_SOURCE_DRAW_BUFFERS: + *params = 1; // TODO + break; + case GL_MAX_ELEMENTS_INDICES: + *params = 1024 * 1024; // TODO + break; + case GL_MAX_ELEMENTS_VERTICES: + *params = 1024 * 1024; // TODO + break; + case GL_MAX_FRAGMENT_ATOMIC_COUNTERS: + *params = 1024 * 4; // TODO + break; + case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: + *params = 16; // TODO + break; + case GL_MAX_FRAGMENT_INPUT_COMPONENTS: + *params = 128; // TODO + break; + case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: + *params = 1024 * 4; // TODO + break; + case GL_MAX_FRAGMENT_UNIFORM_VECTORS: + *params = 256; // TODO + break; + case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: + *params = 14; // TODO + break; + case GL_MAX_FRAMEBUFFER_WIDTH: + *params = 1024 * 16; // TODO + break; + case GL_MAX_FRAMEBUFFER_HEIGHT: + *params = 1024 * 16; // TODO + break; + case GL_MAX_FRAMEBUFFER_LAYERS: + *params = 1024 * 2; // TODO + break; + case GL_MAX_FRAMEBUFFER_SAMPLES: + *params = 16; // TODO + break; + case GL_MAX_GEOMETRY_ATOMIC_COUNTERS: + *params = 14; // TODO + break; + case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS: + *params = 16; // TODO + break; + case GL_MAX_GEOMETRY_INPUT_COMPONENTS: + *params = 128; // TODO + break; + case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS: + *params = 128; // TODO + break; + case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: + *params = 8; // TODO + break; + case GL_MAX_GEOMETRY_UNIFORM_BLOCKS: + *params = 14; // TODO + break; + case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS: + *params = 1024 * 4; // TODO + break; + case GL_MAX_INTEGER_SAMPLES: + *params = 16; // TODO + break; + case GL_MIN_MAP_BUFFER_ALIGNMENT: + *params = 64; // TODO + break; + case GL_MAX_LABEL_LENGTH: + *params = 256; // TODO + break; + case GL_MAX_PROGRAM_TEXEL_OFFSET: + *params = 7; // TODO + break; + case GL_MIN_PROGRAM_TEXEL_OFFSET: + *params = -8; // TODO + break; + case GL_MAX_RECTANGLE_TEXTURE_SIZE: + *params = 16 * 1024; // TODO + break; + case GL_MAX_RENDERBUFFER_SIZE: + *params = 16 * 1024; // TODO + break; + case GL_MAX_SAMPLE_MASK_WORDS: + *params = 1; // TODO + break; + case GL_MAX_SERVER_WAIT_TIMEOUT: + *params = INT_MAX; // TODO + break; + case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: + *params = 16; // TODO + break; + case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS: + *params = 1024 * 4; // TODO + break; + case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS: + *params = 1024 * 4; // TODO + break; + case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS: + *params = 16; // TODO + break; + case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS: + *params = 16; // TODO + break; + case GL_MAX_TEXTURE_BUFFER_SIZE: + *params = 1024 * 1024 * 128; // TODO + break; + case GL_MAX_TEXTURE_IMAGE_UNITS: + *params = 32; // TODO + break; + case GL_MAX_TEXTURE_LOD_BIAS: + *params = 15; // TODO + break; + case GL_MAX_TEXTURE_SIZE: + *params = 1024 * 16; // TODO + break; + case GL_MAX_UNIFORM_BUFFER_BINDINGS: + *params = 84; // TODO + break; + case GL_MAX_UNIFORM_BLOCK_SIZE: + *params = 1024 * 24; // TODO + break; + case GL_MAX_UNIFORM_LOCATIONS: + *params = 1024 * 4; // TODO + break; + case GL_MAX_VARYING_COMPONENTS: + *params = 16; // TODO + break; + case GL_MAX_VARYING_VECTORS: + *params = 16; // TODO + break; + case GL_MAX_VERTEX_ATOMIC_COUNTERS: + *params = 1024 * 4; // TODO + break; + case GL_MAX_VERTEX_ATTRIBS: + *params = 16; // TODO + break; + case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: + *params = 16; // TODO + break; + case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: + *params = 32; // TODO + break; + case GL_MAX_VERTEX_UNIFORM_COMPONENTS: + *params = 1024 * 4; // TODO + break; + case GL_MAX_VERTEX_UNIFORM_VECTORS: + *params = 1024; // TODO + break; + case GL_MAX_VERTEX_OUTPUT_COMPONENTS: + *params = 128; // TODO + break; + case GL_MAX_VERTEX_UNIFORM_BLOCKS: + *params = 14; // TODO + break; + case GL_MAX_VIEWPORT_DIMS: + params[0] = 1024 * 16; // TODO + params[1] = 1024 * 16; // TODO + break; + case GL_MAX_VIEWPORTS: + *params = 16; // TODO + break; + case GL_MINOR_VERSION: + *params = rendererInfo.RendererGLInfo.TargetGLVersion.Minor; + break; + case GL_NUM_COMPRESSED_TEXTURE_FORMATS: + *params = 18; // TODO + break; + case GL_NUM_EXTENSIONS: + *params = (Int)rendererInfo.RendererGLInfo.Extensions.size(); + break; + case GL_NUM_PROGRAM_BINARY_FORMATS: + *params = 2; // TODO + break; + case GL_NUM_SHADER_BINARY_FORMATS: + *params = 0; // TODO + break; + case GL_PACK_ALIGNMENT: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackAlignment); + break; + case GL_PACK_IMAGE_HEIGHT: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackImageHeight); + break; + case GL_PACK_LSB_FIRST: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackLSBFirst); + break; + case GL_PACK_ROW_LENGTH: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackRowLength); + break; + case GL_PACK_SKIP_IMAGES: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackSkipImages); + break; + case GL_PACK_SKIP_PIXELS: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackSkipPixels); + break; + case GL_PACK_SKIP_ROWS: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackSkipRows); + break; + case GL_PACK_SWAP_BYTES: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::PackSwapBytes); + break; + case GL_PIXEL_PACK_BUFFER_BINDING: + *params = 0; // TODO + break; + case GL_PIXEL_UNPACK_BUFFER_BINDING: + *params = 0; // TODO + break; + case GL_POINT_FADE_THRESHOLD_SIZE: + *params = 0; // TODO + break; + case GL_PRIMITIVE_RESTART_INDEX: + *params = 0; // TODO + break; + case GL_PROGRAM_BINARY_FORMATS: + *params = 0; // TODO + break; + case GL_PROGRAM_PIPELINE_BINDING: + *params = 0; // TODO + break; + case GL_PROGRAM_POINT_SIZE: + *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::ProgramPointSize) ? GL_TRUE : GL_FALSE; + break; + case GL_PROVOKING_VERTEX: + *params = 0; // TODO + break; + case GL_POINT_SIZE: + *params = 0; // TODO + break; + case GL_POINT_SIZE_GRANULARITY: + *params = 0; // TODO + break; + case GL_POINT_SIZE_RANGE: + *params = 0; // TODO + break; + case GL_POLYGON_OFFSET_FACTOR: + *params = 0; // TODO + break; + case GL_POLYGON_OFFSET_UNITS: + *params = 0; // TODO + break; + case GL_POLYGON_OFFSET_FILL: + *params = + MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::PolygonOffsetFill) ? GL_TRUE : GL_FALSE; + break; + case GL_POLYGON_OFFSET_LINE: + *params = + MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::PolygonOffsetLine) ? GL_TRUE : GL_FALSE; + break; + case GL_POLYGON_OFFSET_POINT: + *params = + MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::PolygonOffsetPoint) ? GL_TRUE : GL_FALSE; + break; + case GL_POLYGON_SMOOTH: + *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::PolygonSmooth) ? GL_TRUE : GL_FALSE; + break; + case GL_POLYGON_SMOOTH_HINT: + *params = 0; // TODO + break; + case GL_READ_BUFFER: + *params = 0; // TODO + break; + case GL_RENDERBUFFER_BINDING: + *params = 0; // TODO + break; + case GL_SAMPLE_BUFFERS: + *params = 0; // TODO + break; + case GL_SAMPLE_COVERAGE_VALUE: + *params = 0; // TODO + break; + case GL_SAMPLE_COVERAGE_INVERT: + *params = 0; // TODO + break; + case GL_SAMPLE_MASK_VALUE: + *params = 0; // TODO + break; + case GL_SAMPLER_BINDING: { + Int unit = MG_State::pGLContext->GetActiveTextureUnit(); + const auto& tu = MG_State::pGLContext->GetTextureUnitObject(unit); + const auto& sampler = tu.GetSamplerObject(); + *params = sampler ? static_cast(sampler->GetExternalIndex()) : 0; + break; + } + case GL_SAMPLES: + *params = 0; // TODO + break; + case GL_SCISSOR_BOX: + *params = 0; // TODO + break; + case GL_SCISSOR_TEST: + *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::ScissorTest) ? GL_TRUE : GL_FALSE; + break; + case GL_SHADER_COMPILER: + *params = 0; // TODO + break; + case GL_SHADER_STORAGE_BUFFER_BINDING: + *params = 0; // TODO + break; + case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT: + *params = 0; // TODO + break; + case GL_SHADER_STORAGE_BUFFER_START: + *params = 0; // TODO + break; + case GL_SHADER_STORAGE_BUFFER_SIZE: + *params = 0; // TODO + break; + case GL_SMOOTH_LINE_WIDTH_RANGE: + *params = 0; // TODO + break; + case GL_SMOOTH_LINE_WIDTH_GRANULARITY: + *params = 0; // TODO + break; + case GL_STENCIL_BACK_FAIL: + *params = 0; // TODO + break; + case GL_STENCIL_BACK_FUNC: + *params = 0; // TODO + break; + case GL_STENCIL_BACK_PASS_DEPTH_FAIL: + *params = 0; // TODO + break; + case GL_STENCIL_BACK_PASS_DEPTH_PASS: + *params = 0; // TODO + break; + case GL_STENCIL_BACK_REF: + *params = 0; // TODO + break; + case GL_STENCIL_BACK_VALUE_MASK: + *params = 0; // TODO + break; + case GL_STENCIL_BACK_WRITEMASK: + *params = 0; // TODO + break; + case GL_STENCIL_CLEAR_VALUE: + *params = 0; // TODO + break; + case GL_STENCIL_FAIL: + *params = 0; // TODO + break; + case GL_STENCIL_FUNC: + *params = 0; // TODO + break; + case GL_STENCIL_PASS_DEPTH_FAIL: + *params = 0; // TODO + break; + case GL_STENCIL_PASS_DEPTH_PASS: + *params = 0; // TODO + break; + case GL_STENCIL_REF: + *params = 0; // TODO + break; + case GL_STENCIL_TEST: + *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::StencilTest) ? GL_TRUE : GL_FALSE; + break; + case GL_STENCIL_VALUE_MASK: + *params = 0; // TODO + break; + case GL_STENCIL_WRITEMASK: + *params = 0; // TODO + break; + case GL_STEREO: + *params = 0; // TODO + break; + case GL_SUBPIXEL_BITS: + *params = 0; // TODO + break; + case GL_TEXTURE_BINDING_1D: + *params = 0; // TODO + break; + case GL_TEXTURE_BINDING_1D_ARRAY: + *params = 0; // TODO + break; + case GL_TEXTURE_BINDING_2D: { + Int unit = MG_State::pGLContext->GetActiveTextureUnit(); + auto& tu = MG_State::pGLContext->GetTextureUnitObject(unit); + const auto& slot = tu.GetBindingSlot(TextureTarget::Texture2D); + const auto& obj = slot.GetBoundObject(); + *params = obj ? static_cast(obj->GetExternalIndex()) : 0; + MGLOG_D("Get GL_TEXTURE_BINDING_2D: %d", *params); + break; + } + case GL_TEXTURE_BINDING_2D_ARRAY: + *params = 0; // TODO + break; + case GL_TEXTURE_BINDING_2D_MULTISAMPLE: + *params = 0; // TODO + break; + case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY: + *params = 0; // TODO + break; + case GL_TEXTURE_BINDING_3D: { + Int unit = MG_State::pGLContext->GetActiveTextureUnit(); + auto& tu = MG_State::pGLContext->GetTextureUnitObject(unit); + const auto& slot = tu.GetBindingSlot(TextureTarget::Texture3D); + const auto& obj = slot.GetBoundObject(); + *params = obj ? static_cast(obj->GetExternalIndex()) : 0; + break; + } + case GL_TEXTURE_BINDING_BUFFER: + *params = 0; // TODO + break; + case GL_TEXTURE_BINDING_CUBE_MAP: { + Int unit = MG_State::pGLContext->GetActiveTextureUnit(); + auto& tu = MG_State::pGLContext->GetTextureUnitObject(unit); + const auto& slot = tu.GetBindingSlot(TextureTarget::TextureCubeMap); + const auto& obj = slot.GetBoundObject(); + *params = obj ? static_cast(obj->GetExternalIndex()) : 0; + break; + } + case GL_TEXTURE_BINDING_RECTANGLE: + *params = 0; // TODO + break; + case GL_TEXTURE_COMPRESSION_HINT: + *params = 0; // TODO + break; + case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT: + *params = 0; // TODO + break; + case GL_TIMESTAMP: + *params = 0; // TODO + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + *params = 0; // TODO + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + *params = 0; // TODO + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + *params = 0; // TODO + break; + case GL_UNIFORM_BUFFER_BINDING: + *params = 0; // TODO + break; + case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: + *params = (Int)activeBackendObject->GetDynamicParameters().UniformBufferOffsetAlignment; + break; + case GL_UNIFORM_BUFFER_SIZE: + *params = 0; // TODO + break; + case GL_UNIFORM_BUFFER_START: + *params = 0; // TODO + break; + case GL_UNPACK_ALIGNMENT: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackAlignment); + break; + case GL_UNPACK_IMAGE_HEIGHT: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackImageHeight); + break; + case GL_UNPACK_LSB_FIRST: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackLSBFirst); + break; + case GL_UNPACK_ROW_LENGTH: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackRowLength); + break; + case GL_UNPACK_SKIP_IMAGES: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackSkipImages); + break; + case GL_UNPACK_SKIP_PIXELS: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackSkipPixels); + break; + case GL_UNPACK_SKIP_ROWS: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackSkipRows); + break; + case GL_UNPACK_SWAP_BYTES: + *params = MG_State::pGLContext->GetPixelStoreParam(PixelStoreParam::UnpackSwapBytes); + break; + case GL_VERTEX_ARRAY_BINDING: { + const auto& vao = MG_State::pGLContext->GetBoundVertexArray(); + *params = vao ? static_cast(vao->GetExternalIndex()) : 0; + break; + } + case GL_VERTEX_BINDING_DIVISOR: + *params = 0; // TODO + break; + case GL_VERTEX_BINDING_OFFSET: + *params = 0; // TODO + break; + case GL_VERTEX_BINDING_STRIDE: + *params = 0; // TODO + break; + case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET: + *params = 0; // TODO + break; + case GL_MAX_VERTEX_ATTRIB_BINDINGS: + *params = 0; // TODO + break; + case GL_VIEWPORT: { + const auto& vp = MG_State::pGLContext->GetViewport(); + params[0] = vp.x(); + params[1] = vp.y(); + params[2] = vp.z(); + params[3] = vp.w(); + break; + } + case GL_VIEWPORT_BOUNDS_RANGE: + *params = 0; // TODO + break; + case GL_VIEWPORT_INDEX_PROVOKING_VERTEX: + *params = 0; // TODO + break; + case GL_VIEWPORT_SUBPIXEL_BITS: + *params = 0; // TODO + break; + case GL_MAX_ELEMENT_INDEX: + *params = 1024 * 1024; // TODO + break; + case GL_CONTEXT_PROFILE_MASK: + *params = GL_CONTEXT_CORE_PROFILE_BIT; + break; + case GL_MAX_COLOR_ATTACHMENTS: + case GL_MAX_DRAW_BUFFERS: + *params = MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; // TODO: use backend value + break; + case GL_MAX_SAMPLES: + *params = 16; // TODO + break; + default: + MGLOG_E("glGetIntegerv: Invalid enum %s (0x%X)", MG_Util::ConvertGLEnumToString(pname).c_str(), pname); + MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", "GetIntegerv", + std::format("Invalid enum: 0x{:X}", pname))); + + break; + } + } + + GLenum GetError() { + ErrorCode errorCode = MG_State::pGLContext->PopGLError().value_or(Error{ErrorCode::NoError, nullptr}).code; + return MG_Util::ConvertErrorCodeToGLEnum(errorCode); + } +} // namespace MobileGL::MG_Impl::GLImpl diff --git a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.h b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.h index 56d33944..d7fba7e4 100644 --- a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.h +++ b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.h @@ -9,12 +9,10 @@ #pragma once #include -namespace MobileGL { - namespace MG_Impl::GLImpl { - /* @INSERTION_POINT:FUNCTION_DECLARATION@ */ - const GLubyte* GetString(GLenum name); - const GLubyte* GetStringi(GLenum name, GLuint index); - void GetIntegerv(GLenum pname, GLint* params); - GLenum GetError(); - } // namespace MG_Impl::GLImpl -} // namespace MobileGL \ No newline at end of file +namespace MobileGL::MG_Impl::GLImpl { + /* @INSERTION_POINT:FUNCTION_DECLARATION@ */ + const GLubyte* GetString(GLenum name); + const GLubyte* GetStringi(GLenum name, GLuint index); + void GetIntegerv(GLenum pname, GLint* params); + GLenum GetError(); +} // namespace MobileGL::MG_Impl::GLImpl diff --git a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp index e538ab9e..b938a348 100644 --- a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp +++ b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp @@ -477,7 +477,19 @@ namespace MobileGL { auto programObject = TryToGetProgramObject(program); if (!programObject) return; MGLOG_D("%s: linking program %d", __func__, program); - programObject->Link(!MG_Config::RendererInfoPtr->BackendCapability.AllowVSOnlyPrograms); + + static Bool allowVSOnlyPrograms; + static Bool initialized = false; + if (!initialized) { + const auto& activeBackendObject = MG_Backend::pActiveBackendObject; + if (!activeBackendObject) { + MGLOG_E("activeBackendObject is not initialized!"); + return; + } + const auto& rendererInfo = activeBackendObject->GetRendererInfo(); + allowVSOnlyPrograms = (Int)rendererInfo.StaticBackendCapability.AllowVSOnlyPrograms; + } + programObject->Link(!allowVSOnlyPrograms); } void ShaderSource_State(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) { @@ -1160,4 +1172,4 @@ namespace MobileGL { ValidateProgram_State(program); } } // namespace MG_Impl::GLImpl -} // namespace MobileGL \ No newline at end of file +} // namespace MobileGL diff --git a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp index da14735f..fa57f434 100644 --- a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp +++ b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp @@ -13,6 +13,7 @@ #include "ProxyTexture.h" #include +#include #include #include #include @@ -25,159 +26,323 @@ #include #include -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES -#include -#endif +namespace MobileGL::MG_Impl::GLImpl { + SharedPtr GetTextureObjectByTarget(TextureUploadTarget textureUploadingTarget, + TextureTarget textureTarget) { + SharedPtr textureObject = nullptr; + if (TextureImpl::IsProxyTextureTarget(textureUploadingTarget)) { + textureObject = + TextureImpl::pProxyTextureManager->CreateOrReplaceProxyTextureObject(textureUploadingTarget); + } else { + auto activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); + auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); + textureObject = bindingSlot.GetBoundObject(); + } -namespace MobileGL { - namespace MG_Impl::GLImpl { - SharedPtr GetTextureObjectByTarget( - TextureUploadTarget textureUploadingTarget, TextureTarget textureTarget) { - SharedPtr textureObject = nullptr; - if (TextureImpl::IsProxyTextureTarget(textureUploadingTarget)) { - textureObject = - TextureImpl::pProxyTextureManager->CreateOrReplaceProxyTextureObject(textureUploadingTarget); - } else { - auto activeUnit = - MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); - auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); - textureObject = bindingSlot.GetBoundObject(); + if (!TextureImpl::ValidateTextureObject(textureObject)) return nullptr; + + return textureObject; + } + + void GenerateMipmap_Backend(GLenum target) { + MG_Backend::gBackendFunctionsTable.GL.GenerateMipmap(target); + } + + void TexSubImage3D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) { + // TODO: implement + } + + void TexSubImage2D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLenum type, const void* pixels) { + // ======================= Converting ================================ + TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format); + TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type); + // TextureInternalFormat textureInternalFormat = + // MG_Util::ConvertGLEnumToTextureInternalFormat(format); + MGLOG_D("TexSubImage2D_State: target = %s, level = %d, (%d, %d), format = %s, pixels = %p", + MG_Util::ConvertGLEnumToString(target).c_str(), level, width, height, + MG_Util::ConvertTextureInputFormatToString(textureInputFormat).c_str(), pixels); + // ===================== Error Checking ============================== + if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) return; + if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) return; + if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return; + if (!TextureImpl::ValidateTextureLevelNumber(level)) return; + if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return; + if (!TextureImpl::ValidateTextureSizeRange(width, height, 1)) return; + if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return; + + // TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the + // GL_PIXEL_UNPACK_BUFFER target and the buffer object's data store is currently mapped. + // GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the + // GL_PIXEL_UNPACK_BUFFER target and the data would be unpacked from the buffer object such that the + // memory reads required would exceed the data store size. GL_INVALID_OPERATION is generated if a + // non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER target and data is not evenly + // divisible into the number of bytes needed to store in memory a datum indicated by type. + + // ======================= Processing ================================ + auto activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); + auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); + auto textureObject = bindingSlot.GetBoundObject(); + TextureInternalFormat textureInternalFormat = textureObject->GetFormat(); + MGLOG_D("%s: working on texture %d", __func__, textureObject->GetExternalIndex()); + + // ===================== Error Checking ============================== + if (!TextureImpl::ValidateTextureObject(textureObject)) return; + if (!TextureImpl::ValidateTextureSubImageOffsets(textureObject, xoffset, width, yoffset, height)) return; + if (!TextureImpl::ValidateTextureInternalFormatCompatibleWithInput(textureInputFormat, textureInternalFormat, + texturePixelDataType)) + return; + + // ======================= Processing ================================ + // Texture object here should always be an object with mipmap + // Assert this for extra safety. + // This should automatically compiled out in release, + // so that we don't take the perf hit of dyn-cast. + MOBILEGL_ASSERT(nullptr != dynamic_cast(textureObject.get()), + "Texture object here should always be an object with mipmap"); + auto textureMipmapObject = static_cast(textureObject.get()); + auto texelSize = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level); + + SizeT inputSize = 0; + + const void* originalPixels = pixels; + + // PBO + const auto& pixelUnpackBufferObject = + MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject(); + if (pixelUnpackBufferObject) { + MGLOG_D("TexSubImage2D_State: Using Pixel Unpack Buffer Object ID: %u", + pixelUnpackBufferObject->GetExternalIndex()); + originalPixels = reinterpret_cast(pixelUnpackBufferObject->GetDataReadOnly()->data()) + + reinterpret_cast(pixels); + } + + if (!originalPixels) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", __func__, + "No data supplied from pixels parameter and no PBO bound.")); + return; + } + const auto& unpackParams = MG_State::pGLContext->GetPixelStoreParameters(true); + void* processedPixels = MG_Util::PixelStoreProcessor::ProcessTexturePixelsDataUnpack( + originalPixels, unpackParams, textureInternalFormat, textureInputFormat, texturePixelDataType, + {width, height, 1}, false, inputSize); + + if (!processedPixels || inputSize == 0) { + MGLOG_E("TexSubImage2D_State: Failed to process pixel data for TexSubImage2D, width: %d, height: %d", width, + height); + if (processedPixels) free(processedPixels); + return; + } + + const SizeT internalBpp = MG_Util::GetInternalBytesPerPixel(textureInternalFormat, texturePixelDataType); + + const SizeT srcRowSize = static_cast(width) * internalBpp; + const SizeT srcStride = (srcRowSize + unpackParams.Alignment - 1) & ~(unpackParams.Alignment - 1); + const SizeT destRowSize = static_cast(texelSize.x()) * internalBpp; + + if (xoffset + width > static_cast(texelSize.x()) || + yoffset + height > static_cast(texelSize.y())) { + MGLOG_E("TexSubImage2D_State: Specified region exceeds texture dimensions"); + free(processedPixels); + return; + } + + const auto* srcData = static_cast(processedPixels); + Uint8* destData = static_cast(textureMipmapObject->MapMipmapData(textureUploadingTarget, level)); + + if (destData) { + for (GLsizei y = 0; y < height; y++) { + const SizeT destRowOffset = (yoffset + y) * destRowSize + xoffset * internalBpp; + const SizeT srcRowOffset = y * srcStride; + Memcpy(destData + destRowOffset, srcData + srcRowOffset, srcRowSize); } - - if (!TextureImpl::ValidateTextureObject(textureObject)) return nullptr; - - return textureObject; } - void TexSubImage3D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) { - // TODO: implement - } + free(processedPixels); - void TexSubImage2D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, - GLsizei height, GLenum format, GLenum type, const void* pixels) { + MGLOG_D("%s: mark mip %d as dirty", __func__, level); + textureMipmapObject->MarkStorageDirty(textureUploadingTarget, level, true); + } + + void TexSubImage1D_State(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, + const GLvoid* pixels) { + // TODO: implement + } + + // TexParameteriv/TexParameterfv are introduced in OpenGL 4.0, so do not support them for now. + void TexParameterf_State(GLenum target, GLenum pname, GLfloat param) { + + // ======================= Converting ================================ + TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + + // ======================= Processing ================================ + SharedPtr textureObject = + GetTextureObjectByTarget(textureUploadingTarget, textureTarget); + if (!textureObject) return; + + switch (pname) { + case GL_TEXTURE_MAG_FILTER: + textureObject->GetSamplerObject()->SetMagFilter(MG_Util::ConvertGLEnumToSamplerFilterMode(param)); + break; + case GL_TEXTURE_MIN_FILTER: + textureObject->GetSamplerObject()->SetMinFilter(MG_Util::ConvertGLEnumToSamplerFilterMode(param)); + textureObject->GetSamplerObject()->SetMipmapMode(MG_Util::ConvertGLEnumToSamplerMipmapMode(param)); + break; + case GL_TEXTURE_MIN_LOD: { + Float maxLod = textureObject->GetSamplerObject()->GetMaxLod(); + textureObject->GetSamplerObject()->SetLodRange(param, maxLod); + break; + } + case GL_TEXTURE_MAX_LOD: { + Float minLod = textureObject->GetSamplerObject()->GetMinLod(); + textureObject->GetSamplerObject()->SetLodRange(minLod, param); + break; + } + case GL_TEXTURE_BASE_LEVEL: + textureObject->SetBaseLevel(param); + break; + case GL_TEXTURE_MAX_LEVEL: + textureObject->SetMaxLevel(param); + break; + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: { + auto swizzleParam = MG_Util::ConvertGLEnumPnameToTextureSwizzleParam(pname); + auto swizzleValue = MG_Util::ConvertGLEnumToTextureSwizzleParam(param); + textureObject->SetSwizzleParam(swizzleParam, swizzleValue); + break; + } + case GL_TEXTURE_WRAP_S: + textureObject->GetSamplerObject()->SetWrapS(MG_Util::ConvertGLEnumToSamplerWrapMode(param)); + break; + case GL_TEXTURE_WRAP_T: + textureObject->GetSamplerObject()->SetWrapT(MG_Util::ConvertGLEnumToSamplerWrapMode(param)); + break; + case GL_TEXTURE_WRAP_R: + textureObject->GetSamplerObject()->SetWrapR(MG_Util::ConvertGLEnumToSamplerWrapMode(param)); + break; + case GL_TEXTURE_COMPARE_MODE: + textureObject->GetSamplerObject()->SetCompareMode(MG_Util::ConvertGLEnumToSamplerCompareMode(param)); + break; + case GL_TEXTURE_COMPARE_FUNC: + textureObject->GetSamplerObject()->SetSamplerCompareFunc(MG_Util::ConvertGLEnumToSamplerCompareFunc(param)); + break; + case GL_TEXTURE_LOD_BIAS: + textureObject->GetSamplerObject()->SetLodBias(param); + break; + case GL_TEXTURE_SWIZZLE_RGBA: + // Not supported in this function + case GL_TEXTURE_BORDER_COLOR: + // Not supported in this function + default: + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared( + "MG_Impl/GLImpl", __func__, + std::format("pname {} is not a valid texture parameter.", MG_Util::ConvertGLEnumToString(pname)))); + return; + } + } + + void TexParameteri_State(GLenum target, GLenum pname, GLint param) { + // ======================= Converting ================================ + TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + + // ======================= Processing ================================ + SharedPtr textureObject = + GetTextureObjectByTarget(textureUploadingTarget, textureTarget); + if (!textureObject) return; + + switch (pname) { + case GL_TEXTURE_MAG_FILTER: + textureObject->GetSamplerObject()->SetMagFilter(MG_Util::ConvertGLEnumToSamplerFilterMode(param)); + break; + case GL_TEXTURE_MIN_FILTER: + textureObject->GetSamplerObject()->SetMinFilter(MG_Util::ConvertGLEnumToSamplerFilterMode(param)); + textureObject->GetSamplerObject()->SetMipmapMode(MG_Util::ConvertGLEnumToSamplerMipmapMode(param)); + break; + case GL_TEXTURE_MIN_LOD: { + Float maxLod = textureObject->GetSamplerObject()->GetMaxLod(); + textureObject->GetSamplerObject()->SetLodRange(param, maxLod); + break; + } + case GL_TEXTURE_MAX_LOD: { + Float minLod = textureObject->GetSamplerObject()->GetMinLod(); + textureObject->GetSamplerObject()->SetLodRange(minLod, param); + break; + } + case GL_TEXTURE_BASE_LEVEL: + textureObject->SetBaseLevel(param); + break; + case GL_TEXTURE_MAX_LEVEL: + textureObject->SetMaxLevel(param); + break; + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: { + auto swizzleParam = MG_Util::ConvertGLEnumPnameToTextureSwizzleParam(pname); + auto swizzleValue = MG_Util::ConvertGLEnumToTextureSwizzleParam(param); + textureObject->SetSwizzleParam(swizzleParam, swizzleValue); + break; + } + case GL_TEXTURE_WRAP_S: + textureObject->GetSamplerObject()->SetWrapS(MG_Util::ConvertGLEnumToSamplerWrapMode(param)); + break; + case GL_TEXTURE_WRAP_T: + textureObject->GetSamplerObject()->SetWrapT(MG_Util::ConvertGLEnumToSamplerWrapMode(param)); + break; + case GL_TEXTURE_WRAP_R: + textureObject->GetSamplerObject()->SetWrapR(MG_Util::ConvertGLEnumToSamplerWrapMode(param)); + break; + case GL_TEXTURE_COMPARE_MODE: + textureObject->GetSamplerObject()->SetCompareMode(MG_Util::ConvertGLEnumToSamplerCompareMode(param)); + break; + case GL_TEXTURE_COMPARE_FUNC: + textureObject->GetSamplerObject()->SetSamplerCompareFunc(MG_Util::ConvertGLEnumToSamplerCompareFunc(param)); + break; + case GL_TEXTURE_LOD_BIAS: + textureObject->GetSamplerObject()->SetLodBias((GLfloat)param); + break; + case GL_TEXTURE_SWIZZLE_RGBA: + // Not supported in this function + case GL_TEXTURE_BORDER_COLOR: + // Not supported in this function + default: + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared( + "MG_Impl/GLImpl", __func__, + std::format("pname {} is not a valid texture parameter.", MG_Util::ConvertGLEnumToString(pname)))); + return; + } + } + + // Quick and dirty TexParameter*v implementation to make NeoForge happy. + // TODO: implement the missing part + void TexParameterfv_State(GLenum target, GLenum pname, const GLfloat* params) { + switch (pname) { + case GL_TEXTURE_BORDER_COLOR: { // ======================= Converting ================================ TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); - TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format); - TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type); - // TextureInternalFormat textureInternalFormat = - // MG_Util::ConvertGLEnumToTextureInternalFormat(format); - MGLOG_D("TexSubImage2D_State: target = %s, level = %d, (%d, %d), format = %s, pixels = %p", - MG_Util::ConvertGLEnumToString(target).c_str(), level, width, height, - MG_Util::ConvertTextureInputFormatToString(textureInputFormat).c_str(), pixels); - // ===================== Error Checking ============================== - if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) return; - if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) return; - if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return; - if (!TextureImpl::ValidateTextureLevelNumber(level)) return; - if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return; - if (!TextureImpl::ValidateTextureSizeRange(width, height, 1)) return; - if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return; - - // TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the - // GL_PIXEL_UNPACK_BUFFER target and the buffer object's data store is currently mapped. - // GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the - // GL_PIXEL_UNPACK_BUFFER target and the data would be unpacked from the buffer object such that the - // memory reads required would exceed the data store size. GL_INVALID_OPERATION is generated if a - // non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER target and data is not evenly - // divisible into the number of bytes needed to store in memory a datum indicated by type. // ======================= Processing ================================ - auto activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); - auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); - auto textureObject = bindingSlot.GetBoundObject(); - TextureInternalFormat textureInternalFormat = textureObject->GetFormat(); - MGLOG_D("%s: working on texture %d", __func__, textureObject->GetExternalIndex()); - - // ===================== Error Checking ============================== - if (!TextureImpl::ValidateTextureObject(textureObject)) return; - if (!TextureImpl::ValidateTextureSubImageOffsets(textureObject, xoffset, width, yoffset, height)) return; - if (!TextureImpl::ValidateTextureInternalFormatCompatibleWithInput( - textureInputFormat, textureInternalFormat, texturePixelDataType)) - return; - - // ======================= Processing ================================ - // Texture object here should always be an object with mipmap - // Assert this for extra safety. - // This should automatically compiled out in release, - // so that we don't take the perf hit of dyn-cast. - MOBILEGL_ASSERT(nullptr != dynamic_cast(textureObject.get()), - "Texture object here should always be an object with mipmap"); - auto textureMipmapObject = static_cast(textureObject.get()); - auto texelSize = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level); - - SizeT inputSize = 0; - - const void* originalPixels = pixels; - - // PBO - const auto& pixelUnpackBufferObject = - MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject(); - if (pixelUnpackBufferObject) { - MGLOG_D("TexSubImage2D_State: Using Pixel Unpack Buffer Object ID: %u", - pixelUnpackBufferObject->GetExternalIndex()); - originalPixels = reinterpret_cast(pixelUnpackBufferObject->GetDataReadOnly()->data()) + - reinterpret_cast(pixels); - } - - if (!originalPixels) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", __func__, - "No data supplied from pixels parameter and no PBO bound.")); - return; - } - const auto& unpackParams = MG_State::pGLContext->GetPixelStoreParameters(true); - void* processedPixels = MG_Util::PixelStoreProcessor::ProcessTexturePixelsDataUnpack( - originalPixels, unpackParams, textureInternalFormat, textureInputFormat, texturePixelDataType, - {width, height, 1}, false, inputSize); - - if (!processedPixels || inputSize == 0) { - MGLOG_E("TexSubImage2D_State: Failed to process pixel data for TexSubImage2D, width: %d, height: %d", - width, height); - if (processedPixels) free(processedPixels); - return; - } - - const SizeT internalBpp = MG_Util::GetInternalBytesPerPixel(textureInternalFormat, texturePixelDataType); - - const SizeT srcRowSize = static_cast(width) * internalBpp; - const SizeT srcStride = (srcRowSize + unpackParams.Alignment - 1) & ~(unpackParams.Alignment - 1); - const SizeT destRowSize = static_cast(texelSize.x()) * internalBpp; - - if (xoffset + width > static_cast(texelSize.x()) || - yoffset + height > static_cast(texelSize.y())) { - MGLOG_E("TexSubImage2D_State: Specified region exceeds texture dimensions"); - free(processedPixels); - return; - } - - const auto* srcData = static_cast(processedPixels); - Uint8* destData = static_cast(textureMipmapObject->MapMipmapData(textureUploadingTarget, level)); - - if (destData) { - for (GLsizei y = 0; y < height; y++) { - const SizeT destRowOffset = (yoffset + y) * destRowSize + xoffset * internalBpp; - const SizeT srcRowOffset = y * srcStride; - Memcpy(destData + destRowOffset, srcData + srcRowOffset, srcRowSize); - } - } - - free(processedPixels); - - MGLOG_D("%s: mark mip %d as dirty", __func__, level); - textureMipmapObject->MarkStorageDirty(textureUploadingTarget, level, true); + SharedPtr textureObject = + GetTextureObjectByTarget(textureUploadingTarget, textureTarget); + if (!textureObject) return; + THROW_UNIMPL_EXCEPTION; + break; } - - void TexSubImage1D_State(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, - const GLvoid* pixels) { - // TODO: implement - } - - // TexParameteriv/TexParameterfv are introduced in OpenGL 4.0, so do not support them for now. - void TexParameterf_State(GLenum target, GLenum pname, GLfloat param) { - + case GL_TEXTURE_SWIZZLE_RGBA: { // ======================= Converting ================================ TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); @@ -187,73 +352,28 @@ namespace MobileGL { GetTextureObjectByTarget(textureUploadingTarget, textureTarget); if (!textureObject) return; - switch (pname) { - case GL_TEXTURE_MAG_FILTER: - textureObject->GetSamplerObject()->SetMagFilter(MG_Util::ConvertGLEnumToSamplerFilterMode(param)); - break; - case GL_TEXTURE_MIN_FILTER: - textureObject->GetSamplerObject()->SetMinFilter(MG_Util::ConvertGLEnumToSamplerFilterMode(param)); - textureObject->GetSamplerObject()->SetMipmapMode(MG_Util::ConvertGLEnumToSamplerMipmapMode(param)); - break; - case GL_TEXTURE_MIN_LOD: { - Float maxLod = textureObject->GetSamplerObject()->GetMaxLod(); - textureObject->GetSamplerObject()->SetLodRange(param, maxLod); - break; - } - case GL_TEXTURE_MAX_LOD: { - Float minLod = textureObject->GetSamplerObject()->GetMinLod(); - textureObject->GetSamplerObject()->SetLodRange(minLod, param); - break; - } - case GL_TEXTURE_BASE_LEVEL: - textureObject->SetBaseLevel(param); - break; - case GL_TEXTURE_MAX_LEVEL: - textureObject->SetMaxLevel(param); - break; - case GL_TEXTURE_SWIZZLE_R: - case GL_TEXTURE_SWIZZLE_G: - case GL_TEXTURE_SWIZZLE_B: - case GL_TEXTURE_SWIZZLE_A: { - auto swizzleParam = MG_Util::ConvertGLEnumPnameToTextureSwizzleParam(pname); - auto swizzleValue = MG_Util::ConvertGLEnumToTextureSwizzleParam(param); - textureObject->SetSwizzleParam(swizzleParam, swizzleValue); - break; - } - case GL_TEXTURE_WRAP_S: - textureObject->GetSamplerObject()->SetWrapS(MG_Util::ConvertGLEnumToSamplerWrapMode(param)); - break; - case GL_TEXTURE_WRAP_T: - textureObject->GetSamplerObject()->SetWrapT(MG_Util::ConvertGLEnumToSamplerWrapMode(param)); - break; - case GL_TEXTURE_WRAP_R: - textureObject->GetSamplerObject()->SetWrapR(MG_Util::ConvertGLEnumToSamplerWrapMode(param)); - break; - case GL_TEXTURE_COMPARE_MODE: - textureObject->GetSamplerObject()->SetCompareMode(MG_Util::ConvertGLEnumToSamplerCompareMode(param)); - break; - case GL_TEXTURE_COMPARE_FUNC: - textureObject->GetSamplerObject()->SetSamplerCompareFunc( - MG_Util::ConvertGLEnumToSamplerCompareFunc(param)); - break; - case GL_TEXTURE_LOD_BIAS: - textureObject->GetSamplerObject()->SetLodBias(param); - break; - case GL_TEXTURE_SWIZZLE_RGBA: - // Not supported in this function - case GL_TEXTURE_BORDER_COLOR: - // Not supported in this function - default: - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", __func__, - std::format("pname {} is not a valid texture parameter.", - MG_Util::ConvertGLEnumToString(pname)))); - return; + Vec4 swizzleParams; + for (int i = 0; i < 4; i++) { + swizzleParams[i] = MG_Util::ConvertGLEnumToTextureSwizzleParam(static_cast(params[i])); + if (TextureSwizzleParam::Unknown == swizzleParams[i]) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", __func__, "`params` is not valid.")); + return; + } } + textureObject->SetSwizzleParamRGBA(swizzleParams); + break; } + default: + TexParameterf_State(target, pname, *params); + break; + } + } - void TexParameteri_State(GLenum target, GLenum pname, GLint param) { + void TexParameteriv_State(GLenum target, GLenum pname, const GLint* params) { + switch (pname) { + case GL_TEXTURE_BORDER_COLOR: { // ======================= Converting ================================ TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); @@ -263,983 +383,842 @@ namespace MobileGL { GetTextureObjectByTarget(textureUploadingTarget, textureTarget); if (!textureObject) return; - switch (pname) { - case GL_TEXTURE_MAG_FILTER: - textureObject->GetSamplerObject()->SetMagFilter(MG_Util::ConvertGLEnumToSamplerFilterMode(param)); - break; - case GL_TEXTURE_MIN_FILTER: - textureObject->GetSamplerObject()->SetMinFilter(MG_Util::ConvertGLEnumToSamplerFilterMode(param)); - textureObject->GetSamplerObject()->SetMipmapMode(MG_Util::ConvertGLEnumToSamplerMipmapMode(param)); - break; - case GL_TEXTURE_MIN_LOD: { - Float maxLod = textureObject->GetSamplerObject()->GetMaxLod(); - textureObject->GetSamplerObject()->SetLodRange(param, maxLod); - break; - } - case GL_TEXTURE_MAX_LOD: { - Float minLod = textureObject->GetSamplerObject()->GetMinLod(); - textureObject->GetSamplerObject()->SetLodRange(minLod, param); - break; - } - case GL_TEXTURE_BASE_LEVEL: - textureObject->SetBaseLevel(param); - break; - case GL_TEXTURE_MAX_LEVEL: - textureObject->SetMaxLevel(param); - break; - case GL_TEXTURE_SWIZZLE_R: - case GL_TEXTURE_SWIZZLE_G: - case GL_TEXTURE_SWIZZLE_B: - case GL_TEXTURE_SWIZZLE_A: { - auto swizzleParam = MG_Util::ConvertGLEnumPnameToTextureSwizzleParam(pname); - auto swizzleValue = MG_Util::ConvertGLEnumToTextureSwizzleParam(param); - textureObject->SetSwizzleParam(swizzleParam, swizzleValue); - break; - } - case GL_TEXTURE_WRAP_S: - textureObject->GetSamplerObject()->SetWrapS(MG_Util::ConvertGLEnumToSamplerWrapMode(param)); - break; - case GL_TEXTURE_WRAP_T: - textureObject->GetSamplerObject()->SetWrapT(MG_Util::ConvertGLEnumToSamplerWrapMode(param)); - break; - case GL_TEXTURE_WRAP_R: - textureObject->GetSamplerObject()->SetWrapR(MG_Util::ConvertGLEnumToSamplerWrapMode(param)); - break; - case GL_TEXTURE_COMPARE_MODE: - textureObject->GetSamplerObject()->SetCompareMode(MG_Util::ConvertGLEnumToSamplerCompareMode(param)); - break; - case GL_TEXTURE_COMPARE_FUNC: - textureObject->GetSamplerObject()->SetSamplerCompareFunc( - MG_Util::ConvertGLEnumToSamplerCompareFunc(param)); - break; - case GL_TEXTURE_LOD_BIAS: - textureObject->GetSamplerObject()->SetLodBias((GLfloat)param); - break; - case GL_TEXTURE_SWIZZLE_RGBA: - // Not supported in this function - case GL_TEXTURE_BORDER_COLOR: - // Not supported in this function - default: - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", __func__, - std::format("pname {} is not a valid texture parameter.", - MG_Util::ConvertGLEnumToString(pname)))); - return; - } - } - - // Quick and dirty TexParameter*v implementation to make NeoForge happy. - // TODO: implement the missing part - void TexParameterfv_State(GLenum target, GLenum pname, const GLfloat* params) { - switch (pname) { - case GL_TEXTURE_BORDER_COLOR: { - // ======================= Converting ================================ - TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); - - // ======================= Processing ================================ - SharedPtr textureObject = - GetTextureObjectByTarget(textureUploadingTarget, textureTarget); - if (!textureObject) return; - THROW_UNIMPL_EXCEPTION; - break; - } - case GL_TEXTURE_SWIZZLE_RGBA: { - // ======================= Converting ================================ - TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); - - // ======================= Processing ================================ - SharedPtr textureObject = - GetTextureObjectByTarget(textureUploadingTarget, textureTarget); - if (!textureObject) return; - - Vec4 swizzleParams; - for (int i = 0; i < 4; i++) { - swizzleParams[i] = MG_Util::ConvertGLEnumToTextureSwizzleParam(static_cast(params[i])); - if (TextureSwizzleParam::Unknown == swizzleParams[i]) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", __func__, "`params` is not valid.")); - return; - } - } - textureObject->SetSwizzleParamRGBA(swizzleParams); - break; - } - default: - TexParameterf_State(target, pname, *params); - break; - } - } - - void TexParameteriv_State(GLenum target, GLenum pname, const GLint* params) { - switch (pname) { - case GL_TEXTURE_BORDER_COLOR: { - // ======================= Converting ================================ - TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); - - // ======================= Processing ================================ - SharedPtr textureObject = - GetTextureObjectByTarget(textureUploadingTarget, textureTarget); - if (!textureObject) return; - - THROW_UNIMPL_EXCEPTION; - break; - } - case GL_TEXTURE_SWIZZLE_RGBA: { - // ======================= Converting ================================ - TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); - - // ======================= Processing ================================ - SharedPtr textureObject = - GetTextureObjectByTarget(textureUploadingTarget, textureTarget); - if (!textureObject) return; - - Vec4 swizzleParams; - for (int i = 0; i < 4; i++) { - swizzleParams[i] = MG_Util::ConvertGLEnumToTextureSwizzleParam(static_cast(params[i])); - if (TextureSwizzleParam::Unknown == swizzleParams[i]) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", __func__, "`params` is not valid.")); - return; - } - } - textureObject->SetSwizzleParamRGBA(swizzleParams); - break; - } - default: - TexParameteri_State(target, pname, *params); - break; - } - } - - void TexParameterIiv_State(GLenum target, GLenum pname, const GLint* params) { - switch (pname) { - case GL_TEXTURE_BORDER_COLOR: { - THROW_UNIMPL_EXCEPTION; - break; - } - case GL_TEXTURE_SWIZZLE_RGBA: { - // ======================= Converting ================================ - TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); - - // ======================= Processing ================================ - SharedPtr textureObject = - GetTextureObjectByTarget(textureUploadingTarget, textureTarget); - if (!textureObject) return; - - Vec4 swizzleParams; - for (int i = 0; i < 4; i++) { - swizzleParams[i] = MG_Util::ConvertGLEnumToTextureSwizzleParam(static_cast(params[i])); - if (TextureSwizzleParam::Unknown == swizzleParams[i]) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", __func__, "`params` is not valid.")); - return; - } - } - textureObject->SetSwizzleParamRGBA(swizzleParams); - break; - } - default: - TexParameteri_State(target, pname, *params); - break; - } - } - - void TexParameterIuiv_State(GLenum target, GLenum pname, const GLuint* params) { - switch (pname) { - case GL_TEXTURE_BORDER_COLOR: { - THROW_UNIMPL_EXCEPTION; - break; - } - case GL_TEXTURE_SWIZZLE_RGBA: { - // ======================= Converting ================================ - TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); - - // ======================= Processing ================================ - SharedPtr textureObject = - GetTextureObjectByTarget(textureUploadingTarget, textureTarget); - if (!textureObject) return; - - Vec4 swizzleParams; - for (int i = 0; i < 4; i++) { - swizzleParams[i] = MG_Util::ConvertGLEnumToTextureSwizzleParam(static_cast(params[i])); - if (TextureSwizzleParam::Unknown == swizzleParams[i]) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", __func__, "`params` is not valid.")); - return; - } - } - textureObject->SetSwizzleParamRGBA(swizzleParams); - break; - } - default: - TexParameteri_State(target, pname, static_cast(*params)); - break; - } - } - - void TexImage3DMultisample_State(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) { - // TODO: implement - } - - void TexImage2DMultisample_State(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, - GLsizei height, GLboolean fixedsamplelocations) { - // TODO: implement - } - - void TexImage3D_State(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, - GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) { - MGLOG_D( - "%s called with target: %s, level: %d, internalformat: %s, width: %d, height: %d, depth: %d, " - "border: %d, format: %s, type: %s (%u), pixels: %p", - __func__, - MG_Util::ConvertTextureUploadTargetToString(MG_Util::ConvertGLEnumToTextureUploadTarget(target)) - .c_str(), - level, - MG_Util::ConvertTextureInternalFormatToString( - MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat)) - .c_str(), - width, height, depth, border, - MG_Util::ConvertTextureInputFormatToString(MG_Util::ConvertGLEnumToTextureInputFormat(format)).c_str(), - MG_Util::ConvertTexturePixelDataTypeToString(MG_Util::ConvertGLEnumToTexturePixelDataType(type)) - .c_str(), - type, pixels); - // ======================= Converting ================================ - TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); - TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format); - TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type); - TextureInternalFormat textureInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat); - - // ===================== Error Checking ============================== - if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) return; - if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) return; - if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return; - if (!TextureImpl::ValidateTextureLevelNumber(level)) return; - if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return; - if (!TextureImpl::ValidateTextureSizeRange(width, height, depth)) return; - if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return; - if (!TextureImpl::ValidateTextureBorderNumber(border)) return; - if (!TextureImpl::ValidateTextureInternalFormatCompatibleWithInput( - textureInputFormat, textureInternalFormat, texturePixelDataType)) - return; - if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return; - - // TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the - // GL_PIXEL_UNPACK_BUFFER target and the buffer object's data store is currently mapped. - // GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER - // target and the data would be unpacked from the buffer object such that the memory reads required would - // exceed the data store size. - // GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER - // target and data is not evenly divisible into the number of bytes needed to store in memory a datum - // indicated by type. - // ======================= Processing ================================ - SharedPtr textureObject = nullptr; - Bool isProxy = TextureImpl::IsProxyTextureTarget(textureUploadingTarget); - if (isProxy) { - textureObject = - TextureImpl::pProxyTextureManager->CreateOrReplaceProxyTextureObject(textureUploadingTarget); - } else { - auto activeUnit = - MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); - auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); - textureObject = bindingSlot.GetBoundObject(); - } - - // ===================== Error Checking ============================== - if (!TextureImpl::ValidateTextureObject(textureObject)) return; - - // ======================= Processing ================================ - - SizeT imageSize = 0; - const SizeT inputBpp = MG_Util::GetInputBytesPerPixel(textureInputFormat, texturePixelDataType); - const SizeT internalBpp = MG_Util::GetInternalBytesPerPixel(textureInternalFormat, texturePixelDataType); - const SizeT internalBytes = width * height * depth * internalBpp; - - textureObject->SetInternalFormat(textureInternalFormat); - - // if isProxy, no more pixel transfer needed below - if (isProxy) return; - - const void* originalPixels = pixels; - - // PBO - const auto& pixelUnpackBufferObject = - MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject(); - if (pixelUnpackBufferObject) { - MGLOG_D("%s: Using Pixel Unpack Buffer Object ID: %u", __func__, - pixelUnpackBufferObject->GetExternalIndex()); - originalPixels = reinterpret_cast(pixelUnpackBufferObject->GetDataReadOnly()->data()) + - reinterpret_cast(pixels); - } - - MOBILEGL_ASSERT(nullptr != dynamic_cast(textureObject.get()), - "Texture object here should always be an object with mipmap"); - auto textureMipmapObject = static_cast(textureObject.get()); - - // Allocate in TextureObject - textureMipmapObject->AllocateStorage(textureUploadingTarget, level, - {{width, height, depth}, internalBytes}); - - if (!originalPixels) { - MGLOG_D("%s: No input pixel and no PBO bound, no pixel transfer", __func__); - return; - } - - void* processedPixels = nullptr; - processedPixels = MG_Util::PixelStoreProcessor::ProcessTexturePixelsDataUnpack( - originalPixels, MG_State::pGLContext->GetPixelStoreParameters(true), textureInternalFormat, - textureInputFormat, texturePixelDataType, {width, height, depth}, false, imageSize); - - if (processedPixels && imageSize > 0) { - if (imageSize != internalBytes) { - MGLOG_W("%s: Processed pixel data size (%zu) does not match expected size (%zu). " - "This may indicate an alignment or processing issue.", - __func__, imageSize, internalBytes); - } - - const SizeT copySize = std::min(imageSize, internalBytes); - DataPtr texelInput{processedPixels, copySize}; - textureMipmapObject->UpdateMipmapSubData(textureUploadingTarget, level, texelInput); - } - - textureMipmapObject->MarkStorageDirty(textureUploadingTarget, level, true); - - free(processedPixels); - } - - void TexImage2D_State(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, const void* pixels) { - // ======================= Converting ================================ - TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); - TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format); - TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type); - TextureInternalFormat textureInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat); - MGLOG_D("%s called with target: %s (%s), level: %d, internalformat: %s (%s), width: %d, height: %d, " - "border: %d, format: %s (%s), type: %s (%s), pixels: %p", - __func__, MG_Util::ConvertTextureUploadTargetToString(textureUploadingTarget).c_str(), - MG_Util::ConvertGLEnumToString(target).c_str(), level, - MG_Util::ConvertTextureInternalFormatToString(textureInternalFormat).c_str(), - MG_Util::ConvertGLEnumToString(internalformat).c_str(), width, height, border, - MG_Util::ConvertTextureInputFormatToString(textureInputFormat).c_str(), - MG_Util::ConvertGLEnumToString(format).c_str(), - MG_Util::ConvertTexturePixelDataTypeToString(texturePixelDataType).c_str(), - MG_Util::ConvertGLEnumToString(type).c_str(), pixels); - // ===================== Error Checking ============================== - if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) return; - if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) return; - if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return; - if (!TextureImpl::ValidateTextureLevelNumber(level)) return; - if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return; - if (!TextureImpl::ValidateTextureSizeRange(width, height, 1)) return; - if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return; - if (!TextureImpl::ValidateTextureBorderNumber(border)) return; - if (!TextureImpl::ValidateTextureInternalFormatCompatibleWithInput( - textureInputFormat, textureInternalFormat, texturePixelDataType)) - return; - if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return; - - // TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the - // GL_PIXEL_UNPACK_BUFFER target and the buffer object's data store is currently mapped. - // GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER - // target and the data would be unpacked from the buffer object such that the memory reads required would - // exceed the data store size. - // GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER - // target and data is not evenly divisible into the number of bytes needed to store in memory a datum - // indicated by type. - - // ======================= Processing ================================ - textureInternalFormat = - MG_Util::ConvertInternalFormatToSized(textureInternalFormat, textureInputFormat, texturePixelDataType); - SharedPtr textureObject = nullptr; - Bool isProxy = TextureImpl::IsProxyTextureTarget(textureUploadingTarget); - if (isProxy) { - textureObject = - TextureImpl::pProxyTextureManager->CreateOrReplaceProxyTextureObject(textureUploadingTarget); - } else { - auto activeUnit = - MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); - auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); - textureObject = bindingSlot.GetBoundObject(); - } - - // ===================== Error Checking ============================== - if (!TextureImpl::ValidateTextureObject(textureObject)) return; - - // ======================= Processing ================================ - - SizeT imageSize = 0; - const SizeT inputBpp = MG_Util::GetInputBytesPerPixel(textureInputFormat, texturePixelDataType); - const SizeT internalBpp = MG_Util::GetInternalBytesPerPixel(textureInternalFormat, texturePixelDataType); - const SizeT internalBytes = width * height * internalBpp; - - MGLOG_D("%s: working on texture %d", __func__, textureObject->GetExternalIndex()); - - MGLOG_D("%s: texture object had internal format %s, new format %s", __func__, - MG_Util::ConvertTextureInternalFormatToString(textureObject->GetFormat()).c_str(), - MG_Util::ConvertTextureInternalFormatToString(textureInternalFormat).c_str()); - textureObject->SetInternalFormat(textureInternalFormat); - - // if isProxy, no more pixel transfer needed below - if (isProxy) return; - - const void* originalPixels = pixels; - - // PBO - const auto& pixelUnpackBufferObject = - MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject(); - if (pixelUnpackBufferObject) { - MGLOG_D("%s: Using Pixel Unpack Buffer Object ID: %u", __func__, - pixelUnpackBufferObject->GetExternalIndex()); - originalPixels = reinterpret_cast(pixelUnpackBufferObject->GetDataReadOnly()->data()) + - reinterpret_cast(pixels); - } - - MOBILEGL_ASSERT(nullptr != dynamic_cast(textureObject.get()), - "Texture object here should always be an object with mipmap"); - auto textureMipmapObject = static_cast(textureObject.get()); - - // Allocate in TextureObject - MGLOG_D("%s: Allocating %d bytes at mip %d", __func__, internalBytes, level); - textureMipmapObject->AllocateStorage(textureUploadingTarget, level, {{width, height, 1}, internalBytes}); - - if (!originalPixels) { - MGLOG_D("%s: No input pixel and no PBO bound, no pixel transfer", __func__); - return; - } - - void* processedPixels = nullptr; - processedPixels = MG_Util::PixelStoreProcessor::ProcessTexturePixelsDataUnpack( - originalPixels, MG_State::pGLContext->GetPixelStoreParameters(true), textureInternalFormat, - textureInputFormat, texturePixelDataType, {width, height, 1}, false, imageSize); - - if (processedPixels && imageSize > 0) { - if (imageSize != internalBytes) { - MGLOG_W("TexImage2D_State: Processed pixel data size (%zu) does not match expected size (%zu). " - "This may indicate an alignment or processing issue.", - imageSize, internalBytes); - } - - const SizeT copySize = std::min(imageSize, internalBytes); - DataPtr texelInput{processedPixels, copySize}; - textureMipmapObject->UpdateMipmapSubData(textureUploadingTarget, level, texelInput); - } - - free(processedPixels); - - MGLOG_D("%s: mark mip %d as dirty", __func__, level); - textureMipmapObject->MarkStorageDirty(textureUploadingTarget, level, true); - } - - void TexImage1D_State(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, - GLenum format, GLenum type, const GLvoid* pixels) { - // TODO: implement THROW_UNIMPL_EXCEPTION; + break; } - - void TexBuffer_State(GLenum target, GLenum internalformat, GLuint buffer) { + case GL_TEXTURE_SWIZZLE_RGBA: { // ======================= Converting ================================ - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureInternalFormat textureInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat); - - // ===================== Error Checking ============================== - if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return; - if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return; - // TODO: make sure `internalformat` is in one of supported format for TexBuffer - auto bufferObject = MG_State::pGLContext->GetBufferObject(buffer); - if (!bufferObject) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared( - "MG_Impl/GLImpl", __func__, - "`buffer` is not zero and is not the name of an existing buffer object.")); - return; - } + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); // ======================= Processing ================================ + SharedPtr textureObject = + GetTextureObjectByTarget(textureUploadingTarget, textureTarget); + if (!textureObject) return; + + Vec4 swizzleParams; + for (int i = 0; i < 4; i++) { + swizzleParams[i] = MG_Util::ConvertGLEnumToTextureSwizzleParam(static_cast(params[i])); + if (TextureSwizzleParam::Unknown == swizzleParams[i]) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", __func__, "`params` is not valid.")); + return; + } + } + textureObject->SetSwizzleParamRGBA(swizzleParams); + break; + } + default: + TexParameteri_State(target, pname, *params); + break; + } + } + + void TexParameterIiv_State(GLenum target, GLenum pname, const GLint* params) { + switch (pname) { + case GL_TEXTURE_BORDER_COLOR: { + THROW_UNIMPL_EXCEPTION; + break; + } + case GL_TEXTURE_SWIZZLE_RGBA: { + // ======================= Converting ================================ + TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + + // ======================= Processing ================================ + SharedPtr textureObject = + GetTextureObjectByTarget(textureUploadingTarget, textureTarget); + if (!textureObject) return; + + Vec4 swizzleParams; + for (int i = 0; i < 4; i++) { + swizzleParams[i] = MG_Util::ConvertGLEnumToTextureSwizzleParam(static_cast(params[i])); + if (TextureSwizzleParam::Unknown == swizzleParams[i]) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", __func__, "`params` is not valid.")); + return; + } + } + textureObject->SetSwizzleParamRGBA(swizzleParams); + break; + } + default: + TexParameteri_State(target, pname, *params); + break; + } + } + + void TexParameterIuiv_State(GLenum target, GLenum pname, const GLuint* params) { + switch (pname) { + case GL_TEXTURE_BORDER_COLOR: { + THROW_UNIMPL_EXCEPTION; + break; + } + case GL_TEXTURE_SWIZZLE_RGBA: { + // ======================= Converting ================================ + TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + + // ======================= Processing ================================ + SharedPtr textureObject = + GetTextureObjectByTarget(textureUploadingTarget, textureTarget); + if (!textureObject) return; + + Vec4 swizzleParams; + for (int i = 0; i < 4; i++) { + swizzleParams[i] = MG_Util::ConvertGLEnumToTextureSwizzleParam(static_cast(params[i])); + if (TextureSwizzleParam::Unknown == swizzleParams[i]) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", __func__, "`params` is not valid.")); + return; + } + } + textureObject->SetSwizzleParamRGBA(swizzleParams); + break; + } + default: + TexParameteri_State(target, pname, static_cast(*params)); + break; + } + } + + void TexImage3DMultisample_State(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) { + // TODO: implement + } + + void TexImage2DMultisample_State(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, + GLsizei height, GLboolean fixedsamplelocations) { + // TODO: implement + } + + void TexImage3D_State(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) { + MGLOG_D( + "%s called with target: %s, level: %d, internalformat: %s, width: %d, height: %d, depth: %d, " + "border: %d, format: %s, type: %s (%u), pixels: %p", + __func__, + MG_Util::ConvertTextureUploadTargetToString(MG_Util::ConvertGLEnumToTextureUploadTarget(target)).c_str(), + level, + MG_Util::ConvertTextureInternalFormatToString(MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat)) + .c_str(), + width, height, depth, border, + MG_Util::ConvertTextureInputFormatToString(MG_Util::ConvertGLEnumToTextureInputFormat(format)).c_str(), + MG_Util::ConvertTexturePixelDataTypeToString(MG_Util::ConvertGLEnumToTexturePixelDataType(type)).c_str(), + type, pixels); + // ======================= Converting ================================ + TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format); + TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type); + TextureInternalFormat textureInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat); + + // ===================== Error Checking ============================== + if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) return; + if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) return; + if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return; + if (!TextureImpl::ValidateTextureLevelNumber(level)) return; + if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return; + if (!TextureImpl::ValidateTextureSizeRange(width, height, depth)) return; + if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return; + if (!TextureImpl::ValidateTextureBorderNumber(border)) return; + if (!TextureImpl::ValidateTextureInternalFormatCompatibleWithInput(textureInputFormat, textureInternalFormat, + texturePixelDataType)) + return; + if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return; + + // TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the + // GL_PIXEL_UNPACK_BUFFER target and the buffer object's data store is currently mapped. + // GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER + // target and the data would be unpacked from the buffer object such that the memory reads required would + // exceed the data store size. + // GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER + // target and data is not evenly divisible into the number of bytes needed to store in memory a datum + // indicated by type. + // ======================= Processing ================================ + SharedPtr textureObject = nullptr; + Bool isProxy = TextureImpl::IsProxyTextureTarget(textureUploadingTarget); + if (isProxy) { + textureObject = + TextureImpl::pProxyTextureManager->CreateOrReplaceProxyTextureObject(textureUploadingTarget); + } else { auto activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); - auto textureObject = bindingSlot.GetBoundObject(); - - // ===================== Error Checking ============================== - if (!TextureImpl::ValidateTextureObject(textureObject)) return; - if (textureObject->GetStorageType() != TextureStorageType::Buffer) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", __func__, - "The effective target of `texture` is not `GL_TEXTURE_BUFFER`.")); - return; - } - - // ======================= Processing ================================ - // Now we can rest assured, and down-cast texture object to texture buffer - auto* texBufferObject = static_cast(textureObject.get()); - auto& bufferSlot = texBufferObject->GetBufferBindingSlot(); - bufferSlot.Bind(bufferObject); - - texBufferObject->SetInternalFormat(textureInternalFormat); + textureObject = bindingSlot.GetBoundObject(); } - GLboolean IsTexture_State(GLuint texture) { - // ======================= Processing ================================ - if (!TextureImpl::ValidateTextureName(texture, true)) return GL_FALSE; - return MG_State::pGLContext->ValidateTextureObject(texture) ? GL_TRUE : GL_FALSE; + // ===================== Error Checking ============================== + if (!TextureImpl::ValidateTextureObject(textureObject)) return; + + // ======================= Processing ================================ + + SizeT imageSize = 0; + const SizeT inputBpp = MG_Util::GetInputBytesPerPixel(textureInputFormat, texturePixelDataType); + const SizeT internalBpp = MG_Util::GetInternalBytesPerPixel(textureInternalFormat, texturePixelDataType); + const SizeT internalBytes = width * height * depth * internalBpp; + + textureObject->SetInternalFormat(textureInternalFormat); + + // if isProxy, no more pixel transfer needed below + if (isProxy) return; + + const void* originalPixels = pixels; + + // PBO + const auto& pixelUnpackBufferObject = + MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject(); + if (pixelUnpackBufferObject) { + MGLOG_D("%s: Using Pixel Unpack Buffer Object ID: %u", __func__, + pixelUnpackBufferObject->GetExternalIndex()); + originalPixels = reinterpret_cast(pixelUnpackBufferObject->GetDataReadOnly()->data()) + + reinterpret_cast(pixels); } - void GetTexParameterIuiv_State(GLenum target, GLenum pname, GLuint* params) { - // TODO: implement - THROW_UNIMPL_EXCEPTION; + MOBILEGL_ASSERT(nullptr != dynamic_cast(textureObject.get()), + "Texture object here should always be an object with mipmap"); + auto textureMipmapObject = static_cast(textureObject.get()); + + // Allocate in TextureObject + textureMipmapObject->AllocateStorage(textureUploadingTarget, level, {{width, height, depth}, internalBytes}); + + if (!originalPixels) { + MGLOG_D("%s: No input pixel and no PBO bound, no pixel transfer", __func__); + return; } - void GetTexParameterIiv_State(GLenum target, GLenum pname, GLint* params) { - // TODO: implement - THROW_UNIMPL_EXCEPTION; + void* processedPixels = nullptr; + processedPixels = MG_Util::PixelStoreProcessor::ProcessTexturePixelsDataUnpack( + originalPixels, MG_State::pGLContext->GetPixelStoreParameters(true), textureInternalFormat, + textureInputFormat, texturePixelDataType, {width, height, depth}, false, imageSize); + + if (processedPixels && imageSize > 0) { + if (imageSize != internalBytes) { + MGLOG_W("%s: Processed pixel data size (%zu) does not match expected size (%zu). " + "This may indicate an alignment or processing issue.", + __func__, imageSize, internalBytes); + } + + const SizeT copySize = std::min(imageSize, internalBytes); + DataPtr texelInput{processedPixels, copySize}; + textureMipmapObject->UpdateMipmapSubData(textureUploadingTarget, level, texelInput); } - void GetTexParameteriv_State(GLenum target, GLenum pname, GLint* params) { - // ======================= Converting ================================ - TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + textureMipmapObject->MarkStorageDirty(textureUploadingTarget, level, true); - // ======================= Processing ================================ - SharedPtr textureObject = nullptr; - if (TextureImpl::IsProxyTextureTarget(textureUploadingTarget)) { - textureObject = TextureImpl::pProxyTextureManager->GetProxyTextureObject(textureUploadingTarget); - } else { - auto activeUnit = - MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); - auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); - textureObject = bindingSlot.GetBoundObject(); - } + free(processedPixels); + } - if (!TextureImpl::ValidateTextureObject(textureObject)) return; + void TexImage2D_State(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, const void* pixels) { + // ======================= Converting ================================ + TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format); + TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type); + TextureInternalFormat textureInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat); + MGLOG_D("%s called with target: %s (%s), level: %d, internalformat: %s (%s), width: %d, height: %d, " + "border: %d, format: %s (%s), type: %s (%s), pixels: %p", + __func__, MG_Util::ConvertTextureUploadTargetToString(textureUploadingTarget).c_str(), + MG_Util::ConvertGLEnumToString(target).c_str(), level, + MG_Util::ConvertTextureInternalFormatToString(textureInternalFormat).c_str(), + MG_Util::ConvertGLEnumToString(internalformat).c_str(), width, height, border, + MG_Util::ConvertTextureInputFormatToString(textureInputFormat).c_str(), + MG_Util::ConvertGLEnumToString(format).c_str(), + MG_Util::ConvertTexturePixelDataTypeToString(texturePixelDataType).c_str(), + MG_Util::ConvertGLEnumToString(type).c_str(), pixels); + // ===================== Error Checking ============================== + if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) return; + if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) return; + if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return; + if (!TextureImpl::ValidateTextureLevelNumber(level)) return; + if (!TextureImpl::ValidateTextureSizeWithTextureUploadTarget(textureUploadingTarget, width, height)) return; + if (!TextureImpl::ValidateTextureSizeRange(width, height, 1)) return; + if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return; + if (!TextureImpl::ValidateTextureBorderNumber(border)) return; + if (!TextureImpl::ValidateTextureInternalFormatCompatibleWithInput(textureInputFormat, textureInternalFormat, + texturePixelDataType)) + return; + if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return; - switch (pname) { - case GL_TEXTURE_MAG_FILTER: - if (params) { - *params = MG_Util::ConvertSamplerFilterModeToGLEnum( - textureObject->GetSamplerObject()->GetMagFilter(), SamplerMipmapMode::None); - } - break; - case GL_TEXTURE_MIN_FILTER: - if (params) { - *params = - MG_Util::ConvertSamplerFilterModeToGLEnum(textureObject->GetSamplerObject()->GetMinFilter(), - textureObject->GetSamplerObject()->GetMipmapMode()); - } - break; - case GL_TEXTURE_MIN_LOD: - if (params) { - *params = static_cast(textureObject->GetSamplerObject()->GetMinLod()); - } - break; - case GL_TEXTURE_MAX_LOD: - if (params) { - *params = static_cast(textureObject->GetSamplerObject()->GetMaxLod()); - } - break; - case GL_TEXTURE_BASE_LEVEL: - case GL_TEXTURE_MAX_LEVEL: - case GL_TEXTURE_BORDER_COLOR: - break; // TODO - case GL_TEXTURE_WRAP_S: - if (params) { - *params = MG_Util::ConvertSamplerWrapModeToGLEnum(textureObject->GetSamplerObject()->GetWrapS()); - } - break; - case GL_TEXTURE_WRAP_T: - if (params) { - *params = MG_Util::ConvertSamplerWrapModeToGLEnum(textureObject->GetSamplerObject()->GetWrapT()); - } - break; - case GL_TEXTURE_WRAP_R: - if (params) { - *params = MG_Util::ConvertSamplerWrapModeToGLEnum(textureObject->GetSamplerObject()->GetWrapR()); - } - break; - case GL_TEXTURE_COMPARE_MODE: - if (params) { - *params = - MG_Util::ConvertSamplerCompareModeToGLEnum(textureObject->GetSamplerObject()->GetCompareMode()); - } - break; - case GL_TEXTURE_COMPARE_FUNC: - if (params) { - *params = MG_Util::ConvertSamplerCompareFuncToGLEnum( - textureObject->GetSamplerObject()->GetSamplerCompareFunc()); - } - break; - default: - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, MakeShared("MG_Impl/GLImpl", "GetTexParameteriv_State", - "pname is not a valid texture parameter.")); - return; - } + // TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the + // GL_PIXEL_UNPACK_BUFFER target and the buffer object's data store is currently mapped. + // GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER + // target and the data would be unpacked from the buffer object such that the memory reads required would + // exceed the data store size. + // GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER + // target and data is not evenly divisible into the number of bytes needed to store in memory a datum + // indicated by type. + + // ======================= Processing ================================ + textureInternalFormat = + MG_Util::ConvertInternalFormatToSized(textureInternalFormat, textureInputFormat, texturePixelDataType); + SharedPtr textureObject = nullptr; + Bool isProxy = TextureImpl::IsProxyTextureTarget(textureUploadingTarget); + if (isProxy) { + textureObject = + TextureImpl::pProxyTextureManager->CreateOrReplaceProxyTextureObject(textureUploadingTarget); + } else { + auto activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); + auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); + textureObject = bindingSlot.GetBoundObject(); } - void GetTexParameterfv_State(GLenum target, GLenum pname, GLfloat* params) { - // ======================= Converting ================================ - TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + // ===================== Error Checking ============================== + if (!TextureImpl::ValidateTextureObject(textureObject)) return; - // ======================= Processing ================================ - SharedPtr textureObject = nullptr; - if (TextureImpl::IsProxyTextureTarget(textureUploadingTarget)) { - textureObject = TextureImpl::pProxyTextureManager->GetProxyTextureObject(textureUploadingTarget); - } else { - auto activeUnit = - MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); - auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); - textureObject = bindingSlot.GetBoundObject(); - } + // ======================= Processing ================================ - if (!TextureImpl::ValidateTextureObject(textureObject)) return; + SizeT imageSize = 0; + const SizeT inputBpp = MG_Util::GetInputBytesPerPixel(textureInputFormat, texturePixelDataType); + const SizeT internalBpp = MG_Util::GetInternalBytesPerPixel(textureInternalFormat, texturePixelDataType); + const SizeT internalBytes = width * height * internalBpp; - switch (pname) { - case GL_TEXTURE_MAG_FILTER: - if (params) { - *params = MG_Util::ConvertSamplerFilterModeToGLEnum( - textureObject->GetSamplerObject()->GetMagFilter(), SamplerMipmapMode::None); - } - break; - case GL_TEXTURE_MIN_FILTER: - if (params) { - *params = - MG_Util::ConvertSamplerFilterModeToGLEnum(textureObject->GetSamplerObject()->GetMinFilter(), - textureObject->GetSamplerObject()->GetMipmapMode()); - } - break; - case GL_TEXTURE_MIN_LOD: - if (params) { - *params = static_cast(textureObject->GetSamplerObject()->GetMinLod()); - } - break; - case GL_TEXTURE_MAX_LOD: - if (params) { - *params = static_cast(textureObject->GetSamplerObject()->GetMaxLod()); - } - break; - case GL_TEXTURE_BASE_LEVEL: - case GL_TEXTURE_MAX_LEVEL: - case GL_TEXTURE_SWIZZLE_R: - case GL_TEXTURE_SWIZZLE_G: - case GL_TEXTURE_SWIZZLE_B: - case GL_TEXTURE_SWIZZLE_A: - case GL_TEXTURE_SWIZZLE_RGBA: - case GL_TEXTURE_BORDER_COLOR: - break; // TODO - case GL_TEXTURE_WRAP_S: - if (params) { - *params = MG_Util::ConvertSamplerWrapModeToGLEnum(textureObject->GetSamplerObject()->GetWrapS()); - } - break; - case GL_TEXTURE_WRAP_T: - if (params) { - *params = MG_Util::ConvertSamplerWrapModeToGLEnum(textureObject->GetSamplerObject()->GetWrapT()); - } - break; - case GL_TEXTURE_WRAP_R: - if (params) { - *params = MG_Util::ConvertSamplerWrapModeToGLEnum(textureObject->GetSamplerObject()->GetWrapR()); - } - break; - case GL_TEXTURE_COMPARE_MODE: - if (params) { - *params = - MG_Util::ConvertSamplerCompareModeToGLEnum(textureObject->GetSamplerObject()->GetCompareMode()); - } - break; - case GL_TEXTURE_COMPARE_FUNC: - if (params) { - *params = MG_Util::ConvertSamplerCompareFuncToGLEnum( - textureObject->GetSamplerObject()->GetSamplerCompareFunc()); - } - break; - default: - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, MakeShared("MG_Impl/GLImpl", "GetTexParameterfv_State", - "pname is not a valid texture parameter.")); - return; - } + MGLOG_D("%s: working on texture %d", __func__, textureObject->GetExternalIndex()); + + MGLOG_D("%s: texture object had internal format %s, new format %s", __func__, + MG_Util::ConvertTextureInternalFormatToString(textureObject->GetFormat()).c_str(), + MG_Util::ConvertTextureInternalFormatToString(textureInternalFormat).c_str()); + textureObject->SetInternalFormat(textureInternalFormat); + + // if isProxy, no more pixel transfer needed below + if (isProxy) return; + + const void* originalPixels = pixels; + + // PBO + const auto& pixelUnpackBufferObject = + MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject(); + if (pixelUnpackBufferObject) { + MGLOG_D("%s: Using Pixel Unpack Buffer Object ID: %u", __func__, + pixelUnpackBufferObject->GetExternalIndex()); + originalPixels = reinterpret_cast(pixelUnpackBufferObject->GetDataReadOnly()->data()) + + reinterpret_cast(pixels); } - void GetTexLevelParameteriv_State(GLenum target, GLint level, GLenum pname, GLint* params) { - MGLOG_D("GetTexLevelParameteriv_State called"); - // ======================= Converting ================================ - TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + MOBILEGL_ASSERT(nullptr != dynamic_cast(textureObject.get()), + "Texture object here should always be an object with mipmap"); + auto textureMipmapObject = static_cast(textureObject.get()); - // ===================== Error Checking ============================== - if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return; - if (!TextureImpl::ValidateTextureLevelNumber(level)) return; - if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return; + // Allocate in TextureObject + MGLOG_D("%s: Allocating %d bytes at mip %d", __func__, internalBytes, level); + textureMipmapObject->AllocateStorage(textureUploadingTarget, level, {{width, height, 1}, internalBytes}); - // ======================= Processing ================================ - SharedPtr textureObject = nullptr; - - if (TextureImpl::IsProxyTextureTarget(textureUploadingTarget)) { - textureObject = TextureImpl::pProxyTextureManager->GetProxyTextureObject(textureUploadingTarget); - } else { - auto activeUnit = - MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); - auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); - textureObject = bindingSlot.GetBoundObject(); - } - - if (!TextureImpl::ValidateTextureObject(textureObject)) return; - - switch (pname) { - case GL_TEXTURE_WIDTH: - if (params) { - switch (textureObject->GetStorageType()) { - case TextureStorageType::Mipmap: { - const auto textureMipmapObject = - static_cast(textureObject.get()); - *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).x(); - break; - } - default: - THROW_UNIMPL_EXCEPTION; - } - } - break; - case GL_TEXTURE_HEIGHT: - if (params) { - switch (textureObject->GetStorageType()) { - case TextureStorageType::Mipmap: { - const auto textureMipmapObject = - static_cast(textureObject.get()); - *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).y(); - break; - } - default: - THROW_UNIMPL_EXCEPTION; - } - } - break; - case GL_TEXTURE_DEPTH: - if (params) { - switch (textureObject->GetStorageType()) { - case TextureStorageType::Mipmap: { - const auto textureMipmapObject = - static_cast(textureObject.get()); - *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).z(); - break; - } - default: - THROW_UNIMPL_EXCEPTION; - } - } - break; - case GL_TEXTURE_INTERNAL_FORMAT: - if (params) { - *params = MG_Util::ConvertTextureInternalFormatToGLEnum(textureObject->GetFormat()); - } - break; - case GL_TEXTURE_RED_TYPE: - case GL_TEXTURE_GREEN_TYPE: - case GL_TEXTURE_BLUE_TYPE: - case GL_TEXTURE_ALPHA_TYPE: - case GL_TEXTURE_DEPTH_TYPE: - case GL_TEXTURE_RED_SIZE: - case GL_TEXTURE_GREEN_SIZE: - case GL_TEXTURE_BLUE_SIZE: - case GL_TEXTURE_ALPHA_SIZE: - case GL_TEXTURE_DEPTH_SIZE: - case GL_TEXTURE_COMPRESSED: - case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: - break; // TODO - default: - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", "GetTexLevelParameteriv_State", - "pname is not a valid texture level parameter.")); - return; - } + if (!originalPixels) { + MGLOG_D("%s: No input pixel and no PBO bound, no pixel transfer", __func__); + return; } - void GetTexLevelParameterfv_State(GLenum target, GLint level, GLenum pname, GLfloat* params) { - // ======================= Converting ================================ - TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + void* processedPixels = nullptr; + processedPixels = MG_Util::PixelStoreProcessor::ProcessTexturePixelsDataUnpack( + originalPixels, MG_State::pGLContext->GetPixelStoreParameters(true), textureInternalFormat, + textureInputFormat, texturePixelDataType, {width, height, 1}, false, imageSize); - // ===================== Error Checking ============================== - if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return; - if (!TextureImpl::ValidateTextureLevelNumber(level)) return; - if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return; - - // ======================= Processing ================================ - SharedPtr textureObject = nullptr; - if (TextureImpl::IsProxyTextureTarget(textureUploadingTarget)) { - textureObject = TextureImpl::pProxyTextureManager->GetProxyTextureObject(textureUploadingTarget); - } else { - auto activeUnit = - MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); - auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); - textureObject = bindingSlot.GetBoundObject(); + if (processedPixels && imageSize > 0) { + if (imageSize != internalBytes) { + MGLOG_W("TexImage2D_State: Processed pixel data size (%zu) does not match expected size (%zu). " + "This may indicate an alignment or processing issue.", + imageSize, internalBytes); } - if (!TextureImpl::ValidateTextureObject(textureObject)) return; + const SizeT copySize = std::min(imageSize, internalBytes); + DataPtr texelInput{processedPixels, copySize}; + textureMipmapObject->UpdateMipmapSubData(textureUploadingTarget, level, texelInput); + } - switch (pname) { - case GL_TEXTURE_WIDTH: - if (params) { - switch (textureObject->GetStorageType()) { - case TextureStorageType::Mipmap: { - const auto textureMipmapObject = - static_cast(textureObject.get()); - *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).x(); - break; - } - default: - THROW_UNIMPL_EXCEPTION; - } + free(processedPixels); + + MGLOG_D("%s: mark mip %d as dirty", __func__, level); + textureMipmapObject->MarkStorageDirty(textureUploadingTarget, level, true); + } + + void TexImage1D_State(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, + GLenum type, const GLvoid* pixels) { + // TODO: implement + THROW_UNIMPL_EXCEPTION; + } + + void TexBuffer_State(GLenum target, GLenum internalformat, GLuint buffer) { + // ======================= Converting ================================ + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); + TextureInternalFormat textureInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat); + + // ===================== Error Checking ============================== + if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return; + if (!TextureImpl::ValidateTextureInternalFormat(textureInternalFormat)) return; + // TODO: make sure `internalformat` is in one of supported format for TexBuffer + auto bufferObject = MG_State::pGLContext->GetBufferObject(buffer); + if (!bufferObject) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", __func__, + "`buffer` is not zero and is not the name of an existing buffer object.")); + return; + } + + // ======================= Processing ================================ + auto activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); + auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); + auto textureObject = bindingSlot.GetBoundObject(); + + // ===================== Error Checking ============================== + if (!TextureImpl::ValidateTextureObject(textureObject)) return; + if (textureObject->GetStorageType() != TextureStorageType::Buffer) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", __func__, + "The effective target of `texture` is not `GL_TEXTURE_BUFFER`.")); + return; + } + + // ======================= Processing ================================ + // Now we can rest assured, and down-cast texture object to texture buffer + auto* texBufferObject = static_cast(textureObject.get()); + auto& bufferSlot = texBufferObject->GetBufferBindingSlot(); + bufferSlot.Bind(bufferObject); + + texBufferObject->SetInternalFormat(textureInternalFormat); + } + + GLboolean IsTexture_State(GLuint texture) { + // ======================= Processing ================================ + if (!TextureImpl::ValidateTextureName(texture, true)) return GL_FALSE; + return MG_State::pGLContext->ValidateTextureObject(texture) ? GL_TRUE : GL_FALSE; + } + + void GetTexParameterIuiv_State(GLenum target, GLenum pname, GLuint* params) { + // TODO: implement + THROW_UNIMPL_EXCEPTION; + } + + void GetTexParameterIiv_State(GLenum target, GLenum pname, GLint* params) { + // TODO: implement + THROW_UNIMPL_EXCEPTION; + } + + void GetTexParameteriv_State(GLenum target, GLenum pname, GLint* params) { + // ======================= Converting ================================ + TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + + // ======================= Processing ================================ + SharedPtr textureObject = nullptr; + if (TextureImpl::IsProxyTextureTarget(textureUploadingTarget)) { + textureObject = TextureImpl::pProxyTextureManager->GetProxyTextureObject(textureUploadingTarget); + } else { + auto activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); + auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); + textureObject = bindingSlot.GetBoundObject(); + } + + if (!TextureImpl::ValidateTextureObject(textureObject)) return; + + switch (pname) { + case GL_TEXTURE_MAG_FILTER: + if (params) { + *params = MG_Util::ConvertSamplerFilterModeToGLEnum(textureObject->GetSamplerObject()->GetMagFilter(), + SamplerMipmapMode::None); + } + break; + case GL_TEXTURE_MIN_FILTER: + if (params) { + *params = MG_Util::ConvertSamplerFilterModeToGLEnum(textureObject->GetSamplerObject()->GetMinFilter(), + textureObject->GetSamplerObject()->GetMipmapMode()); + } + break; + case GL_TEXTURE_MIN_LOD: + if (params) { + *params = static_cast(textureObject->GetSamplerObject()->GetMinLod()); + } + break; + case GL_TEXTURE_MAX_LOD: + if (params) { + *params = static_cast(textureObject->GetSamplerObject()->GetMaxLod()); + } + break; + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_BORDER_COLOR: + break; // TODO + case GL_TEXTURE_WRAP_S: + if (params) { + *params = MG_Util::ConvertSamplerWrapModeToGLEnum(textureObject->GetSamplerObject()->GetWrapS()); + } + break; + case GL_TEXTURE_WRAP_T: + if (params) { + *params = MG_Util::ConvertSamplerWrapModeToGLEnum(textureObject->GetSamplerObject()->GetWrapT()); + } + break; + case GL_TEXTURE_WRAP_R: + if (params) { + *params = MG_Util::ConvertSamplerWrapModeToGLEnum(textureObject->GetSamplerObject()->GetWrapR()); + } + break; + case GL_TEXTURE_COMPARE_MODE: + if (params) { + *params = + MG_Util::ConvertSamplerCompareModeToGLEnum(textureObject->GetSamplerObject()->GetCompareMode()); + } + break; + case GL_TEXTURE_COMPARE_FUNC: + if (params) { + *params = MG_Util::ConvertSamplerCompareFuncToGLEnum( + textureObject->GetSamplerObject()->GetSamplerCompareFunc()); + } + break; + default: + MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", "GetTexParameteriv_State", + "pname is not a valid texture parameter.")); + return; + } + } + + void GetTexParameterfv_State(GLenum target, GLenum pname, GLfloat* params) { + // ======================= Converting ================================ + TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + + // ======================= Processing ================================ + SharedPtr textureObject = nullptr; + if (TextureImpl::IsProxyTextureTarget(textureUploadingTarget)) { + textureObject = TextureImpl::pProxyTextureManager->GetProxyTextureObject(textureUploadingTarget); + } else { + auto activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); + auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); + textureObject = bindingSlot.GetBoundObject(); + } + + if (!TextureImpl::ValidateTextureObject(textureObject)) return; + + switch (pname) { + case GL_TEXTURE_MAG_FILTER: + if (params) { + *params = MG_Util::ConvertSamplerFilterModeToGLEnum(textureObject->GetSamplerObject()->GetMagFilter(), + SamplerMipmapMode::None); + } + break; + case GL_TEXTURE_MIN_FILTER: + if (params) { + *params = MG_Util::ConvertSamplerFilterModeToGLEnum(textureObject->GetSamplerObject()->GetMinFilter(), + textureObject->GetSamplerObject()->GetMipmapMode()); + } + break; + case GL_TEXTURE_MIN_LOD: + if (params) { + *params = static_cast(textureObject->GetSamplerObject()->GetMinLod()); + } + break; + case GL_TEXTURE_MAX_LOD: + if (params) { + *params = static_cast(textureObject->GetSamplerObject()->GetMaxLod()); + } + break; + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: + case GL_TEXTURE_SWIZZLE_RGBA: + case GL_TEXTURE_BORDER_COLOR: + break; // TODO + case GL_TEXTURE_WRAP_S: + if (params) { + *params = MG_Util::ConvertSamplerWrapModeToGLEnum(textureObject->GetSamplerObject()->GetWrapS()); + } + break; + case GL_TEXTURE_WRAP_T: + if (params) { + *params = MG_Util::ConvertSamplerWrapModeToGLEnum(textureObject->GetSamplerObject()->GetWrapT()); + } + break; + case GL_TEXTURE_WRAP_R: + if (params) { + *params = MG_Util::ConvertSamplerWrapModeToGLEnum(textureObject->GetSamplerObject()->GetWrapR()); + } + break; + case GL_TEXTURE_COMPARE_MODE: + if (params) { + *params = + MG_Util::ConvertSamplerCompareModeToGLEnum(textureObject->GetSamplerObject()->GetCompareMode()); + } + break; + case GL_TEXTURE_COMPARE_FUNC: + if (params) { + *params = MG_Util::ConvertSamplerCompareFuncToGLEnum( + textureObject->GetSamplerObject()->GetSamplerCompareFunc()); + } + break; + default: + MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", "GetTexParameterfv_State", + "pname is not a valid texture parameter.")); + return; + } + } + + void GetTexLevelParameteriv_State(GLenum target, GLint level, GLenum pname, GLint* params) { + MGLOG_D("GetTexLevelParameteriv_State called"); + // ======================= Converting ================================ + TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + + // ===================== Error Checking ============================== + if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return; + if (!TextureImpl::ValidateTextureLevelNumber(level)) return; + if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return; + + // ======================= Processing ================================ + SharedPtr textureObject = nullptr; + + if (TextureImpl::IsProxyTextureTarget(textureUploadingTarget)) { + textureObject = TextureImpl::pProxyTextureManager->GetProxyTextureObject(textureUploadingTarget); + } else { + auto activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); + auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); + textureObject = bindingSlot.GetBoundObject(); + } + + if (!TextureImpl::ValidateTextureObject(textureObject)) return; + + switch (pname) { + case GL_TEXTURE_WIDTH: + if (params) { + switch (textureObject->GetStorageType()) { + case TextureStorageType::Mipmap: { + const auto textureMipmapObject = + static_cast(textureObject.get()); + *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).x(); + break; } - break; - case GL_TEXTURE_HEIGHT: - if (params) { - switch (textureObject->GetStorageType()) { - case TextureStorageType::Mipmap: { - const auto textureMipmapObject = - static_cast(textureObject.get()); - *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).y(); - break; - } - default: - THROW_UNIMPL_EXCEPTION; - } + default: + THROW_UNIMPL_EXCEPTION; } - break; - case GL_TEXTURE_DEPTH: - if (params) { - switch (textureObject->GetStorageType()) { - case TextureStorageType::Mipmap: { - const auto textureMipmapObject = - static_cast(textureObject.get()); - *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).z(); - break; - } - default: - THROW_UNIMPL_EXCEPTION; - } + } + break; + case GL_TEXTURE_HEIGHT: + if (params) { + switch (textureObject->GetStorageType()) { + case TextureStorageType::Mipmap: { + const auto textureMipmapObject = + static_cast(textureObject.get()); + *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).y(); + break; } - break; - case GL_TEXTURE_INTERNAL_FORMAT: - if (params) { - *params = MG_Util::ConvertTextureInternalFormatToGLEnum(textureObject->GetFormat()); + default: + THROW_UNIMPL_EXCEPTION; } - break; - case GL_TEXTURE_RED_TYPE: - case GL_TEXTURE_GREEN_TYPE: - case GL_TEXTURE_BLUE_TYPE: - case GL_TEXTURE_ALPHA_TYPE: - case GL_TEXTURE_DEPTH_TYPE: - case GL_TEXTURE_RED_SIZE: - case GL_TEXTURE_GREEN_SIZE: - case GL_TEXTURE_BLUE_SIZE: - case GL_TEXTURE_ALPHA_SIZE: - case GL_TEXTURE_DEPTH_SIZE: - case GL_TEXTURE_COMPRESSED: - case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: - break; // TODO - default: - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", "GetTexLevelParameterfv_State", - "pname is not a valid texture level parameter.")); - return; } - } - - void GetCompressedTexImage_State(GLenum target, GLint level, void* img) { - // TODO: implement - } - - void GenTextures_State(GLsizei n, GLuint* textures) { - // ===================== Error Checking ============================== - if (n < 0) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, - MakeShared("MG_Impl/GLImpl", "GenTextures_State", "n must be non-negative")); - return; + break; + case GL_TEXTURE_DEPTH: + if (params) { + switch (textureObject->GetStorageType()) { + case TextureStorageType::Mipmap: { + const auto textureMipmapObject = + static_cast(textureObject.get()); + *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).z(); + break; + } + default: + THROW_UNIMPL_EXCEPTION; + } } - - // ======================= Processing ================================ - auto textureNames = MG_State::pGLContext->GenTextureNames(n); - Copy(textureNames.data(), textures, textureNames.size()); - } - - void DeleteTextures_State(GLsizei n, const GLuint* textures) { - // ===================== Error Checking ============================== - if (n < 0) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, - MakeShared("MG_Impl/GLImpl", "DeleteTextures_State", "n must be non-negative.")); - return; + break; + case GL_TEXTURE_INTERNAL_FORMAT: + if (params) { + *params = MG_Util::ConvertTextureInternalFormatToGLEnum(textureObject->GetFormat()); } + break; + case GL_TEXTURE_RED_TYPE: + case GL_TEXTURE_GREEN_TYPE: + case GL_TEXTURE_BLUE_TYPE: + case GL_TEXTURE_ALPHA_TYPE: + case GL_TEXTURE_DEPTH_TYPE: + case GL_TEXTURE_RED_SIZE: + case GL_TEXTURE_GREEN_SIZE: + case GL_TEXTURE_BLUE_SIZE: + case GL_TEXTURE_ALPHA_SIZE: + case GL_TEXTURE_DEPTH_SIZE: + case GL_TEXTURE_COMPRESSED: + case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: + break; // TODO + default: + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, MakeShared("MG_Impl/GLImpl", "GetTexLevelParameteriv_State", + "pname is not a valid texture level parameter.")); + return; + } + } - if (!textures) { - MG_State::pGLContext->RecordError(ErrorCode::InvalidValue, - MakeShared("MG_Impl/GLImpl", "DeleteTextures_State", - "Texture names array cannot be null.")); - return; + void GetTexLevelParameterfv_State(GLenum target, GLint level, GLenum pname, GLfloat* params) { + // ======================= Converting ================================ + TextureUploadTarget textureUploadingTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + + // ===================== Error Checking ============================== + if (!TextureImpl::ValidateTextureUploadTarget(textureUploadingTarget)) return; + if (!TextureImpl::ValidateTextureLevelNumber(level)) return; + if (!TextureImpl::ValidateTextureLevelWithUploadTarget(textureUploadingTarget, level)) return; + + // ======================= Processing ================================ + SharedPtr textureObject = nullptr; + if (TextureImpl::IsProxyTextureTarget(textureUploadingTarget)) { + textureObject = TextureImpl::pProxyTextureManager->GetProxyTextureObject(textureUploadingTarget); + } else { + auto activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); + auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); + textureObject = bindingSlot.GetBoundObject(); + } + + if (!TextureImpl::ValidateTextureObject(textureObject)) return; + + switch (pname) { + case GL_TEXTURE_WIDTH: + if (params) { + switch (textureObject->GetStorageType()) { + case TextureStorageType::Mipmap: { + const auto textureMipmapObject = + static_cast(textureObject.get()); + *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).x(); + break; + } + default: + THROW_UNIMPL_EXCEPTION; + } } - - // ======================= Processing ================================ - for (SizeT i = 0; i < static_cast(n); ++i) { - Uint textureName = textures[i]; - if (textureName == 0) continue; - if (!TextureImpl::ValidateTextureName(textureName, true)) continue; - MG_State::pGLContext->MarkTextureObjectForDeletion(textureName); + break; + case GL_TEXTURE_HEIGHT: + if (params) { + switch (textureObject->GetStorageType()) { + case TextureStorageType::Mipmap: { + const auto textureMipmapObject = + static_cast(textureObject.get()); + *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).y(); + break; + } + default: + THROW_UNIMPL_EXCEPTION; + } } - } - - void CopyTexSubImage3D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, - GLint y, GLsizei width, GLsizei height) { - // TODO: implement - } - - void CopyTexSubImage2D_Backend(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, - GLsizei width, GLsizei height) { -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); -#endif - } - - void CopyTexSubImage1D_State(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { - // TODO: implement - } - - void CopyTexImage2D_State(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, - GLsizei height, GLint border) { - auto internalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat); - const auto& currentReadFBO = - MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); - if (!currentReadFBO) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared( - "MG_Impl/GLImpl", "CopyTexImage2D_State", - "No framebuffer is currently bound to the GL_READ_FRAMEBUFFER target.")); - return; + break; + case GL_TEXTURE_DEPTH: + if (params) { + switch (textureObject->GetStorageType()) { + case TextureStorageType::Mipmap: { + const auto textureMipmapObject = + static_cast(textureObject.get()); + *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).z(); + break; + } + default: + THROW_UNIMPL_EXCEPTION; + } } + break; + case GL_TEXTURE_INTERNAL_FORMAT: + if (params) { + *params = MG_Util::ConvertTextureInternalFormatToGLEnum(textureObject->GetFormat()); + } + break; + case GL_TEXTURE_RED_TYPE: + case GL_TEXTURE_GREEN_TYPE: + case GL_TEXTURE_BLUE_TYPE: + case GL_TEXTURE_ALPHA_TYPE: + case GL_TEXTURE_DEPTH_TYPE: + case GL_TEXTURE_RED_SIZE: + case GL_TEXTURE_GREEN_SIZE: + case GL_TEXTURE_BLUE_SIZE: + case GL_TEXTURE_ALPHA_SIZE: + case GL_TEXTURE_DEPTH_SIZE: + case GL_TEXTURE_COMPRESSED: + case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: + break; // TODO + default: + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, MakeShared("MG_Impl/GLImpl", "GetTexLevelParameterfv_State", + "pname is not a valid texture level parameter.")); + return; + } + } - Bool isDepth = MG_Util::IsDepthFormatInternalFormat(internalFormat); - Bool isStencil = MG_Util::IsStencilFormatInternalFormat(internalFormat); - TextureInternalFormat srcInternalFormat = TextureInternalFormat::Unknown; + void GetCompressedTexImage_State(GLenum target, GLint level, void* img) { + // TODO: implement + } + + void GenTextures_State(GLsizei n, GLuint* textures) { + // ===================== Error Checking ============================== + if (n < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", "GenTextures_State", "n must be non-negative")); + return; + } + + // ======================= Processing ================================ + auto textureNames = MG_State::pGLContext->GenTextureNames(n); + Copy(textureNames.data(), textures, textureNames.size()); + } + + void DeleteTextures_State(GLsizei n, const GLuint* textures) { + // ===================== Error Checking ============================== + if (n < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", "DeleteTextures_State", "n must be non-negative.")); + return; + } + + if (!textures) { + MG_State::pGLContext->RecordError(ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", "DeleteTextures_State", + "Texture names array cannot be null.")); + return; + } + + // ======================= Processing ================================ + for (SizeT i = 0; i < static_cast(n); ++i) { + Uint textureName = textures[i]; + if (textureName == 0) continue; + if (!TextureImpl::ValidateTextureName(textureName, true)) continue; + MG_State::pGLContext->MarkTextureObjectForDeletion(textureName); + } + } + + void CopyTexSubImage3D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, + GLint y, GLsizei width, GLsizei height) { + // TODO: implement + } + + void CopyTexSubImage2D_Backend(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height) { + MG_Backend::gBackendFunctionsTable.GL.CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + } + + void CopyTexSubImage1D_State(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { + // TODO: implement + } + + void CopyTexImage2D_State(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, + GLsizei height, GLint border) { + auto internalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat); + const auto& currentReadFBO = + MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject(); + if (!currentReadFBO) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "CopyTexImage2D_State", + "No framebuffer is currently bound to the GL_READ_FRAMEBUFFER target.")); + return; + } + + Bool isDepth = MG_Util::IsDepthFormatInternalFormat(internalFormat); + Bool isStencil = MG_Util::IsStencilFormatInternalFormat(internalFormat); + TextureInternalFormat srcInternalFormat = TextureInternalFormat::Unknown; #define GET_SRC_INTERNAL_FORMAT(AttachmentType) \ const auto& srcAttachment = currentReadFBO->GetAttachment(AttachmentType); \ if (srcAttachment.IsTexture()) { \ @@ -1255,427 +1234,421 @@ namespace MobileGL { "The attachment specified by the read buffer is incomplete.")); \ return; \ } - if (isDepth) { - GET_SRC_INTERNAL_FORMAT(FramebufferAttachmentType::Depth); - } else if (isStencil) { - GET_SRC_INTERNAL_FORMAT(FramebufferAttachmentType::Stencil); - } else { - const auto& readBufferType = currentReadFBO->GetReadBuffer(); - GET_SRC_INTERNAL_FORMAT(readBufferType); - } - - if (!TextureImpl::ValidateBaseInternalFormatMatch(internalFormat, srcInternalFormat)) - THROW_UNIMPL_EXCEPTION; - - GLenum outInternalFormat = MG_Util::ConvertTextureInternalFormatToGLEnum(srcInternalFormat); - GLenum realInternalFormat = GL_RGBA8; - GLenum format = GL_DEPTH_COMPONENT; - GLenum type = GL_UNSIGNED_INT; - MG_Util::TextureFormatProcessor::NormalizePixelFormat( - outInternalFormat, PixelFormatNormalizeOptionBit::None, &realInternalFormat, &format, &type); - const auto pixelUnpackBufferObject = - MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject(); - TexImage2D_State(target, level, realInternalFormat, width, height, border, format, type, nullptr); - MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).Bind(pixelUnpackBufferObject); + if (isDepth) { + GET_SRC_INTERNAL_FORMAT(FramebufferAttachmentType::Depth); + } else if (isStencil) { + GET_SRC_INTERNAL_FORMAT(FramebufferAttachmentType::Stencil); + } else { + const auto& readBufferType = currentReadFBO->GetReadBuffer(); + GET_SRC_INTERNAL_FORMAT(readBufferType); } - void CopyTexImage2D_Backend(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, - GLsizei height, GLint border) { -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::CopyTexImage2D(target, level, internalformat, x, y, width, height, border); -#endif + if (!TextureImpl::ValidateBaseInternalFormatMatch(internalFormat, srcInternalFormat)) THROW_UNIMPL_EXCEPTION; + + GLenum outInternalFormat = MG_Util::ConvertTextureInternalFormatToGLEnum(srcInternalFormat); + GLenum realInternalFormat = GL_RGBA8; + GLenum format = GL_DEPTH_COMPONENT; + GLenum type = GL_UNSIGNED_INT; + MG_Util::TextureFormatProcessor::NormalizePixelFormat(outInternalFormat, PixelFormatNormalizeOptionBit::None, + &realInternalFormat, &format, &type); + const auto pixelUnpackBufferObject = + MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).GetBoundObject(); + TexImage2D_State(target, level, realInternalFormat, width, height, border, format, type, nullptr); + MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelUnpack).Bind(pixelUnpackBufferObject); + } + + void CopyTexImage2D_Backend(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, + GLsizei height, GLint border) { + MG_Backend::gBackendFunctionsTable.GL.CopyTexImage2D(target, level, internalformat, x, y, width, height, + border); + } + + void CopyTexImage1D_State(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, + GLint border) { + // TODO: implement + THROW_UNIMPL_EXCEPTION; + } + + void CompressedTexSubImage3D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, + const void* data) { + // TODO: implement + THROW_UNIMPL_EXCEPTION; + } + + void CompressedTexSubImage2D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLsizei imageSize, const void* data) { + // TODO: implement + THROW_UNIMPL_EXCEPTION; + } + + void CompressedTexSubImage1D_State(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, + GLsizei imageSize, const void* data) { + // TODO: implement + THROW_UNIMPL_EXCEPTION; + } + + void CompressedTexImage3D_State(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLsizei imageSize, const void* data) { + // TODO: implement + THROW_UNIMPL_EXCEPTION; + } + + void CompressedTexImage2D_State(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, + GLint border, GLsizei imageSize, const void* data) { + // TODO: implement + THROW_UNIMPL_EXCEPTION; + } + + void CompressedTexImage1D_State(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, + GLsizei imageSize, const void* data) { + // TODO: implement + THROW_UNIMPL_EXCEPTION; + } + + void BindTexture_State(GLenum target, GLuint texture) { + // TODO: deal with condition where texture == 0 + MGLOG_D("BindTexture_State called with target: 0x%X, texture: %u", target, texture); + // ======================= Converting ================================ + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + + // ===================== Error Checking ============================== + if (!TextureImpl::ValidateTextureName(texture, true)) return; + if (!TextureImpl::ValidateTextureTarget(textureTarget)) return; + + // ======================= Processing ================================ + auto textureObject = MG_State::pGLContext->GetTextureObject(texture); + + // ===================== Error Checking ============================== + if (!TextureImpl::ValidateTextureTargetUniformity(textureObject, textureTarget)) return; + + // ======================= Processing ================================ + if (!textureObject) { + textureObject = MG_State::pGLContext->CreateTextureObject(texture, textureTarget); } - void CopyTexImage1D_State(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, - GLint border) { - // TODO: implement - THROW_UNIMPL_EXCEPTION; + auto& currentUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); + auto& bindingSlot = currentUnit.GetBindingSlot(textureTarget); + bindingSlot.Bind(textureObject); + } + + void ActiveTexture_State(GLenum texture) { + // ===================== Error Checking ============================== + if (texture < GL_TEXTURE0 || texture > GL_TEXTURE31) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared( + "MG_Impl/GLImpl", "ActiveTexture_State", + std::format("Texture must be one of GL_TEXTUREi, where i is in the range 0 to 31, but got " + "invalid enum: 0x{:X}, which may stand for unit {}.", + texture, texture - GL_TEXTURE0))); + return; } - void CompressedTexSubImage3D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, GLenum format, - GLsizei imageSize, const void* data) { - // TODO: implement - THROW_UNIMPL_EXCEPTION; + // ======================= Processing ================================ + MG_State::pGLContext->SetActiveTextureUnit((Int)texture - GL_TEXTURE0); + } + + void GetTexImage_Backend(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) { + MG_Backend::gBackendFunctionsTable.GL.GetTexImage(target, level, format, type, pixels); + } + + // Add to GL_Texture.cpp + void GetTexImage_State(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) { + // ======================= Converting ================================ + TextureUploadTarget textureUploadTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); + TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); + TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format); + TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type); + + // ===================== Error Checking ============================== + // Validate target + if (!TextureImpl::ValidateTextureUploadTarget(textureUploadTarget)) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", "GetTexImage_State", "Invalid texture target")); + return; } - void CompressedTexSubImage2D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, - GLsizei height, GLenum format, GLsizei imageSize, const void* data) { - // TODO: implement - THROW_UNIMPL_EXCEPTION; + // Validate level + if (level < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", "GetTexImage_State", "Level must be non-negative")); + return; } - void CompressedTexSubImage1D_State(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, - GLsizei imageSize, const void* data) { - // TODO: implement - THROW_UNIMPL_EXCEPTION; + // Validate format + if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", "GetTexImage_State", "Invalid format")); + return; } - void CompressedTexImage3D_State(GLenum target, GLint level, GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, - const void* data) { - // TODO: implement - THROW_UNIMPL_EXCEPTION; + // Validate type + if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", "GetTexImage_State", "Invalid pixel data type")); + return; } - void CompressedTexImage2D_State(GLenum target, GLint level, GLenum internalformat, GLsizei width, - GLsizei height, GLint border, GLsizei imageSize, const void* data) { - // TODO: implement - THROW_UNIMPL_EXCEPTION; + // Get texture object + SharedPtr textureObject = nullptr; + if (TextureImpl::IsProxyTextureTarget(textureUploadTarget)) { + textureObject = TextureImpl::pProxyTextureManager->GetProxyTextureObject(textureUploadTarget); + } else { + auto activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); + auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); + textureObject = bindingSlot.GetBoundObject(); } - void CompressedTexImage1D_State(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, - GLsizei imageSize, const void* data) { - // TODO: implement - THROW_UNIMPL_EXCEPTION; + if (!TextureImpl::ValidateTextureObject(textureObject)) { + MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "GetTexImage_State", + "No valid texture bound to target")); + return; } - void BindTexture_State(GLenum target, GLuint texture) { - // TODO: deal with condition where texture == 0 - MGLOG_D("BindTexture_State called with target: 0x%X, texture: %u", target, texture); - // ======================= Converting ================================ - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); - - // ===================== Error Checking ============================== - if (!TextureImpl::ValidateTextureName(texture, true)) return; - if (!TextureImpl::ValidateTextureTarget(textureTarget)) return; - - // ======================= Processing ================================ - auto textureObject = MG_State::pGLContext->GetTextureObject(texture); - - // ===================== Error Checking ============================== - if (!TextureImpl::ValidateTextureTargetUniformity(textureObject, textureTarget)) return; - - // ======================= Processing ================================ - if (!textureObject) { - textureObject = MG_State::pGLContext->CreateTextureObject(texture, textureTarget); - } - - auto& currentUnit = - MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); - auto& bindingSlot = currentUnit.GetBindingSlot(textureTarget); - bindingSlot.Bind(textureObject); + // Check texture completeness + if (!textureObject->IsComplete()) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "GetTexImage_State", "Texture is incomplete")); + return; } - void ActiveTexture_State(GLenum texture) { - // ===================== Error Checking ============================== - if (texture < GL_TEXTURE0 || texture > GL_TEXTURE31) { + // Check PBO state + const auto& pixelPackBufferObject = + MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); + + if (pixelPackBufferObject) { + // Check if PBO is mapped + if (pixelPackBufferObject->IsMapped()) { MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared( - "MG_Impl/GLImpl", "ActiveTexture_State", - std::format("Texture must be one of GL_TEXTUREi, where i is in the range 0 to 31, but got " - "invalid enum: 0x{:X}, which may stand for unit {}.", - texture, texture - GL_TEXTURE0))); + ErrorCode::InvalidOperation, MakeShared("MG_Impl/GLImpl", "GetTexImage_State", + "Pixel pack buffer is currently mapped")); return; } - // ======================= Processing ================================ - MG_State::pGLContext->SetActiveTextureUnit(texture - GL_TEXTURE0); - } - - void GetTexImage_Backend(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) { -#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES - MG_Backend::DirectGLES::GetTexImage(target, level, format, type, pixels); -#endif - } - - // Add to GL_Texture.cpp - void GetTexImage_State(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) { - // ======================= Converting ================================ - TextureUploadTarget textureUploadTarget = MG_Util::ConvertGLEnumToTextureUploadTarget(target); - TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target); - TextureInputFormat textureInputFormat = MG_Util::ConvertGLEnumToTextureInputFormat(format); - TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type); - - // ===================== Error Checking ============================== - // Validate target - if (!TextureImpl::ValidateTextureUploadTarget(textureUploadTarget)) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", "GetTexImage_State", "Invalid texture target")); - return; - } - - // Validate level - if (level < 0) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidValue, - MakeShared("MG_Impl/GLImpl", "GetTexImage_State", "Level must be non-negative")); - return; - } - - // Validate format - if (!TextureImpl::ValidateTextureInputFormat(textureInputFormat)) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", "GetTexImage_State", "Invalid format")); - return; - } - - // Validate type - if (!TextureImpl::ValidateTexturePixelDataType(texturePixelDataType)) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidEnum, - MakeShared("MG_Impl/GLImpl", "GetTexImage_State", "Invalid pixel data type")); - return; - } - - // Get texture object - SharedPtr textureObject = nullptr; - if (TextureImpl::IsProxyTextureTarget(textureUploadTarget)) { - textureObject = TextureImpl::pProxyTextureManager->GetProxyTextureObject(textureUploadTarget); - } else { - auto activeUnit = - MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit()); - auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget); - textureObject = bindingSlot.GetBoundObject(); - } - - if (!TextureImpl::ValidateTextureObject(textureObject)) { - MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "GetTexImage_State", - "No valid texture bound to target")); - return; - } - - // Check texture completeness - if (!textureObject->IsComplete()) { + // Check alignment + const SizeT typeSize = MG_Util::GetTexturePixelDataTypeSize(texturePixelDataType); + if (reinterpret_cast(pixels) % typeSize != 0) { MG_State::pGLContext->RecordError( ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "GetTexImage_State", "Texture is incomplete")); + MakeShared("MG_Impl/GLImpl", "GetTexImage_State", + "Pixel data not aligned for pixel pack buffer")); return; } + } - // Check PBO state - const auto& pixelPackBufferObject = - MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::PixelPack).GetBoundObject(); - - if (pixelPackBufferObject) { - // Check if PBO is mapped - if (pixelPackBufferObject->IsMapped()) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "GetTexImage_State", - "Pixel pack buffer is currently mapped")); - return; - } - - // Check alignment - const SizeT typeSize = MG_Util::GetTexturePixelDataTypeSize(texturePixelDataType); - if (reinterpret_cast(pixels) % typeSize != 0) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "GetTexImage_State", - "Pixel data not aligned for pixel pack buffer")); - return; - } - } - - // Special case for depth/stencil - if (textureInputFormat == TextureInputFormat::StencilIndex) { - if (textureObject->GetFormat() != TextureInternalFormat::DepthStencil && - textureObject->GetFormat() != TextureInternalFormat::Depth24Stencil8 && - textureObject->GetFormat() != TextureInternalFormat::Depth32FStencil8) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "GetTexImage_State", - "No stencil buffer for stencil index format")); - return; - } - } - - // Check for multisampling - if (textureObject->GetStorageType() == TextureStorageType::Mipmap) { - auto mipmapObject = static_cast(textureObject.get()); - if (mipmapObject->GetMipmapLevelCount() > 1) { - MG_State::pGLContext->RecordError( - ErrorCode::InvalidOperation, - MakeShared("MG_Impl/GLImpl", "GetTexImage_State", - "Multisampled textures not supported for GetTexImage")); - return; - } + // Special case for depth/stencil + if (textureInputFormat == TextureInputFormat::StencilIndex) { + if (textureObject->GetFormat() != TextureInternalFormat::DepthStencil && + textureObject->GetFormat() != TextureInternalFormat::Depth24Stencil8 && + textureObject->GetFormat() != TextureInternalFormat::Depth32FStencil8) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "GetTexImage_State", + "No stencil buffer for stencil index format")); + return; } } - /* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */ - void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) { - GetTexImage_State(target, level, format, type, pixels); - GetTexImage_Backend(target, level, format, type, pixels); + // Check for multisampling + if (textureObject->GetStorageType() == TextureStorageType::Mipmap) { + auto mipmapObject = static_cast(textureObject.get()); + if (mipmapObject->GetMipmapLevelCount() > 1) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeShared("MG_Impl/GLImpl", "GetTexImage_State", + "Multisampled textures not supported for GetTexImage")); + return; + } } + } - void TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) { - TexSubImage3D_State(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); - } + /* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */ + void GenerateMipmap(GLenum target) { + GenerateMipmap_Backend(target); + } - void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLenum type, const void* pixels) { - TexSubImage2D_State(target, level, xoffset, yoffset, width, height, format, type, pixels); - } + void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels) { + GetTexImage_State(target, level, format, type, pixels); + GetTexImage_Backend(target, level, format, type, pixels); + } - void TexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, - const GLvoid* pixels) { - TexSubImage1D_State(target, level, xoffset, width, format, type, pixels); - } + void TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) { + TexSubImage3D_State(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + } - void TexParameterf(GLenum target, GLenum pname, GLfloat param) { - TexParameterf_State(target, pname, param); - } + void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLenum type, const void* pixels) { + TexSubImage2D_State(target, level, xoffset, yoffset, width, height, format, type, pixels); + } - void TexParameteri(GLenum target, GLenum pname, GLint param) { - TexParameteri_State(target, pname, param); - } + void TexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, + const GLvoid* pixels) { + TexSubImage1D_State(target, level, xoffset, width, format, type, pixels); + } - void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) { - TexParameterfv_State(target, pname, params); - } + void TexParameterf(GLenum target, GLenum pname, GLfloat param) { + TexParameterf_State(target, pname, param); + } - void TexParameteriv(GLenum target, GLenum pname, const GLint* params) { - TexParameteriv_State(target, pname, params); - } + void TexParameteri(GLenum target, GLenum pname, GLint param) { + TexParameteri_State(target, pname, param); + } - void TexParameterIiv(GLenum target, GLenum pname, const GLint* params) { - TexParameterIiv_State(target, pname, params); - } + void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) { + TexParameterfv_State(target, pname, params); + } - void TexParameterIuiv(GLenum target, GLenum pname, const GLuint* params) { - TexParameterIuiv_State(target, pname, params); - } + void TexParameteriv(GLenum target, GLenum pname, const GLint* params) { + TexParameteriv_State(target, pname, params); + } - void TexImage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, - GLsizei depth, GLboolean fixedsamplelocations) { - TexImage3DMultisample_State(target, samples, internalformat, width, height, depth, fixedsamplelocations); - } + void TexParameterIiv(GLenum target, GLenum pname, const GLint* params) { + TexParameterIiv_State(target, pname, params); + } - void TexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, - GLboolean fixedsamplelocations) { - TexImage2DMultisample_State(target, samples, internalformat, width, height, fixedsamplelocations); - } + void TexParameterIuiv(GLenum target, GLenum pname, const GLuint* params) { + TexParameterIuiv_State(target, pname, params); + } - void TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, - GLint border, GLenum format, GLenum type, const void* pixels) { - TexImage3D_State(target, level, internalformat, width, height, depth, border, format, type, pixels); - } + void TexImage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLboolean fixedsamplelocations) { + TexImage3DMultisample_State(target, samples, internalformat, width, height, depth, fixedsamplelocations); + } - void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, const void* pixels) { - TexImage2D_State(target, level, internalformat, width, height, border, format, type, pixels); - } + void TexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, + GLboolean fixedsamplelocations) { + TexImage2DMultisample_State(target, samples, internalformat, width, height, fixedsamplelocations); + } - void TexImage1D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, - GLenum type, const GLvoid* pixels) { - TexImage1D_State(target, level, internalFormat, width, border, format, type, pixels); - } + void TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum format, GLenum type, const void* pixels) { + TexImage3D_State(target, level, internalformat, width, height, depth, border, format, type, pixels); + } - void TexBuffer(GLenum target, GLenum internalformat, GLuint buffer) { - TexBuffer_State(target, internalformat, buffer); - } + void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, const void* pixels) { + TexImage2D_State(target, level, internalformat, width, height, border, format, type, pixels); + } - GLboolean IsTexture(GLuint texture) { - return IsTexture_State(texture); - } + void TexImage1D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, + GLenum type, const GLvoid* pixels) { + TexImage1D_State(target, level, internalFormat, width, border, format, type, pixels); + } - void GetTexParameterIuiv(GLenum target, GLenum pname, GLuint* params) { - GetTexParameterIuiv_State(target, pname, params); - } + void TexBuffer(GLenum target, GLenum internalformat, GLuint buffer) { + TexBuffer_State(target, internalformat, buffer); + } - void GetTexParameterIiv(GLenum target, GLenum pname, GLint* params) { - GetTexParameterIiv_State(target, pname, params); - } + GLboolean IsTexture(GLuint texture) { + return IsTexture_State(texture); + } - void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) { - GetTexParameteriv_State(target, pname, params); - } + void GetTexParameterIuiv(GLenum target, GLenum pname, GLuint* params) { + GetTexParameterIuiv_State(target, pname, params); + } - void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) { - GetTexParameterfv_State(target, pname, params); - } + void GetTexParameterIiv(GLenum target, GLenum pname, GLint* params) { + GetTexParameterIiv_State(target, pname, params); + } - void GetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params) { - GetTexLevelParameteriv_State(target, level, pname, params); - } + void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) { + GetTexParameteriv_State(target, pname, params); + } - void GetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params) { - GetTexLevelParameterfv_State(target, level, pname, params); - } + void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) { + GetTexParameterfv_State(target, pname, params); + } - void GetCompressedTexImage(GLenum target, GLint level, void* img) { - GetCompressedTexImage_State(target, level, img); - } + void GetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params) { + GetTexLevelParameteriv_State(target, level, pname, params); + } - void GenTextures(GLsizei n, GLuint* textures) { - GenTextures_State(n, textures); - } + void GetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params) { + GetTexLevelParameterfv_State(target, level, pname, params); + } - void DeleteTextures(GLsizei n, const GLuint* textures) { - DeleteTextures_State(n, textures); - } + void GetCompressedTexImage(GLenum target, GLint level, void* img) { + GetCompressedTexImage_State(target, level, img); + } - void CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, - GLint y, GLsizei width, GLsizei height) { - CopyTexSubImage3D_State(target, level, xoffset, yoffset, zoffset, x, y, width, height); - } + void GenTextures(GLsizei n, GLuint* textures) { + GenTextures_State(n, textures); + } - void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, - GLsizei width, GLsizei height) { - CopyTexSubImage2D_Backend(target, level, xoffset, yoffset, x, y, width, height); - } + void DeleteTextures(GLsizei n, const GLuint* textures) { + DeleteTextures_State(n, textures); + } - void CopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { - CopyTexSubImage1D_State(target, level, xoffset, x, y, width); - } + void CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, + GLsizei width, GLsizei height) { + CopyTexSubImage3D_State(target, level, xoffset, yoffset, zoffset, x, y, width, height); + } - void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, - GLsizei height, GLint border) { - CopyTexImage2D_State(target, level, internalformat, x, y, width, height, border); - CopyTexImage2D_Backend(target, level, internalformat, x, y, width, height, border); - } + void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, + GLsizei height) { + CopyTexSubImage2D_Backend(target, level, xoffset, yoffset, x, y, width, height); + } - void CopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, - GLint border) { - CopyTexImage1D_State(target, level, internalformat, x, y, width, border); - } + void CopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { + CopyTexSubImage1D_State(target, level, xoffset, x, y, width); + } - void CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, - const void* data) { - CompressedTexSubImage3D_State(target, level, xoffset, yoffset, zoffset, width, height, depth, format, - imageSize, data); - } + void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, + GLsizei height, GLint border) { + CopyTexImage2D_State(target, level, internalformat, x, y, width, height, border); + CopyTexImage2D_Backend(target, level, internalformat, x, y, width, height, border); + } - void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, - GLsizei height, GLenum format, GLsizei imageSize, const void* data) { - CompressedTexSubImage2D_State(target, level, xoffset, yoffset, width, height, format, imageSize, data); - } + void CopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, + GLint border) { + CopyTexImage1D_State(target, level, internalformat, x, y, width, border); + } - void CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, - GLsizei imageSize, const void* data) { - CompressedTexSubImage1D_State(target, level, xoffset, width, format, imageSize, data); - } + void CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data) { + CompressedTexSubImage3D_State(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, + data); + } - void CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, - GLsizei depth, GLint border, GLsizei imageSize, const void* data) { - CompressedTexImage3D_State(target, level, internalformat, width, height, depth, border, imageSize, data); - } + void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLsizei imageSize, const void* data) { + CompressedTexSubImage2D_State(target, level, xoffset, yoffset, width, height, format, imageSize, data); + } - void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, - GLint border, GLsizei imageSize, const void* data) { - CompressedTexImage2D_State(target, level, internalformat, width, height, border, imageSize, data); - } + void CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, + GLsizei imageSize, const void* data) { + CompressedTexSubImage1D_State(target, level, xoffset, width, format, imageSize, data); + } - void CompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, - GLsizei imageSize, const void* data) { - CompressedTexImage1D_State(target, level, internalformat, width, border, imageSize, data); - } + void CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLsizei imageSize, const void* data) { + CompressedTexImage3D_State(target, level, internalformat, width, height, depth, border, imageSize, data); + } - void BindTexture(GLenum target, GLuint texture) { - BindTexture_State(target, texture); - } + void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, + GLint border, GLsizei imageSize, const void* data) { + CompressedTexImage2D_State(target, level, internalformat, width, height, border, imageSize, data); + } - void ActiveTexture(GLenum texture) { - ActiveTexture_State(texture); - } + void CompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, + GLsizei imageSize, const void* data) { + CompressedTexImage1D_State(target, level, internalformat, width, border, imageSize, data); + } - } // namespace MG_Impl::GLImpl -} // namespace MobileGL + void BindTexture(GLenum target, GLuint texture) { + BindTexture_State(target, texture); + } + + void ActiveTexture(GLenum texture) { + ActiveTexture_State(texture); + } + +} // namespace MobileGL::MG_Impl::GLImpl diff --git a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.h b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.h index 2bd725bc..642a27ad 100644 --- a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.h +++ b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.h @@ -9,67 +9,65 @@ #pragma once #include -namespace MobileGL { - namespace MG_Impl::GLImpl { - /* @INSERTION_POINT:FUNCTION_DECLARATION@ */ - void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels); - void TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); - void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLenum type, const void* pixels); - void TexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, - const GLvoid* pixels); - void TexParameterf(GLenum target, GLenum pname, GLfloat param); - void TexParameteri(GLenum target, GLenum pname, GLint param); - void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params); - void TexParameteriv(GLenum target, GLenum pname, const GLint* params); - void TexParameterIiv(GLenum target, GLenum pname, const GLint* params); - void TexParameterIuiv(GLenum target, GLenum pname, const GLuint* params); +namespace MobileGL::MG_Impl::GLImpl { + /* @INSERTION_POINT:FUNCTION_DECLARATION@ */ + void GenerateMipmap(GLenum target); + void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels); + void TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); + void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLenum type, const void* pixels); + void TexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, + const GLvoid* pixels); + void TexParameterf(GLenum target, GLenum pname, GLfloat param); + void TexParameteri(GLenum target, GLenum pname, GLint param); + void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params); + void TexParameteriv(GLenum target, GLenum pname, const GLint* params); + void TexParameterIiv(GLenum target, GLenum pname, const GLint* params); + void TexParameterIuiv(GLenum target, GLenum pname, const GLuint* params); - void TexImage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, - GLsizei depth, GLboolean fixedsamplelocations); - void TexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, - GLboolean fixedsamplelocations); - void TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, - GLint border, GLenum format, GLenum type, const void* pixels); - void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, const void* pixels); - void TexImage1D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, - GLenum type, const GLvoid* pixels); - void TexBuffer(GLenum target, GLenum internalformat, GLuint buffer); - GLboolean IsTexture(GLuint texture); - void GetTexParameterIuiv(GLenum target, GLenum pname, GLuint* params); - void GetTexParameterIiv(GLenum target, GLenum pname, GLint* params); - void GetTexParameteriv(GLenum target, GLenum pname, GLint* params); - void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params); - void GetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params); - void GetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params); - void GetCompressedTexImage(GLenum target, GLint level, void* img); - void GenTextures(GLsizei n, GLuint* textures); - void DeleteTextures(GLsizei n, const GLuint* textures); - void CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, - GLint y, GLsizei width, GLsizei height); - void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, - GLsizei width, GLsizei height); - void CopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); - void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, - GLsizei height, GLint border); - void CopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, - GLint border); - void CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, - const void* data); - void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, - GLsizei height, GLenum format, GLsizei imageSize, const void* data); - void CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, - GLsizei imageSize, const void* data); - void CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, - GLsizei depth, GLint border, GLsizei imageSize, const void* data); - void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, - GLint border, GLsizei imageSize, const void* data); - void CompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, - GLsizei imageSize, const void* data); - void BindTexture(GLenum target, GLuint texture); - void ActiveTexture(GLenum texture); - } // namespace MG_Impl::GLImpl -} // namespace MobileGL + void TexImage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLboolean fixedsamplelocations); + void TexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, + GLboolean fixedsamplelocations); + void TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum format, GLenum type, const void* pixels); + void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, const void* pixels); + void TexImage1D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, + GLenum type, const GLvoid* pixels); + void TexBuffer(GLenum target, GLenum internalformat, GLuint buffer); + GLboolean IsTexture(GLuint texture); + void GetTexParameterIuiv(GLenum target, GLenum pname, GLuint* params); + void GetTexParameterIiv(GLenum target, GLenum pname, GLint* params); + void GetTexParameteriv(GLenum target, GLenum pname, GLint* params); + void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params); + void GetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params); + void GetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params); + void GetCompressedTexImage(GLenum target, GLint level, void* img); + void GenTextures(GLsizei n, GLuint* textures); + void DeleteTextures(GLsizei n, const GLuint* textures); + void CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, + GLsizei width, GLsizei height); + void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, + GLsizei height); + void CopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); + void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, + GLsizei height, GLint border); + void CopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, + GLint border); + void CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); + void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLsizei imageSize, const void* data); + void CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, + GLsizei imageSize, const void* data); + void CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLsizei imageSize, const void* data); + void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, + GLint border, GLsizei imageSize, const void* data); + void CompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, + GLsizei imageSize, const void* data); + void BindTexture(GLenum target, GLuint texture); + void ActiveTexture(GLenum texture); +} // namespace MobileGL::MG_Impl::GLImpl diff --git a/MobileGL/MG_Impl/Init.cpp b/MobileGL/MG_Impl/Init.cpp index f026a4d9..448edbbc 100644 --- a/MobileGL/MG_Impl/Init.cpp +++ b/MobileGL/MG_Impl/Init.cpp @@ -14,31 +14,29 @@ #include #include -namespace MobileGL { - namespace MG_Impl { - void Init() { - MGLOG_D("Initializing MobileGL Implementation..."); - GLImpl::TextureImpl::pProxyTextureManager = new GLImpl::TextureImpl::ProxyTextureManager(); +namespace MobileGL::MG_Impl { + void Init() { + MGLOG_D("Initializing MobileGL Implementation..."); + GLImpl::TextureImpl::pProxyTextureManager = new GLImpl::TextureImpl::ProxyTextureManager(); - // TODO: get real info in EGL - auto fbo0 = MG_State::pGLContext->CreateFramebufferObject(0); - auto colorTex = MakeShared(0); - colorTex->SetInternalFormat(TextureInternalFormat::RGBA8); - colorTex->AllocateStorage(TextureUploadTarget::Texture2D, 0, {{512, 512, 1}, 0}); - // colorTex->SetMipmapLevel({{512, 512, 1}, 0, false, 0, {nullptr, 0}}); - auto depthTex = MakeShared(0); - depthTex->SetInternalFormat(TextureInternalFormat::Depth32FStencil8); - depthTex->AllocateStorage(TextureUploadTarget::Texture2D, 0, {{512, 512, 1}, 0}); - // depthTex->SetMipmapLevel({{512, 512, 1}, 0, false, 0, {nullptr, 0}}); - auto stencilTex = MakeShared(0); - stencilTex->SetInternalFormat(TextureInternalFormat::Depth32FStencil8); - stencilTex->AllocateStorage(TextureUploadTarget::Texture2D, 0, {{512, 512, 1}, 0}); - // stencilTex->SetMipmapLevel({{512, 512, 1}, 0, false, 0, {nullptr, 0}}); - fbo0->AttachTexture(FramebufferAttachmentType::Color0, colorTex); - fbo0->AttachTexture(FramebufferAttachmentType::Depth, depthTex); - fbo0->AttachTexture(FramebufferAttachmentType::Stencil, stencilTex); - GLImpl::FramebufferImpl::pDefaultFramebufferInfo = - new GLImpl::FramebufferImpl::DefaultFramebufferInfo(fbo0, colorTex, depthTex, stencilTex); - } - } // namespace MG_Impl -} // namespace MobileGL \ No newline at end of file + // TODO: get real info in EGL + auto fbo0 = MG_State::pGLContext->CreateFramebufferObject(0); + auto colorTex = MakeShared(0); + colorTex->SetInternalFormat(TextureInternalFormat::RGBA8); + colorTex->AllocateStorage(TextureUploadTarget::Texture2D, 0, {{512, 512, 1}, 0}); + // colorTex->SetMipmapLevel({{512, 512, 1}, 0, false, 0, {nullptr, 0}}); + auto depthTex = MakeShared(0); + depthTex->SetInternalFormat(TextureInternalFormat::Depth32FStencil8); + depthTex->AllocateStorage(TextureUploadTarget::Texture2D, 0, {{512, 512, 1}, 0}); + // depthTex->SetMipmapLevel({{512, 512, 1}, 0, false, 0, {nullptr, 0}}); + auto stencilTex = MakeShared(0); + stencilTex->SetInternalFormat(TextureInternalFormat::Depth32FStencil8); + stencilTex->AllocateStorage(TextureUploadTarget::Texture2D, 0, {{512, 512, 1}, 0}); + // stencilTex->SetMipmapLevel({{512, 512, 1}, 0, false, 0, {nullptr, 0}}); + fbo0->AttachTexture(FramebufferAttachmentType::Color0, colorTex); + fbo0->AttachTexture(FramebufferAttachmentType::Depth, depthTex); + fbo0->AttachTexture(FramebufferAttachmentType::Stencil, stencilTex); + GLImpl::FramebufferImpl::pDefaultFramebufferInfo = + new GLImpl::FramebufferImpl::DefaultFramebufferInfo(fbo0, colorTex, depthTex, stencilTex); + } +} // namespace MobileGL::MG_Impl diff --git a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp index c89d064c..719421e5 100644 --- a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp +++ b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp @@ -13,12 +13,13 @@ namespace MobileGL { namespace MG_State { namespace GLState { // FramebufferAttachmentObject - FramebufferAttachmentObject::FramebufferAttachmentObject(SharedPtr texture, - Int level) + FramebufferAttachmentObject::FramebufferAttachmentObject( + SharedPtr texture, Int level) : m_texture(texture), m_textureLevel(level) {} FramebufferAttachmentObject::FramebufferAttachmentObject(SharedPtr renderbuffer) : m_renderbuffer(renderbuffer) {} - FramebufferAttachmentObject::FramebufferAttachmentObject(Bool IsValid) : m_texture(nullptr), m_renderbuffer(nullptr) { + FramebufferAttachmentObject::FramebufferAttachmentObject(Bool IsValid) + : m_texture(nullptr), m_renderbuffer(nullptr) { m_isValid = IsValid; } @@ -104,7 +105,8 @@ namespace MobileGL { return m_attachmentObjects[static_cast(type)]; } - const FramebufferObject::FramebufferAttachmentObjectArray& FramebufferObject::GetAllAttachmentObjects() const { + const FramebufferObject::FramebufferAttachmentObjectArray& FramebufferObject::GetAllAttachmentObjects() + const { return m_attachmentObjects; } diff --git a/MobileGL/MG_State/GLState/TextureState/TextureObject.h b/MobileGL/MG_State/GLState/TextureState/TextureObject.h index cef2bde3..5f111641 100644 --- a/MobileGL/MG_State/GLState/TextureState/TextureObject.h +++ b/MobileGL/MG_State/GLState/TextureState/TextureObject.h @@ -69,6 +69,7 @@ namespace MobileGL { void SetBaseLevel(Uint baseLevel) override; void SetMaxLevel(Uint maxLevel) override; Uint16 GetTextureParamsVersion() const override; + protected: const Uint m_externalIndex; const TextureTarget m_target = TextureTarget::Unknown; diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp index 7e954f9d..05c3efd3 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp @@ -7,1063 +7,637 @@ // End of Source File Header #include "Loader.h" +#include "MG_Util/Types.h" -#define GL_FUNC_DECL(name) name##_PTR name; -#define EGL_FUNC_DECL(name) name##_PTR name; - -namespace MobileGL { - namespace MG_External { - namespace GLES { - Caps::GLESCaps g_glesCaps; - - GL_FUNC_DECL(glActiveTexture) - GL_FUNC_DECL(glAttachShader) - GL_FUNC_DECL(glBindAttribLocation) - GL_FUNC_DECL(glBindBuffer) - GL_FUNC_DECL(glBindFramebuffer) - GL_FUNC_DECL(glBindRenderbuffer) - GL_FUNC_DECL(glBindTexture) - GL_FUNC_DECL(glBlendColor) - GL_FUNC_DECL(glBlendEquation) - GL_FUNC_DECL(glBlendEquationSeparate) - GL_FUNC_DECL(glBlendFunc) - GL_FUNC_DECL(glBlendFuncSeparate) - GL_FUNC_DECL(glBufferData) - GL_FUNC_DECL(glBufferSubData) - GL_FUNC_DECL(glCheckFramebufferStatus) - GL_FUNC_DECL(glClear) - GL_FUNC_DECL(glClearColor) - GL_FUNC_DECL(glClearDepthf) - GL_FUNC_DECL(glClearStencil) - GL_FUNC_DECL(glColorMask) - GL_FUNC_DECL(glCompileShader) - GL_FUNC_DECL(glCompressedTexImage2D) - GL_FUNC_DECL(glCompressedTexSubImage2D) - GL_FUNC_DECL(glCopyTexImage2D) - GL_FUNC_DECL(glCopyTexSubImage2D) - GL_FUNC_DECL(glCreateProgram) - GL_FUNC_DECL(glCreateShader) - GL_FUNC_DECL(glCullFace) - GL_FUNC_DECL(glDeleteBuffers) - GL_FUNC_DECL(glDeleteFramebuffers) - GL_FUNC_DECL(glDeleteProgram) - GL_FUNC_DECL(glDeleteRenderbuffers) - GL_FUNC_DECL(glDeleteShader) - GL_FUNC_DECL(glDeleteTextures) - GL_FUNC_DECL(glDepthFunc) - GL_FUNC_DECL(glDepthMask) - GL_FUNC_DECL(glDepthRangef) - GL_FUNC_DECL(glDetachShader) - GL_FUNC_DECL(glDisable) - GL_FUNC_DECL(glDisableVertexAttribArray) - GL_FUNC_DECL(glDrawArrays) - GL_FUNC_DECL(glDrawElements) - GL_FUNC_DECL(glEnable) - GL_FUNC_DECL(glEnableVertexAttribArray) - GL_FUNC_DECL(glFinish) - GL_FUNC_DECL(glFlush) - GL_FUNC_DECL(glFramebufferRenderbuffer) - GL_FUNC_DECL(glFramebufferTexture2D) - GL_FUNC_DECL(glFrontFace) - GL_FUNC_DECL(glGenBuffers) - GL_FUNC_DECL(glGenerateMipmap) - GL_FUNC_DECL(glGenFramebuffers) - GL_FUNC_DECL(glGenRenderbuffers) - GL_FUNC_DECL(glGenTextures) - GL_FUNC_DECL(glGetActiveAttrib) - GL_FUNC_DECL(glGetActiveUniform) - GL_FUNC_DECL(glGetAttachedShaders) - GL_FUNC_DECL(glGetAttribLocation) - GL_FUNC_DECL(glGetBooleanv) - GL_FUNC_DECL(glGetBufferParameteriv) - GL_FUNC_DECL(glGetError) - GL_FUNC_DECL(glGetString) - GL_FUNC_DECL(glGetStringi) - GL_FUNC_DECL(glGetFloatv) - GL_FUNC_DECL(glGetFramebufferAttachmentParameteriv) - GL_FUNC_DECL(glGetIntegerv) - GL_FUNC_DECL(glGetProgramiv) - GL_FUNC_DECL(glGetProgramInfoLog) - GL_FUNC_DECL(glGetRenderbufferParameteriv) - GL_FUNC_DECL(glGetShaderiv) - GL_FUNC_DECL(glGetShaderInfoLog) - GL_FUNC_DECL(glGetShaderPrecisionFormat) - GL_FUNC_DECL(glGetShaderSource) - GL_FUNC_DECL(glGetTexParameterfv) - GL_FUNC_DECL(glGetTexParameteriv) - GL_FUNC_DECL(glGetUniformfv) - GL_FUNC_DECL(glGetUniformiv) - GL_FUNC_DECL(glGetUniformLocation) - GL_FUNC_DECL(glGetVertexAttribfv) - GL_FUNC_DECL(glGetVertexAttribiv) - GL_FUNC_DECL(glGetVertexAttribPointerv) - GL_FUNC_DECL(glHint) - GL_FUNC_DECL(glIsBuffer) - GL_FUNC_DECL(glIsEnabled) - GL_FUNC_DECL(glIsFramebuffer) - GL_FUNC_DECL(glIsProgram) - GL_FUNC_DECL(glIsRenderbuffer) - GL_FUNC_DECL(glIsShader) - GL_FUNC_DECL(glIsTexture) - GL_FUNC_DECL(glLineWidth) - GL_FUNC_DECL(glLinkProgram) - GL_FUNC_DECL(glPixelStorei) - GL_FUNC_DECL(glPolygonOffset) - GL_FUNC_DECL(glReadPixels) - GL_FUNC_DECL(glReleaseShaderCompiler) - GL_FUNC_DECL(glRenderbufferStorage) - GL_FUNC_DECL(glSampleCoverage) - GL_FUNC_DECL(glScissor) - GL_FUNC_DECL(glShaderBinary) - GL_FUNC_DECL(glShaderSource) - GL_FUNC_DECL(glStencilFunc) - GL_FUNC_DECL(glStencilFuncSeparate) - GL_FUNC_DECL(glStencilMask) - GL_FUNC_DECL(glStencilMaskSeparate) - GL_FUNC_DECL(glStencilOp) - GL_FUNC_DECL(glStencilOpSeparate) - GL_FUNC_DECL(glTexImage2D) - GL_FUNC_DECL(glTexParameterf) - GL_FUNC_DECL(glTexParameterfv) - GL_FUNC_DECL(glTexParameteri) - GL_FUNC_DECL(glTexParameteriv) - GL_FUNC_DECL(glTexSubImage2D) - GL_FUNC_DECL(glUniform1f) - GL_FUNC_DECL(glUniform1fv) - GL_FUNC_DECL(glUniform1i) - GL_FUNC_DECL(glUniform1iv) - GL_FUNC_DECL(glUniform2f) - GL_FUNC_DECL(glUniform2fv) - GL_FUNC_DECL(glUniform2i) - GL_FUNC_DECL(glUniform2iv) - GL_FUNC_DECL(glUniform3f) - GL_FUNC_DECL(glUniform3fv) - GL_FUNC_DECL(glUniform3i) - GL_FUNC_DECL(glUniform3iv) - GL_FUNC_DECL(glUniform4f) - GL_FUNC_DECL(glUniform4fv) - GL_FUNC_DECL(glUniform4i) - GL_FUNC_DECL(glUniform4iv) - GL_FUNC_DECL(glUniformMatrix2fv) - GL_FUNC_DECL(glUniformMatrix3fv) - GL_FUNC_DECL(glUniformMatrix4fv) - GL_FUNC_DECL(glUseProgram) - GL_FUNC_DECL(glValidateProgram) - GL_FUNC_DECL(glVertexAttrib1f) - GL_FUNC_DECL(glVertexAttrib1fv) - GL_FUNC_DECL(glVertexAttrib2f) - GL_FUNC_DECL(glVertexAttrib2fv) - GL_FUNC_DECL(glVertexAttrib3f) - GL_FUNC_DECL(glVertexAttrib3fv) - GL_FUNC_DECL(glVertexAttrib4f) - GL_FUNC_DECL(glVertexAttrib4fv) - GL_FUNC_DECL(glVertexAttribPointer) - GL_FUNC_DECL(glViewport) - GL_FUNC_DECL(glReadBuffer) - GL_FUNC_DECL(glDrawRangeElements) - GL_FUNC_DECL(glTexImage3D) - GL_FUNC_DECL(glTexSubImage3D) - GL_FUNC_DECL(glCopyTexSubImage3D) - GL_FUNC_DECL(glCompressedTexImage3D) - GL_FUNC_DECL(glCompressedTexSubImage3D) - GL_FUNC_DECL(glGenQueries) - GL_FUNC_DECL(glDeleteQueries) - GL_FUNC_DECL(glIsQuery) - GL_FUNC_DECL(glBeginQuery) - GL_FUNC_DECL(glEndQuery) - GL_FUNC_DECL(glGetQueryiv) - GL_FUNC_DECL(glGetQueryObjectuiv) - GL_FUNC_DECL(glUnmapBuffer) - GL_FUNC_DECL(glGetBufferPointerv) - GL_FUNC_DECL(glDrawBuffers) - GL_FUNC_DECL(glUniformMatrix2x3fv) - GL_FUNC_DECL(glUniformMatrix3x2fv) - GL_FUNC_DECL(glUniformMatrix2x4fv) - GL_FUNC_DECL(glUniformMatrix4x2fv) - GL_FUNC_DECL(glUniformMatrix3x4fv) - GL_FUNC_DECL(glUniformMatrix4x3fv) - GL_FUNC_DECL(glBlitFramebuffer) - GL_FUNC_DECL(glRenderbufferStorageMultisample) - GL_FUNC_DECL(glFramebufferTextureLayer) - GL_FUNC_DECL(glFlushMappedBufferRange) - GL_FUNC_DECL(glBindVertexArray) - GL_FUNC_DECL(glDeleteVertexArrays) - GL_FUNC_DECL(glGenVertexArrays) - GL_FUNC_DECL(glIsVertexArray) - GL_FUNC_DECL(glGetIntegeri_v) - GL_FUNC_DECL(glBeginTransformFeedback) - GL_FUNC_DECL(glEndTransformFeedback) - GL_FUNC_DECL(glBindBufferRange) - GL_FUNC_DECL(glBindBufferBase) - GL_FUNC_DECL(glTransformFeedbackVaryings) - GL_FUNC_DECL(glGetTransformFeedbackVarying) - GL_FUNC_DECL(glVertexAttribIPointer) - GL_FUNC_DECL(glGetVertexAttribIiv) - GL_FUNC_DECL(glGetVertexAttribIuiv) - GL_FUNC_DECL(glVertexAttribI4i) - GL_FUNC_DECL(glVertexAttribI4ui) - GL_FUNC_DECL(glVertexAttribI4iv) - GL_FUNC_DECL(glVertexAttribI4uiv) - GL_FUNC_DECL(glGetUniformuiv) - GL_FUNC_DECL(glGetFragDataLocation) - GL_FUNC_DECL(glUniform1ui) - GL_FUNC_DECL(glUniform2ui) - GL_FUNC_DECL(glUniform3ui) - GL_FUNC_DECL(glUniform4ui) - GL_FUNC_DECL(glUniform1uiv) - GL_FUNC_DECL(glUniform2uiv) - GL_FUNC_DECL(glUniform3uiv) - GL_FUNC_DECL(glUniform4uiv) - GL_FUNC_DECL(glClearBufferiv) - GL_FUNC_DECL(glClearBufferuiv) - GL_FUNC_DECL(glClearBufferfv) - GL_FUNC_DECL(glClearBufferfi) - GL_FUNC_DECL(glCopyBufferSubData) - GL_FUNC_DECL(glGetUniformIndices) - GL_FUNC_DECL(glGetActiveUniformsiv) - GL_FUNC_DECL(glGetUniformBlockIndex) - GL_FUNC_DECL(glGetActiveUniformBlockiv) - GL_FUNC_DECL(glGetActiveUniformBlockName) - GL_FUNC_DECL(glUniformBlockBinding) - GL_FUNC_DECL(glDrawArraysInstanced) - GL_FUNC_DECL(glDrawElementsInstanced) - GL_FUNC_DECL(glFenceSync) - GL_FUNC_DECL(glIsSync) - GL_FUNC_DECL(glDeleteSync) - GL_FUNC_DECL(glClientWaitSync) - GL_FUNC_DECL(glWaitSync) - GL_FUNC_DECL(glGetInteger64v) - GL_FUNC_DECL(glGetSynciv) - GL_FUNC_DECL(glGetInteger64i_v) - GL_FUNC_DECL(glGetBufferParameteri64v) - GL_FUNC_DECL(glGenSamplers) - GL_FUNC_DECL(glDeleteSamplers) - GL_FUNC_DECL(glIsSampler) - GL_FUNC_DECL(glBindSampler) - GL_FUNC_DECL(glSamplerParameteri) - GL_FUNC_DECL(glSamplerParameteriv) - GL_FUNC_DECL(glSamplerParameterf) - GL_FUNC_DECL(glSamplerParameterfv) - GL_FUNC_DECL(glGetSamplerParameteriv) - GL_FUNC_DECL(glGetSamplerParameterfv) - GL_FUNC_DECL(glVertexAttribDivisor) - GL_FUNC_DECL(glBindTransformFeedback) - GL_FUNC_DECL(glDeleteTransformFeedbacks) - GL_FUNC_DECL(glGenTransformFeedbacks) - GL_FUNC_DECL(glIsTransformFeedback) - GL_FUNC_DECL(glPauseTransformFeedback) - GL_FUNC_DECL(glResumeTransformFeedback) - GL_FUNC_DECL(glGetProgramBinary) - GL_FUNC_DECL(glProgramBinary) - GL_FUNC_DECL(glProgramParameteri) - GL_FUNC_DECL(glInvalidateFramebuffer) - GL_FUNC_DECL(glInvalidateSubFramebuffer) - GL_FUNC_DECL(glTexStorage2D) - GL_FUNC_DECL(glTexStorage3D) - GL_FUNC_DECL(glGetInternalformativ) - GL_FUNC_DECL(glDispatchCompute) - GL_FUNC_DECL(glDispatchComputeIndirect) - GL_FUNC_DECL(glDrawArraysIndirect) - GL_FUNC_DECL(glDrawElementsIndirect) - GL_FUNC_DECL(glFramebufferParameteri) - GL_FUNC_DECL(glGetFramebufferParameteriv) - GL_FUNC_DECL(glGetProgramInterfaceiv) - GL_FUNC_DECL(glGetProgramResourceIndex) - GL_FUNC_DECL(glGetProgramResourceName) - GL_FUNC_DECL(glGetProgramResourceiv) - GL_FUNC_DECL(glGetProgramResourceLocation) - GL_FUNC_DECL(glUseProgramStages) - GL_FUNC_DECL(glActiveShaderProgram) - GL_FUNC_DECL(glCreateShaderProgramv) - GL_FUNC_DECL(glBindProgramPipeline) - GL_FUNC_DECL(glDeleteProgramPipelines) - GL_FUNC_DECL(glGenProgramPipelines) - GL_FUNC_DECL(glIsProgramPipeline) - GL_FUNC_DECL(glGetProgramPipelineiv) - GL_FUNC_DECL(glProgramUniform1i) - GL_FUNC_DECL(glProgramUniform2i) - GL_FUNC_DECL(glProgramUniform3i) - GL_FUNC_DECL(glProgramUniform4i) - GL_FUNC_DECL(glProgramUniform1ui) - GL_FUNC_DECL(glProgramUniform2ui) - GL_FUNC_DECL(glProgramUniform3ui) - GL_FUNC_DECL(glProgramUniform4ui) - GL_FUNC_DECL(glProgramUniform1f) - GL_FUNC_DECL(glProgramUniform2f) - GL_FUNC_DECL(glProgramUniform3f) - GL_FUNC_DECL(glProgramUniform4f) - GL_FUNC_DECL(glProgramUniform1iv) - GL_FUNC_DECL(glProgramUniform2iv) - GL_FUNC_DECL(glProgramUniform3iv) - GL_FUNC_DECL(glProgramUniform4iv) - GL_FUNC_DECL(glProgramUniform1uiv) - GL_FUNC_DECL(glProgramUniform2uiv) - GL_FUNC_DECL(glProgramUniform3uiv) - GL_FUNC_DECL(glProgramUniform4uiv) - GL_FUNC_DECL(glProgramUniform1fv) - GL_FUNC_DECL(glProgramUniform2fv) - GL_FUNC_DECL(glProgramUniform3fv) - GL_FUNC_DECL(glProgramUniform4fv) - GL_FUNC_DECL(glProgramUniformMatrix2fv) - GL_FUNC_DECL(glProgramUniformMatrix3fv) - GL_FUNC_DECL(glProgramUniformMatrix4fv) - GL_FUNC_DECL(glProgramUniformMatrix2x3fv) - GL_FUNC_DECL(glProgramUniformMatrix3x2fv) - GL_FUNC_DECL(glProgramUniformMatrix2x4fv) - GL_FUNC_DECL(glProgramUniformMatrix4x2fv) - GL_FUNC_DECL(glProgramUniformMatrix3x4fv) - GL_FUNC_DECL(glProgramUniformMatrix4x3fv) - GL_FUNC_DECL(glValidateProgramPipeline) - GL_FUNC_DECL(glGetProgramPipelineInfoLog) - GL_FUNC_DECL(glBindImageTexture) - GL_FUNC_DECL(glGetBooleani_v) - GL_FUNC_DECL(glMemoryBarrier) - GL_FUNC_DECL(glMemoryBarrierByRegion) - GL_FUNC_DECL(glTexStorage2DMultisample) - GL_FUNC_DECL(glGetMultisamplefv) - GL_FUNC_DECL(glSampleMaski) - GL_FUNC_DECL(glGetTexLevelParameteriv) - GL_FUNC_DECL(glGetTexLevelParameterfv) - GL_FUNC_DECL(glBindVertexBuffer) - GL_FUNC_DECL(glVertexAttribFormat) - GL_FUNC_DECL(glVertexAttribIFormat) - GL_FUNC_DECL(glVertexAttribBinding) - GL_FUNC_DECL(glVertexBindingDivisor) - GL_FUNC_DECL(glBlendBarrier) - GL_FUNC_DECL(glCopyImageSubData) - GL_FUNC_DECL(glDebugMessageControl) - GL_FUNC_DECL(glDebugMessageInsert) - GL_FUNC_DECL(glDebugMessageCallback) - GL_FUNC_DECL(glGetDebugMessageLog) - GL_FUNC_DECL(glPushDebugGroup) - GL_FUNC_DECL(glPopDebugGroup) - GL_FUNC_DECL(glObjectLabel) - GL_FUNC_DECL(glGetObjectLabel) - GL_FUNC_DECL(glObjectPtrLabel) - GL_FUNC_DECL(glGetObjectPtrLabel) - GL_FUNC_DECL(glGetPointerv) - GL_FUNC_DECL(glEnablei) - GL_FUNC_DECL(glDisablei) - GL_FUNC_DECL(glBlendEquationi) - GL_FUNC_DECL(glBlendEquationSeparatei) - GL_FUNC_DECL(glBlendFunci) - GL_FUNC_DECL(glBlendFuncSeparatei) - GL_FUNC_DECL(glColorMaski) - GL_FUNC_DECL(glIsEnabledi) - GL_FUNC_DECL(glDrawElementsBaseVertex) - GL_FUNC_DECL(glDrawRangeElementsBaseVertex) - GL_FUNC_DECL(glDrawElementsInstancedBaseVertex) - GL_FUNC_DECL(glFramebufferTexture) - GL_FUNC_DECL(glPrimitiveBoundingBox) - GL_FUNC_DECL(glGetGraphicsResetStatus) - GL_FUNC_DECL(glReadnPixels) - GL_FUNC_DECL(glGetnUniformfv) - GL_FUNC_DECL(glGetnUniformiv) - GL_FUNC_DECL(glGetnUniformuiv) - GL_FUNC_DECL(glMinSampleShading) - GL_FUNC_DECL(glPatchParameteri) - GL_FUNC_DECL(glTexParameterIiv) - GL_FUNC_DECL(glTexParameterIuiv) - GL_FUNC_DECL(glGetTexParameterIiv) - GL_FUNC_DECL(glGetTexParameterIuiv) - GL_FUNC_DECL(glSamplerParameterIiv) - GL_FUNC_DECL(glSamplerParameterIuiv) - GL_FUNC_DECL(glGetSamplerParameterIiv) - GL_FUNC_DECL(glGetSamplerParameterIuiv) - GL_FUNC_DECL(glTexBuffer) - GL_FUNC_DECL(glTexBufferRange) - GL_FUNC_DECL(glTexStorage3DMultisample) - GL_FUNC_DECL(glMapBufferRange) - GL_FUNC_DECL(glBufferStorageEXT) - GL_FUNC_DECL(glGetQueryObjectivEXT) - GL_FUNC_DECL(glGetQueryObjecti64vEXT) - GL_FUNC_DECL(glBindFragDataLocationEXT) - GL_FUNC_DECL(glMapBufferOES) - - GL_FUNC_DECL(glMultiDrawArraysIndirectEXT) - GL_FUNC_DECL(glMultiDrawElementsIndirectEXT) - GL_FUNC_DECL(glMultiDrawElementsBaseVertexEXT) - - GL_FUNC_DECL(glBruh) - } // namespace GLES - - namespace EGL { - EGL_FUNC_DECL(eglBindAPI) - EGL_FUNC_DECL(eglBindTexImage) - EGL_FUNC_DECL(eglChooseConfig) - EGL_FUNC_DECL(eglCopyBuffers) - EGL_FUNC_DECL(eglCreateContext) - EGL_FUNC_DECL(eglCreatePbufferFromClientBuffer) - EGL_FUNC_DECL(eglCreatePbufferSurface) - EGL_FUNC_DECL(eglCreatePixmapSurface) - EGL_FUNC_DECL(eglCreatePlatformWindowSurface) - EGL_FUNC_DECL(eglCreateWindowSurface) - EGL_FUNC_DECL(eglDestroyContext) - EGL_FUNC_DECL(eglDestroySurface) - EGL_FUNC_DECL(eglGetConfigAttrib) - EGL_FUNC_DECL(eglGetConfigs) - EGL_FUNC_DECL(eglGetCurrentContext) - EGL_FUNC_DECL(eglGetCurrentDisplay) - EGL_FUNC_DECL(eglGetCurrentSurface) - EGL_FUNC_DECL(eglGetDisplay) - EGL_FUNC_DECL(eglGetPlatformDisplay) - EGL_FUNC_DECL(eglGetError) - EGL_FUNC_DECL(eglGetProcAddress) - EGL_FUNC_DECL(eglInitialize) - EGL_FUNC_DECL(eglMakeCurrent) - EGL_FUNC_DECL(eglQueryAPI) - EGL_FUNC_DECL(eglQueryContext) - EGL_FUNC_DECL(eglQueryString) - EGL_FUNC_DECL(eglQuerySurface) - EGL_FUNC_DECL(eglReleaseTexImage) - EGL_FUNC_DECL(eglReleaseThread) - EGL_FUNC_DECL(eglSurfaceAttrib) - EGL_FUNC_DECL(eglSwapBuffers) - EGL_FUNC_DECL(eglSwapBuffersWithDamageEXT) - EGL_FUNC_DECL(eglSwapInterval) - EGL_FUNC_DECL(eglTerminate) - EGL_FUNC_DECL(eglUnlockSurfaceKHR) - EGL_FUNC_DECL(eglWaitClient) - EGL_FUNC_DECL(eglWaitGL) - EGL_FUNC_DECL(eglWaitNative) - EGL_FUNC_DECL(eglCreateSync) - EGL_FUNC_DECL(eglDestroySync) - EGL_FUNC_DECL(eglClientWaitSync) - EGL_FUNC_DECL(eglGetSyncAttrib) - EGL_FUNC_DECL(eglCreateImage) - EGL_FUNC_DECL(eglDestroyImage) - EGL_FUNC_DECL(eglCreatePlatformPixmapSurface) - EGL_FUNC_DECL(eglWaitSync) - } // namespace EGL - } // namespace MG_External - -#undef GL_FUNC_DECL -#undef EGL_FUNC_DECL - - namespace MG_Util { - namespace BackendLoader::GLES { - Bool Init() { - LoadLibs(); - if (libGLES == nullptr || libEGL == nullptr || - (glGetError_PTR)ProcAddress(libGLES, "glGetError") == nullptr) { - return false; - } - InitEGL(); - InitGLES(); - DestroyTempEGLCtx(); - return true; - } - - void *libGLES = nullptr, *libEGL = nullptr; - - static const char* LibPathPrefixes[] = { - "/opt/vc/lib/", - "/usr/local/lib/", - "/usr/lib/", - "/usr/lib/x86_64-linux-gnu/", - "", // We should put this to the end of the list to avoid breaking `LD_LIBRARY_PATH` usage - nullptr}; - static const char* LibExts[] = {"so", "so.1", "so.2", "dylib", "dll", nullptr}; - static const char* GLES3Libs[] = {"libGLESv3_CM", "libGLESv3", "libGLESv2_CM", "libGLESv2", nullptr}; - static const char* EGLLibs[] = {"libEGL", nullptr}; - - void* OpenLib(const char** names, const char* override) { +namespace MobileGL::MG_Util::BackendLoader { + static void* OpenLib(const Vector& names) { #if !defined(__WIN32) && !defined(_WIN32) && !defined(__APPLE__) - void* lib = nullptr; + static const String LibPathPrefixes[] = { + "/opt/vc/lib/", "/usr/local/lib/", "/usr/lib/", "/usr/lib/x86_64-linux-gnu/", + "" // We should put this to the end of the list to avoid breaking `LD_LIBRARY_PATH` usage + }; - char path_name[PATH_MAX + 1]; - int flags = RTLD_LOCAL | RTLD_NOW; - if (override) { - if ((lib = dlopen(override, flags))) { - strncpy(path_name, override, PATH_MAX); - return lib; - } + void* lib = nullptr; + + Int flags = RTLD_LOCAL | RTLD_NOW; + for (const auto& prefix : LibPathPrefixes) { + for (const auto& name : names) { + String path_name = prefix + name; + if ((lib = dlopen(path_name.c_str(), flags))) { + return lib; } - for (int p = 0; LibPathPrefixes[p]; p++) { - for (int i = 0; names[i]; i++) { - for (int e = 0; LibExts[e]; e++) { - snprintf(path_name, PATH_MAX, "%s%s.%s", LibPathPrefixes[p], names[i], LibExts[e]); - if ((lib = dlopen(path_name, flags))) { - return lib; - } - } - } - } - return lib; -#else - return nullptr; + } + } #endif - } - - void LoadLibs() { - // TODO: Add ANGLE override? - libGLES = OpenLib(GLES3Libs, nullptr); - libEGL = OpenLib(EGLLibs, nullptr); - } - - void* ProcAddress(void* lib, const char* name) { -#if !defined(__WIN32) && !defined(_WIN32) && !defined(__APPLE__) - return dlsym(lib, name); -#else - return nullptr; -#endif - } - - void InitGLESCapabilities() { - auto* vendorName = MG_External::GLES::glGetString(GL_VENDOR); - MGLOG_I("GL_VENDOR: %s", vendorName); - auto* gpuName = MG_External::GLES::glGetString(GL_RENDERER); - MGLOG_I("GL_RENDERER: %s", gpuName); - MG_External::GLES::glGetIntegerv(GL_MAJOR_VERSION, &MG_External::GLES::g_glesCaps.version.Major); - MG_External::GLES::glGetIntegerv(GL_MINOR_VERSION, &MG_External::GLES::g_glesCaps.version.Minor); - - GLint extCount = 0; - MG_External::GLES::glGetIntegerv(GL_NUM_EXTENSIONS, &extCount); - MGLOG_I("Detected %d OpenGL ES extensions:", extCount); - for (GLint i = 0; i < extCount; ++i) { - const char* extension = (const char*)MG_External::GLES::glGetStringi(GL_EXTENSIONS, i); - if (extension) { - MGLOG_I(" %s", extension); - if (std::strcmp(extension, "GL_EXT_buffer_storage") == 0) { - MG_External::GLES::g_glesCaps.hasPersistentMapping = true; - } - if (std::strcmp(extension, "GL_EXT_texture_norm16") == 0) { - MG_External::GLES::g_glesCaps.hasNorm16Texture = true; - } - } - } - - MGLOG_I("OpenGL ES capabilities:"); - MG_External::GLES::glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, - &MG_External::GLES::g_glesCaps.uniformBufferOffsetAlignment); - MGLOG_I(" GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: %d", - MG_External::GLES::g_glesCaps.uniformBufferOffsetAlignment); - } - - void InitGLES() { - INIT_GLES_FUNC(glActiveTexture) - INIT_GLES_FUNC(glAttachShader) - INIT_GLES_FUNC(glBindAttribLocation) - INIT_GLES_FUNC(glBindBuffer) - INIT_GLES_FUNC(glBindFramebuffer) - INIT_GLES_FUNC(glBindRenderbuffer) - INIT_GLES_FUNC(glBindTexture) - INIT_GLES_FUNC(glBlendColor) - INIT_GLES_FUNC(glBlendEquation) - INIT_GLES_FUNC(glBlendEquationSeparate) - INIT_GLES_FUNC(glBlendFunc) - INIT_GLES_FUNC(glBlendFuncSeparate) - INIT_GLES_FUNC(glBufferData) - INIT_GLES_FUNC(glBufferSubData) - INIT_GLES_FUNC(glCheckFramebufferStatus) - INIT_GLES_FUNC(glClear) - INIT_GLES_FUNC(glClearColor) - INIT_GLES_FUNC(glClearDepthf) - INIT_GLES_FUNC(glClearStencil) - INIT_GLES_FUNC(glColorMask) - INIT_GLES_FUNC(glCompileShader) - INIT_GLES_FUNC(glCompressedTexImage2D) - INIT_GLES_FUNC(glCompressedTexSubImage2D) - // INIT_GLES_FUNC(glCopyTexImage1D) - INIT_GLES_FUNC(glCopyTexImage2D) - INIT_GLES_FUNC(glCopyTexSubImage2D) - INIT_GLES_FUNC(glCreateProgram) - INIT_GLES_FUNC(glCreateShader) - INIT_GLES_FUNC(glCullFace) - INIT_GLES_FUNC(glDeleteBuffers) - INIT_GLES_FUNC(glDeleteFramebuffers) - INIT_GLES_FUNC(glDeleteProgram) - INIT_GLES_FUNC(glDeleteRenderbuffers) - INIT_GLES_FUNC(glDeleteShader) - INIT_GLES_FUNC(glDeleteTextures) - INIT_GLES_FUNC(glDepthFunc) - INIT_GLES_FUNC(glDepthMask) - INIT_GLES_FUNC(glDepthRangef) - INIT_GLES_FUNC(glDetachShader) - INIT_GLES_FUNC(glDisable) - INIT_GLES_FUNC(glDisableVertexAttribArray) - INIT_GLES_FUNC(glDrawArrays) - INIT_GLES_FUNC(glDrawElements) - INIT_GLES_FUNC(glEnable) - INIT_GLES_FUNC(glEnableVertexAttribArray) - INIT_GLES_FUNC(glFinish) - INIT_GLES_FUNC(glFlush) - INIT_GLES_FUNC(glFramebufferRenderbuffer) - INIT_GLES_FUNC(glFramebufferTexture2D) - INIT_GLES_FUNC(glFrontFace) - INIT_GLES_FUNC(glGenBuffers) - INIT_GLES_FUNC(glGenerateMipmap) - INIT_GLES_FUNC(glGenFramebuffers) - INIT_GLES_FUNC(glGenRenderbuffers) - INIT_GLES_FUNC(glGenTextures) - INIT_GLES_FUNC(glGetActiveAttrib) - INIT_GLES_FUNC(glGetActiveUniform) - INIT_GLES_FUNC(glGetAttachedShaders) - INIT_GLES_FUNC(glGetAttribLocation) - INIT_GLES_FUNC(glGetBooleanv) - INIT_GLES_FUNC(glGetBufferParameteriv) - INIT_GLES_FUNC(glGetError) - INIT_GLES_FUNC(glGetString) - INIT_GLES_FUNC(glGetStringi) - INIT_GLES_FUNC(glGetFloatv) - INIT_GLES_FUNC(glGetFramebufferAttachmentParameteriv) - INIT_GLES_FUNC(glGetIntegerv) - INIT_GLES_FUNC(glGetProgramiv) - INIT_GLES_FUNC(glGetProgramInfoLog) - INIT_GLES_FUNC(glGetRenderbufferParameteriv) - INIT_GLES_FUNC(glGetShaderiv) - INIT_GLES_FUNC(glGetShaderInfoLog) - INIT_GLES_FUNC(glGetShaderPrecisionFormat) - INIT_GLES_FUNC(glGetShaderSource) - INIT_GLES_FUNC(glGetTexParameterfv) - INIT_GLES_FUNC(glGetTexParameteriv) - INIT_GLES_FUNC(glGetUniformfv) - INIT_GLES_FUNC(glGetUniformiv) - INIT_GLES_FUNC(glGetUniformLocation) - INIT_GLES_FUNC(glGetVertexAttribfv) - INIT_GLES_FUNC(glGetVertexAttribiv) - INIT_GLES_FUNC(glGetVertexAttribPointerv) - INIT_GLES_FUNC(glHint) - INIT_GLES_FUNC(glIsBuffer) - INIT_GLES_FUNC(glIsEnabled) - INIT_GLES_FUNC(glIsFramebuffer) - INIT_GLES_FUNC(glIsProgram) - INIT_GLES_FUNC(glIsRenderbuffer) - INIT_GLES_FUNC(glIsShader) - INIT_GLES_FUNC(glIsTexture) - INIT_GLES_FUNC(glLineWidth) - INIT_GLES_FUNC(glLinkProgram) - INIT_GLES_FUNC(glPixelStorei) - INIT_GLES_FUNC(glPolygonOffset) - INIT_GLES_FUNC(glReadPixels) - INIT_GLES_FUNC(glReleaseShaderCompiler) - INIT_GLES_FUNC(glRenderbufferStorage) - INIT_GLES_FUNC(glSampleCoverage) - INIT_GLES_FUNC(glScissor) - INIT_GLES_FUNC(glShaderBinary) - INIT_GLES_FUNC(glShaderSource) - INIT_GLES_FUNC(glStencilFunc) - INIT_GLES_FUNC(glStencilFuncSeparate) - INIT_GLES_FUNC(glStencilMask) - INIT_GLES_FUNC(glStencilMaskSeparate) - INIT_GLES_FUNC(glStencilOp) - INIT_GLES_FUNC(glStencilOpSeparate) - // INIT_GLES_FUNC(glTexImage1D) - INIT_GLES_FUNC(glTexImage2D) - // INIT_GLES_FUNC(glTexStorage1D) - INIT_GLES_FUNC(glTexParameterf) - INIT_GLES_FUNC(glTexParameterfv) - INIT_GLES_FUNC(glTexParameteri) - INIT_GLES_FUNC(glTexParameteriv) - INIT_GLES_FUNC(glTexSubImage2D) - INIT_GLES_FUNC(glUniform1f) - INIT_GLES_FUNC(glUniform1fv) - INIT_GLES_FUNC(glUniform1i) - INIT_GLES_FUNC(glUniform1iv) - INIT_GLES_FUNC(glUniform2f) - INIT_GLES_FUNC(glUniform2fv) - INIT_GLES_FUNC(glUniform2i) - INIT_GLES_FUNC(glUniform2iv) - INIT_GLES_FUNC(glUniform3f) - INIT_GLES_FUNC(glUniform3fv) - INIT_GLES_FUNC(glUniform3i) - INIT_GLES_FUNC(glUniform3iv) - INIT_GLES_FUNC(glUniform4f) - INIT_GLES_FUNC(glUniform4fv) - INIT_GLES_FUNC(glUniform4i) - INIT_GLES_FUNC(glUniform4iv) - INIT_GLES_FUNC(glUniformMatrix2fv) - INIT_GLES_FUNC(glUniformMatrix3fv) - INIT_GLES_FUNC(glUniformMatrix4fv) - INIT_GLES_FUNC(glUseProgram) - INIT_GLES_FUNC(glValidateProgram) - INIT_GLES_FUNC(glVertexAttrib1f) - INIT_GLES_FUNC(glVertexAttrib1fv) - INIT_GLES_FUNC(glVertexAttrib2f) - INIT_GLES_FUNC(glVertexAttrib2fv) - INIT_GLES_FUNC(glVertexAttrib3f) - INIT_GLES_FUNC(glVertexAttrib3fv) - INIT_GLES_FUNC(glVertexAttrib4f) - INIT_GLES_FUNC(glVertexAttrib4fv) - INIT_GLES_FUNC(glVertexAttribPointer) - INIT_GLES_FUNC(glViewport) - INIT_GLES_FUNC(glReadBuffer) - INIT_GLES_FUNC(glDrawRangeElements) - INIT_GLES_FUNC(glTexImage3D) - INIT_GLES_FUNC(glTexSubImage3D) - INIT_GLES_FUNC(glCopyTexSubImage3D) - INIT_GLES_FUNC(glCompressedTexImage3D) - INIT_GLES_FUNC(glCompressedTexSubImage3D) - INIT_GLES_FUNC(glGenQueries) - INIT_GLES_FUNC(glDeleteQueries) - INIT_GLES_FUNC(glIsQuery) - INIT_GLES_FUNC(glBeginQuery) - INIT_GLES_FUNC(glEndQuery) - INIT_GLES_FUNC(glGetQueryiv) - INIT_GLES_FUNC(glGetQueryObjectuiv) - INIT_GLES_FUNC(glUnmapBuffer) - INIT_GLES_FUNC(glGetBufferPointerv) - INIT_GLES_FUNC(glDrawBuffers) - INIT_GLES_FUNC(glUniformMatrix2x3fv) - INIT_GLES_FUNC(glUniformMatrix3x2fv) - INIT_GLES_FUNC(glUniformMatrix2x4fv) - INIT_GLES_FUNC(glUniformMatrix4x2fv) - INIT_GLES_FUNC(glUniformMatrix3x4fv) - INIT_GLES_FUNC(glUniformMatrix4x3fv) - INIT_GLES_FUNC(glBlitFramebuffer) - INIT_GLES_FUNC(glRenderbufferStorageMultisample) - INIT_GLES_FUNC(glFramebufferTextureLayer) - INIT_GLES_FUNC(glFlushMappedBufferRange) - INIT_GLES_FUNC(glBindVertexArray) - INIT_GLES_FUNC(glDeleteVertexArrays) - INIT_GLES_FUNC(glGenVertexArrays) - INIT_GLES_FUNC(glIsVertexArray) - INIT_GLES_FUNC(glGetIntegeri_v) - INIT_GLES_FUNC(glBeginTransformFeedback) - INIT_GLES_FUNC(glEndTransformFeedback) - INIT_GLES_FUNC(glBindBufferRange) - INIT_GLES_FUNC(glBindBufferBase) - INIT_GLES_FUNC(glTransformFeedbackVaryings) - INIT_GLES_FUNC(glGetTransformFeedbackVarying) - INIT_GLES_FUNC(glVertexAttribIPointer) - INIT_GLES_FUNC(glGetVertexAttribIiv) - INIT_GLES_FUNC(glGetVertexAttribIuiv) - INIT_GLES_FUNC(glVertexAttribI4i) - INIT_GLES_FUNC(glVertexAttribI4ui) - INIT_GLES_FUNC(glVertexAttribI4iv) - INIT_GLES_FUNC(glVertexAttribI4uiv) - INIT_GLES_FUNC(glGetUniformuiv) - INIT_GLES_FUNC(glGetFragDataLocation) - INIT_GLES_FUNC(glUniform1ui) - INIT_GLES_FUNC(glUniform2ui) - INIT_GLES_FUNC(glUniform3ui) - INIT_GLES_FUNC(glUniform4ui) - INIT_GLES_FUNC(glUniform1uiv) - INIT_GLES_FUNC(glUniform2uiv) - INIT_GLES_FUNC(glUniform3uiv) - INIT_GLES_FUNC(glUniform4uiv) - INIT_GLES_FUNC(glClearBufferiv) - INIT_GLES_FUNC(glClearBufferuiv) - INIT_GLES_FUNC(glClearBufferfv) - INIT_GLES_FUNC(glClearBufferfi) - INIT_GLES_FUNC(glCopyBufferSubData) - INIT_GLES_FUNC(glGetUniformIndices) - INIT_GLES_FUNC(glGetActiveUniformsiv) - INIT_GLES_FUNC(glGetUniformBlockIndex) - INIT_GLES_FUNC(glGetActiveUniformBlockiv) - INIT_GLES_FUNC(glGetActiveUniformBlockName) - INIT_GLES_FUNC(glUniformBlockBinding) - INIT_GLES_FUNC(glDrawArraysInstanced) - INIT_GLES_FUNC(glDrawElementsInstanced) - INIT_GLES_FUNC(glFenceSync) - INIT_GLES_FUNC(glIsSync) - INIT_GLES_FUNC(glDeleteSync) - INIT_GLES_FUNC(glClientWaitSync) - INIT_GLES_FUNC(glWaitSync) - INIT_GLES_FUNC(glGetInteger64v) - INIT_GLES_FUNC(glGetSynciv) - INIT_GLES_FUNC(glGetInteger64i_v) - INIT_GLES_FUNC(glGetBufferParameteri64v) - INIT_GLES_FUNC(glGenSamplers) - INIT_GLES_FUNC(glDeleteSamplers) - INIT_GLES_FUNC(glIsSampler) - INIT_GLES_FUNC(glBindSampler) - INIT_GLES_FUNC(glSamplerParameteri) - INIT_GLES_FUNC(glSamplerParameteriv) - INIT_GLES_FUNC(glSamplerParameterf) - INIT_GLES_FUNC(glSamplerParameterfv) - INIT_GLES_FUNC(glGetSamplerParameteriv) - INIT_GLES_FUNC(glGetSamplerParameterfv) - INIT_GLES_FUNC(glVertexAttribDivisor) - INIT_GLES_FUNC(glBindTransformFeedback) - INIT_GLES_FUNC(glDeleteTransformFeedbacks) - INIT_GLES_FUNC(glGenTransformFeedbacks) - INIT_GLES_FUNC(glIsTransformFeedback) - INIT_GLES_FUNC(glPauseTransformFeedback) - INIT_GLES_FUNC(glResumeTransformFeedback) - INIT_GLES_FUNC(glGetProgramBinary) - INIT_GLES_FUNC(glProgramBinary) - INIT_GLES_FUNC(glProgramParameteri) - INIT_GLES_FUNC(glInvalidateFramebuffer) - INIT_GLES_FUNC(glInvalidateSubFramebuffer) - INIT_GLES_FUNC(glTexStorage2D) - INIT_GLES_FUNC(glTexStorage3D) - INIT_GLES_FUNC(glGetInternalformativ) - INIT_GLES_FUNC(glDispatchCompute) - INIT_GLES_FUNC(glDispatchComputeIndirect) - INIT_GLES_FUNC(glDrawArraysIndirect) - INIT_GLES_FUNC(glDrawElementsIndirect) - INIT_GLES_FUNC(glFramebufferParameteri) - INIT_GLES_FUNC(glGetFramebufferParameteriv) - INIT_GLES_FUNC(glGetProgramInterfaceiv) - INIT_GLES_FUNC(glGetProgramResourceIndex) - INIT_GLES_FUNC(glGetProgramResourceName) - INIT_GLES_FUNC(glGetProgramResourceiv) - INIT_GLES_FUNC(glGetProgramResourceLocation) - INIT_GLES_FUNC(glUseProgramStages) - INIT_GLES_FUNC(glActiveShaderProgram) - INIT_GLES_FUNC(glCreateShaderProgramv) - INIT_GLES_FUNC(glBindProgramPipeline) - INIT_GLES_FUNC(glDeleteProgramPipelines) - INIT_GLES_FUNC(glGenProgramPipelines) - INIT_GLES_FUNC(glIsProgramPipeline) - INIT_GLES_FUNC(glGetProgramPipelineiv) - INIT_GLES_FUNC(glProgramUniform1i) - INIT_GLES_FUNC(glProgramUniform2i) - INIT_GLES_FUNC(glProgramUniform3i) - INIT_GLES_FUNC(glProgramUniform4i) - INIT_GLES_FUNC(glProgramUniform1ui) - INIT_GLES_FUNC(glProgramUniform2ui) - INIT_GLES_FUNC(glProgramUniform3ui) - INIT_GLES_FUNC(glProgramUniform4ui) - INIT_GLES_FUNC(glProgramUniform1f) - INIT_GLES_FUNC(glProgramUniform2f) - INIT_GLES_FUNC(glProgramUniform3f) - INIT_GLES_FUNC(glProgramUniform4f) - INIT_GLES_FUNC(glProgramUniform1iv) - INIT_GLES_FUNC(glProgramUniform2iv) - INIT_GLES_FUNC(glProgramUniform3iv) - INIT_GLES_FUNC(glProgramUniform4iv) - INIT_GLES_FUNC(glProgramUniform1uiv) - INIT_GLES_FUNC(glProgramUniform2uiv) - INIT_GLES_FUNC(glProgramUniform3uiv) - INIT_GLES_FUNC(glProgramUniform4uiv) - INIT_GLES_FUNC(glProgramUniform1fv) - INIT_GLES_FUNC(glProgramUniform2fv) - INIT_GLES_FUNC(glProgramUniform3fv) - INIT_GLES_FUNC(glProgramUniform4fv) - INIT_GLES_FUNC(glProgramUniformMatrix2fv) - INIT_GLES_FUNC(glProgramUniformMatrix3fv) - INIT_GLES_FUNC(glProgramUniformMatrix4fv) - INIT_GLES_FUNC(glProgramUniformMatrix2x3fv) - INIT_GLES_FUNC(glProgramUniformMatrix3x2fv) - INIT_GLES_FUNC(glProgramUniformMatrix2x4fv) - INIT_GLES_FUNC(glProgramUniformMatrix4x2fv) - INIT_GLES_FUNC(glProgramUniformMatrix3x4fv) - INIT_GLES_FUNC(glProgramUniformMatrix4x3fv) - INIT_GLES_FUNC(glValidateProgramPipeline) - INIT_GLES_FUNC(glGetProgramPipelineInfoLog) - INIT_GLES_FUNC(glBindImageTexture) - INIT_GLES_FUNC(glGetBooleani_v) - INIT_GLES_FUNC(glMemoryBarrier) - INIT_GLES_FUNC(glMemoryBarrierByRegion) - INIT_GLES_FUNC(glTexStorage2DMultisample) - INIT_GLES_FUNC(glGetMultisamplefv) - INIT_GLES_FUNC(glSampleMaski) - INIT_GLES_FUNC(glGetTexLevelParameteriv) - INIT_GLES_FUNC(glGetTexLevelParameterfv) - INIT_GLES_FUNC(glBindVertexBuffer) - INIT_GLES_FUNC(glVertexAttribFormat) - INIT_GLES_FUNC(glVertexAttribIFormat) - INIT_GLES_FUNC(glVertexAttribBinding) - INIT_GLES_FUNC(glVertexBindingDivisor) - INIT_GLES_FUNC(glBlendBarrier) - INIT_GLES_FUNC(glCopyImageSubData) - INIT_GLES_FUNC(glDebugMessageControl) - INIT_GLES_FUNC(glDebugMessageInsert) - INIT_GLES_FUNC(glDebugMessageCallback) - INIT_GLES_FUNC(glGetDebugMessageLog) - INIT_GLES_FUNC(glPushDebugGroup) - INIT_GLES_FUNC(glPopDebugGroup) - INIT_GLES_FUNC(glObjectLabel) - INIT_GLES_FUNC(glGetObjectLabel) - INIT_GLES_FUNC(glObjectPtrLabel) - INIT_GLES_FUNC(glGetObjectPtrLabel) - INIT_GLES_FUNC(glGetPointerv) - INIT_GLES_FUNC(glEnablei) - INIT_GLES_FUNC(glDisablei) - INIT_GLES_FUNC(glBlendEquationi) - INIT_GLES_FUNC(glBlendEquationSeparatei) - INIT_GLES_FUNC(glBlendFunci) - INIT_GLES_FUNC(glBlendFuncSeparatei) - INIT_GLES_FUNC(glColorMaski) - INIT_GLES_FUNC(glIsEnabledi) - INIT_GLES_FUNC(glDrawElementsBaseVertex) - INIT_GLES_FUNC(glDrawRangeElementsBaseVertex) - INIT_GLES_FUNC(glDrawElementsInstancedBaseVertex) - INIT_GLES_FUNC(glFramebufferTexture) - INIT_GLES_FUNC(glPrimitiveBoundingBox) - INIT_GLES_FUNC(glGetGraphicsResetStatus) - INIT_GLES_FUNC(glReadnPixels) - INIT_GLES_FUNC(glGetnUniformfv) - INIT_GLES_FUNC(glGetnUniformiv) - INIT_GLES_FUNC(glGetnUniformuiv) - INIT_GLES_FUNC(glMinSampleShading) - INIT_GLES_FUNC(glPatchParameteri) - INIT_GLES_FUNC(glTexParameterIiv) - INIT_GLES_FUNC(glTexParameterIuiv) - INIT_GLES_FUNC(glGetTexParameterIiv) - INIT_GLES_FUNC(glGetTexParameterIuiv) - INIT_GLES_FUNC(glSamplerParameterIiv) - INIT_GLES_FUNC(glSamplerParameterIuiv) - INIT_GLES_FUNC(glGetSamplerParameterIiv) - INIT_GLES_FUNC(glGetSamplerParameterIuiv) - INIT_GLES_FUNC(glTexBuffer) - INIT_GLES_FUNC(glTexBufferRange) - INIT_GLES_FUNC(glTexStorage3DMultisample) - INIT_GLES_FUNC(glMapBufferRange) - INIT_GLES_FUNC(glBufferStorageEXT) - INIT_GLES_FUNC(glGetQueryObjectivEXT) - INIT_GLES_FUNC(glGetQueryObjecti64vEXT) - INIT_GLES_FUNC(glBindFragDataLocationEXT) - INIT_GLES_FUNC(glMapBufferOES) - INIT_GLES_FUNC(glMultiDrawArraysIndirectEXT) - INIT_GLES_FUNC(glMultiDrawElementsIndirectEXT) - INIT_GLES_FUNC(glMultiDrawElementsBaseVertexEXT) - - InitGLESCapabilities(); - } - - static EGLDisplay eglDisplay = EGL_NO_DISPLAY; - static EGLSurface eglSurface = EGL_NO_SURFACE; - static EGLContext eglContext = EGL_NO_CONTEXT; - -#define INIT_EGL_FUNC(name) \ - if (libEGL != NULL) { \ - MG_External::EGL::name = (MG_External::EGL::name##_PTR)ProcAddress(libEGL, #name); \ + return nullptr; } - void InitEGL() { - INIT_EGL_FUNC(eglBindAPI) - INIT_EGL_FUNC(eglBindTexImage) - INIT_EGL_FUNC(eglChooseConfig) - INIT_EGL_FUNC(eglCopyBuffers) - INIT_EGL_FUNC(eglCreateContext) - INIT_EGL_FUNC(eglCreatePbufferFromClientBuffer) - INIT_EGL_FUNC(eglCreatePbufferSurface) - INIT_EGL_FUNC(eglCreatePixmapSurface) - INIT_EGL_FUNC(eglCreatePlatformPixmapSurface) - INIT_EGL_FUNC(eglCreatePlatformWindowSurface) - INIT_EGL_FUNC(eglCreateWindowSurface) - INIT_EGL_FUNC(eglDestroyContext) - INIT_EGL_FUNC(eglDestroySurface) - INIT_EGL_FUNC(eglGetConfigAttrib) - INIT_EGL_FUNC(eglGetConfigs) - INIT_EGL_FUNC(eglGetCurrentContext) - INIT_EGL_FUNC(eglGetCurrentDisplay) - INIT_EGL_FUNC(eglGetCurrentSurface) - INIT_EGL_FUNC(eglGetDisplay) - INIT_EGL_FUNC(eglGetPlatformDisplay) - INIT_EGL_FUNC(eglGetError) - INIT_EGL_FUNC(eglGetProcAddress) - INIT_EGL_FUNC(eglInitialize) - INIT_EGL_FUNC(eglMakeCurrent) - INIT_EGL_FUNC(eglQueryAPI) - INIT_EGL_FUNC(eglQueryContext) - INIT_EGL_FUNC(eglQueryString) - INIT_EGL_FUNC(eglQuerySurface) - INIT_EGL_FUNC(eglReleaseTexImage) - INIT_EGL_FUNC(eglReleaseThread) - INIT_EGL_FUNC(eglSurfaceAttrib) - INIT_EGL_FUNC(eglSwapBuffers) - INIT_EGL_FUNC(eglSwapBuffersWithDamageEXT) - INIT_EGL_FUNC(eglSwapInterval) - INIT_EGL_FUNC(eglTerminate) - INIT_EGL_FUNC(eglUnlockSurfaceKHR) - INIT_EGL_FUNC(eglWaitClient) - INIT_EGL_FUNC(eglWaitGL) - INIT_EGL_FUNC(eglWaitNative) - INIT_EGL_FUNC(eglCreateSync) - INIT_EGL_FUNC(eglDestroySync) - INIT_EGL_FUNC(eglClientWaitSync) - INIT_EGL_FUNC(eglGetSyncAttrib) - INIT_EGL_FUNC(eglCreateImage) - INIT_EGL_FUNC(eglDestroyImage) - INIT_EGL_FUNC(eglGetPlatformDisplay) - INIT_EGL_FUNC(eglWaitSync) - EGLint configAttribs[] = {EGL_RED_SIZE, - 8, - EGL_GREEN_SIZE, - 8, - EGL_BLUE_SIZE, - 8, - EGL_ALPHA_SIZE, - 8, - EGL_SURFACE_TYPE, - EGL_PBUFFER_BIT, - EGL_RENDERABLE_TYPE, - EGL_OPENGL_ES2_BIT, - EGL_NONE}; + inline void* ProcAddress(void* lib, const char* name) { +#if !defined(__WIN32) && !defined(_WIN32) && !defined(__APPLE__) + return dlsym(lib, name); +#else + return nullptrptr; +#endif + } - EGLint ctxAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; + Bool AcquireGLESFunctions(MG_External::GLESFunctionsTable& funcs, + MG_External::EGL::eglGetProcAddress_PTR procAddress) { + if (!procAddress) { + MGLOG_E("eglGetProcAddress is nullptr, cannot load GLES functions"); + return false; + } - EGLint pbAttribs[] = {EGL_WIDTH, 32, EGL_HEIGHT, 32, EGL_NONE}; +#define INIT_GLES_FUNC(name) \ + do { \ + funcs.name = (MG_External::GLES::name##_PTR)procAddress(#name); \ + if (!funcs.name) { \ + MGLOG_E("Failed to load GLES function: %s", #name); \ + } \ + } while (0); - EGLConfig pbufConfig; - EGLint configsFound = 0; + { + INIT_GLES_FUNC(glActiveTexture) + INIT_GLES_FUNC(glAttachShader) + INIT_GLES_FUNC(glBindAttribLocation) + INIT_GLES_FUNC(glBindBuffer) + INIT_GLES_FUNC(glBindFramebuffer) + INIT_GLES_FUNC(glBindRenderbuffer) + INIT_GLES_FUNC(glBindTexture) + INIT_GLES_FUNC(glBlendColor) + INIT_GLES_FUNC(glBlendEquation) + INIT_GLES_FUNC(glBlendEquationSeparate) + INIT_GLES_FUNC(glBlendFunc) + INIT_GLES_FUNC(glBlendFuncSeparate) + INIT_GLES_FUNC(glBufferData) + INIT_GLES_FUNC(glBufferSubData) + INIT_GLES_FUNC(glCheckFramebufferStatus) + INIT_GLES_FUNC(glClear) + INIT_GLES_FUNC(glClearColor) + INIT_GLES_FUNC(glClearDepthf) + INIT_GLES_FUNC(glClearStencil) + INIT_GLES_FUNC(glColorMask) + INIT_GLES_FUNC(glCompileShader) + INIT_GLES_FUNC(glCompressedTexImage2D) + INIT_GLES_FUNC(glCompressedTexSubImage2D) + // INIT_GLES_FUNC(glCopyTexImage1D) + INIT_GLES_FUNC(glCopyTexImage2D) + INIT_GLES_FUNC(glCopyTexSubImage2D) + INIT_GLES_FUNC(glCreateProgram) + INIT_GLES_FUNC(glCreateShader) + INIT_GLES_FUNC(glCullFace) + INIT_GLES_FUNC(glDeleteBuffers) + INIT_GLES_FUNC(glDeleteFramebuffers) + INIT_GLES_FUNC(glDeleteProgram) + INIT_GLES_FUNC(glDeleteRenderbuffers) + INIT_GLES_FUNC(glDeleteShader) + INIT_GLES_FUNC(glDeleteTextures) + INIT_GLES_FUNC(glDepthFunc) + INIT_GLES_FUNC(glDepthMask) + INIT_GLES_FUNC(glDepthRangef) + INIT_GLES_FUNC(glDetachShader) + INIT_GLES_FUNC(glDisable) + INIT_GLES_FUNC(glDisableVertexAttribArray) + INIT_GLES_FUNC(glDrawArrays) + INIT_GLES_FUNC(glDrawElements) + INIT_GLES_FUNC(glEnable) + INIT_GLES_FUNC(glEnableVertexAttribArray) + INIT_GLES_FUNC(glFinish) + INIT_GLES_FUNC(glFlush) + INIT_GLES_FUNC(glFramebufferRenderbuffer) + INIT_GLES_FUNC(glFramebufferTexture2D) + INIT_GLES_FUNC(glFrontFace) + INIT_GLES_FUNC(glGenBuffers) + INIT_GLES_FUNC(glGenerateMipmap) + INIT_GLES_FUNC(glGenFramebuffers) + INIT_GLES_FUNC(glGenRenderbuffers) + INIT_GLES_FUNC(glGenTextures) + INIT_GLES_FUNC(glGetActiveAttrib) + INIT_GLES_FUNC(glGetActiveUniform) + INIT_GLES_FUNC(glGetAttachedShaders) + INIT_GLES_FUNC(glGetAttribLocation) + INIT_GLES_FUNC(glGetBooleanv) + INIT_GLES_FUNC(glGetBufferParameteriv) + INIT_GLES_FUNC(glGetError) + INIT_GLES_FUNC(glGetString) + INIT_GLES_FUNC(glGetStringi) + INIT_GLES_FUNC(glGetFloatv) + INIT_GLES_FUNC(glGetFramebufferAttachmentParameteriv) + INIT_GLES_FUNC(glGetIntegerv) + INIT_GLES_FUNC(glGetProgramiv) + INIT_GLES_FUNC(glGetProgramInfoLog) + INIT_GLES_FUNC(glGetRenderbufferParameteriv) + INIT_GLES_FUNC(glGetShaderiv) + INIT_GLES_FUNC(glGetShaderInfoLog) + INIT_GLES_FUNC(glGetShaderPrecisionFormat) + INIT_GLES_FUNC(glGetShaderSource) + INIT_GLES_FUNC(glGetTexParameterfv) + INIT_GLES_FUNC(glGetTexParameteriv) + INIT_GLES_FUNC(glGetUniformfv) + INIT_GLES_FUNC(glGetUniformiv) + INIT_GLES_FUNC(glGetUniformLocation) + INIT_GLES_FUNC(glGetVertexAttribfv) + INIT_GLES_FUNC(glGetVertexAttribiv) + INIT_GLES_FUNC(glGetVertexAttribPointerv) + INIT_GLES_FUNC(glHint) + INIT_GLES_FUNC(glIsBuffer) + INIT_GLES_FUNC(glIsEnabled) + INIT_GLES_FUNC(glIsFramebuffer) + INIT_GLES_FUNC(glIsProgram) + INIT_GLES_FUNC(glIsRenderbuffer) + INIT_GLES_FUNC(glIsShader) + INIT_GLES_FUNC(glIsTexture) + INIT_GLES_FUNC(glLineWidth) + INIT_GLES_FUNC(glLinkProgram) + INIT_GLES_FUNC(glPixelStorei) + INIT_GLES_FUNC(glPolygonOffset) + INIT_GLES_FUNC(glReadPixels) + INIT_GLES_FUNC(glReleaseShaderCompiler) + INIT_GLES_FUNC(glRenderbufferStorage) + INIT_GLES_FUNC(glSampleCoverage) + INIT_GLES_FUNC(glScissor) + INIT_GLES_FUNC(glShaderBinary) + INIT_GLES_FUNC(glShaderSource) + INIT_GLES_FUNC(glStencilFunc) + INIT_GLES_FUNC(glStencilFuncSeparate) + INIT_GLES_FUNC(glStencilMask) + INIT_GLES_FUNC(glStencilMaskSeparate) + INIT_GLES_FUNC(glStencilOp) + INIT_GLES_FUNC(glStencilOpSeparate) + // INIT_GLES_FUNC(glTexImage1D) + INIT_GLES_FUNC(glTexImage2D) + // INIT_GLES_FUNC(glTexStorage1D) + INIT_GLES_FUNC(glTexParameterf) + INIT_GLES_FUNC(glTexParameterfv) + INIT_GLES_FUNC(glTexParameteri) + INIT_GLES_FUNC(glTexParameteriv) + INIT_GLES_FUNC(glTexSubImage2D) + INIT_GLES_FUNC(glUniform1f) + INIT_GLES_FUNC(glUniform1fv) + INIT_GLES_FUNC(glUniform1i) + INIT_GLES_FUNC(glUniform1iv) + INIT_GLES_FUNC(glUniform2f) + INIT_GLES_FUNC(glUniform2fv) + INIT_GLES_FUNC(glUniform2i) + INIT_GLES_FUNC(glUniform2iv) + INIT_GLES_FUNC(glUniform3f) + INIT_GLES_FUNC(glUniform3fv) + INIT_GLES_FUNC(glUniform3i) + INIT_GLES_FUNC(glUniform3iv) + INIT_GLES_FUNC(glUniform4f) + INIT_GLES_FUNC(glUniform4fv) + INIT_GLES_FUNC(glUniform4i) + INIT_GLES_FUNC(glUniform4iv) + INIT_GLES_FUNC(glUniformMatrix2fv) + INIT_GLES_FUNC(glUniformMatrix3fv) + INIT_GLES_FUNC(glUniformMatrix4fv) + INIT_GLES_FUNC(glUseProgram) + INIT_GLES_FUNC(glValidateProgram) + INIT_GLES_FUNC(glVertexAttrib1f) + INIT_GLES_FUNC(glVertexAttrib1fv) + INIT_GLES_FUNC(glVertexAttrib2f) + INIT_GLES_FUNC(glVertexAttrib2fv) + INIT_GLES_FUNC(glVertexAttrib3f) + INIT_GLES_FUNC(glVertexAttrib3fv) + INIT_GLES_FUNC(glVertexAttrib4f) + INIT_GLES_FUNC(glVertexAttrib4fv) + INIT_GLES_FUNC(glVertexAttribPointer) + INIT_GLES_FUNC(glViewport) + INIT_GLES_FUNC(glReadBuffer) + INIT_GLES_FUNC(glDrawRangeElements) + INIT_GLES_FUNC(glTexImage3D) + INIT_GLES_FUNC(glTexSubImage3D) + INIT_GLES_FUNC(glCopyTexSubImage3D) + INIT_GLES_FUNC(glCompressedTexImage3D) + INIT_GLES_FUNC(glCompressedTexSubImage3D) + INIT_GLES_FUNC(glGenQueries) + INIT_GLES_FUNC(glDeleteQueries) + INIT_GLES_FUNC(glIsQuery) + INIT_GLES_FUNC(glBeginQuery) + INIT_GLES_FUNC(glEndQuery) + INIT_GLES_FUNC(glGetQueryiv) + INIT_GLES_FUNC(glGetQueryObjectuiv) + INIT_GLES_FUNC(glUnmapBuffer) + INIT_GLES_FUNC(glGetBufferPointerv) + INIT_GLES_FUNC(glDrawBuffers) + INIT_GLES_FUNC(glUniformMatrix2x3fv) + INIT_GLES_FUNC(glUniformMatrix3x2fv) + INIT_GLES_FUNC(glUniformMatrix2x4fv) + INIT_GLES_FUNC(glUniformMatrix4x2fv) + INIT_GLES_FUNC(glUniformMatrix3x4fv) + INIT_GLES_FUNC(glUniformMatrix4x3fv) + INIT_GLES_FUNC(glBlitFramebuffer) + INIT_GLES_FUNC(glRenderbufferStorageMultisample) + INIT_GLES_FUNC(glFramebufferTextureLayer) + INIT_GLES_FUNC(glFlushMappedBufferRange) + INIT_GLES_FUNC(glBindVertexArray) + INIT_GLES_FUNC(glDeleteVertexArrays) + INIT_GLES_FUNC(glGenVertexArrays) + INIT_GLES_FUNC(glIsVertexArray) + INIT_GLES_FUNC(glGetIntegeri_v) + INIT_GLES_FUNC(glBeginTransformFeedback) + INIT_GLES_FUNC(glEndTransformFeedback) + INIT_GLES_FUNC(glBindBufferRange) + INIT_GLES_FUNC(glBindBufferBase) + INIT_GLES_FUNC(glTransformFeedbackVaryings) + INIT_GLES_FUNC(glGetTransformFeedbackVarying) + INIT_GLES_FUNC(glVertexAttribIPointer) + INIT_GLES_FUNC(glGetVertexAttribIiv) + INIT_GLES_FUNC(glGetVertexAttribIuiv) + INIT_GLES_FUNC(glVertexAttribI4i) + INIT_GLES_FUNC(glVertexAttribI4ui) + INIT_GLES_FUNC(glVertexAttribI4iv) + INIT_GLES_FUNC(glVertexAttribI4uiv) + INIT_GLES_FUNC(glGetUniformuiv) + INIT_GLES_FUNC(glGetFragDataLocation) + INIT_GLES_FUNC(glUniform1ui) + INIT_GLES_FUNC(glUniform2ui) + INIT_GLES_FUNC(glUniform3ui) + INIT_GLES_FUNC(glUniform4ui) + INIT_GLES_FUNC(glUniform1uiv) + INIT_GLES_FUNC(glUniform2uiv) + INIT_GLES_FUNC(glUniform3uiv) + INIT_GLES_FUNC(glUniform4uiv) + INIT_GLES_FUNC(glClearBufferiv) + INIT_GLES_FUNC(glClearBufferuiv) + INIT_GLES_FUNC(glClearBufferfv) + INIT_GLES_FUNC(glClearBufferfi) + INIT_GLES_FUNC(glCopyBufferSubData) + INIT_GLES_FUNC(glGetUniformIndices) + INIT_GLES_FUNC(glGetActiveUniformsiv) + INIT_GLES_FUNC(glGetUniformBlockIndex) + INIT_GLES_FUNC(glGetActiveUniformBlockiv) + INIT_GLES_FUNC(glGetActiveUniformBlockName) + INIT_GLES_FUNC(glUniformBlockBinding) + INIT_GLES_FUNC(glDrawArraysInstanced) + INIT_GLES_FUNC(glDrawElementsInstanced) + INIT_GLES_FUNC(glFenceSync) + INIT_GLES_FUNC(glIsSync) + INIT_GLES_FUNC(glDeleteSync) + INIT_GLES_FUNC(glClientWaitSync) + INIT_GLES_FUNC(glWaitSync) + INIT_GLES_FUNC(glGetInteger64v) + INIT_GLES_FUNC(glGetSynciv) + INIT_GLES_FUNC(glGetInteger64i_v) + INIT_GLES_FUNC(glGetBufferParameteri64v) + INIT_GLES_FUNC(glGenSamplers) + INIT_GLES_FUNC(glDeleteSamplers) + INIT_GLES_FUNC(glIsSampler) + INIT_GLES_FUNC(glBindSampler) + INIT_GLES_FUNC(glSamplerParameteri) + INIT_GLES_FUNC(glSamplerParameteriv) + INIT_GLES_FUNC(glSamplerParameterf) + INIT_GLES_FUNC(glSamplerParameterfv) + INIT_GLES_FUNC(glGetSamplerParameteriv) + INIT_GLES_FUNC(glGetSamplerParameterfv) + INIT_GLES_FUNC(glVertexAttribDivisor) + INIT_GLES_FUNC(glBindTransformFeedback) + INIT_GLES_FUNC(glDeleteTransformFeedbacks) + INIT_GLES_FUNC(glGenTransformFeedbacks) + INIT_GLES_FUNC(glIsTransformFeedback) + INIT_GLES_FUNC(glPauseTransformFeedback) + INIT_GLES_FUNC(glResumeTransformFeedback) + INIT_GLES_FUNC(glGetProgramBinary) + INIT_GLES_FUNC(glProgramBinary) + INIT_GLES_FUNC(glProgramParameteri) + INIT_GLES_FUNC(glInvalidateFramebuffer) + INIT_GLES_FUNC(glInvalidateSubFramebuffer) + INIT_GLES_FUNC(glTexStorage2D) + INIT_GLES_FUNC(glTexStorage3D) + INIT_GLES_FUNC(glGetInternalformativ) + INIT_GLES_FUNC(glDispatchCompute) + INIT_GLES_FUNC(glDispatchComputeIndirect) + INIT_GLES_FUNC(glDrawArraysIndirect) + INIT_GLES_FUNC(glDrawElementsIndirect) + INIT_GLES_FUNC(glFramebufferParameteri) + INIT_GLES_FUNC(glGetFramebufferParameteriv) + INIT_GLES_FUNC(glGetProgramInterfaceiv) + INIT_GLES_FUNC(glGetProgramResourceIndex) + INIT_GLES_FUNC(glGetProgramResourceName) + INIT_GLES_FUNC(glGetProgramResourceiv) + INIT_GLES_FUNC(glGetProgramResourceLocation) + INIT_GLES_FUNC(glUseProgramStages) + INIT_GLES_FUNC(glActiveShaderProgram) + INIT_GLES_FUNC(glCreateShaderProgramv) + INIT_GLES_FUNC(glBindProgramPipeline) + INIT_GLES_FUNC(glDeleteProgramPipelines) + INIT_GLES_FUNC(glGenProgramPipelines) + INIT_GLES_FUNC(glIsProgramPipeline) + INIT_GLES_FUNC(glGetProgramPipelineiv) + INIT_GLES_FUNC(glProgramUniform1i) + INIT_GLES_FUNC(glProgramUniform2i) + INIT_GLES_FUNC(glProgramUniform3i) + INIT_GLES_FUNC(glProgramUniform4i) + INIT_GLES_FUNC(glProgramUniform1ui) + INIT_GLES_FUNC(glProgramUniform2ui) + INIT_GLES_FUNC(glProgramUniform3ui) + INIT_GLES_FUNC(glProgramUniform4ui) + INIT_GLES_FUNC(glProgramUniform1f) + INIT_GLES_FUNC(glProgramUniform2f) + INIT_GLES_FUNC(glProgramUniform3f) + INIT_GLES_FUNC(glProgramUniform4f) + INIT_GLES_FUNC(glProgramUniform1iv) + INIT_GLES_FUNC(glProgramUniform2iv) + INIT_GLES_FUNC(glProgramUniform3iv) + INIT_GLES_FUNC(glProgramUniform4iv) + INIT_GLES_FUNC(glProgramUniform1uiv) + INIT_GLES_FUNC(glProgramUniform2uiv) + INIT_GLES_FUNC(glProgramUniform3uiv) + INIT_GLES_FUNC(glProgramUniform4uiv) + INIT_GLES_FUNC(glProgramUniform1fv) + INIT_GLES_FUNC(glProgramUniform2fv) + INIT_GLES_FUNC(glProgramUniform3fv) + INIT_GLES_FUNC(glProgramUniform4fv) + INIT_GLES_FUNC(glProgramUniformMatrix2fv) + INIT_GLES_FUNC(glProgramUniformMatrix3fv) + INIT_GLES_FUNC(glProgramUniformMatrix4fv) + INIT_GLES_FUNC(glProgramUniformMatrix2x3fv) + INIT_GLES_FUNC(glProgramUniformMatrix3x2fv) + INIT_GLES_FUNC(glProgramUniformMatrix2x4fv) + INIT_GLES_FUNC(glProgramUniformMatrix4x2fv) + INIT_GLES_FUNC(glProgramUniformMatrix3x4fv) + INIT_GLES_FUNC(glProgramUniformMatrix4x3fv) + INIT_GLES_FUNC(glValidateProgramPipeline) + INIT_GLES_FUNC(glGetProgramPipelineInfoLog) + INIT_GLES_FUNC(glBindImageTexture) + INIT_GLES_FUNC(glGetBooleani_v) + INIT_GLES_FUNC(glMemoryBarrier) + INIT_GLES_FUNC(glMemoryBarrierByRegion) + INIT_GLES_FUNC(glTexStorage2DMultisample) + INIT_GLES_FUNC(glGetMultisamplefv) + INIT_GLES_FUNC(glSampleMaski) + INIT_GLES_FUNC(glGetTexLevelParameteriv) + INIT_GLES_FUNC(glGetTexLevelParameterfv) + INIT_GLES_FUNC(glBindVertexBuffer) + INIT_GLES_FUNC(glVertexAttribFormat) + INIT_GLES_FUNC(glVertexAttribIFormat) + INIT_GLES_FUNC(glVertexAttribBinding) + INIT_GLES_FUNC(glVertexBindingDivisor) + INIT_GLES_FUNC(glBlendBarrier) + INIT_GLES_FUNC(glCopyImageSubData) + INIT_GLES_FUNC(glDebugMessageControl) + INIT_GLES_FUNC(glDebugMessageInsert) + INIT_GLES_FUNC(glDebugMessageCallback) + INIT_GLES_FUNC(glGetDebugMessageLog) + INIT_GLES_FUNC(glPushDebugGroup) + INIT_GLES_FUNC(glPopDebugGroup) + INIT_GLES_FUNC(glObjectLabel) + INIT_GLES_FUNC(glGetObjectLabel) + INIT_GLES_FUNC(glObjectPtrLabel) + INIT_GLES_FUNC(glGetObjectPtrLabel) + INIT_GLES_FUNC(glGetPointerv) + INIT_GLES_FUNC(glEnablei) + INIT_GLES_FUNC(glDisablei) + INIT_GLES_FUNC(glBlendEquationi) + INIT_GLES_FUNC(glBlendEquationSeparatei) + INIT_GLES_FUNC(glBlendFunci) + INIT_GLES_FUNC(glBlendFuncSeparatei) + INIT_GLES_FUNC(glColorMaski) + INIT_GLES_FUNC(glIsEnabledi) + INIT_GLES_FUNC(glDrawElementsBaseVertex) + INIT_GLES_FUNC(glDrawRangeElementsBaseVertex) + INIT_GLES_FUNC(glDrawElementsInstancedBaseVertex) + INIT_GLES_FUNC(glFramebufferTexture) + INIT_GLES_FUNC(glPrimitiveBoundingBox) + INIT_GLES_FUNC(glGetGraphicsResetStatus) + INIT_GLES_FUNC(glReadnPixels) + INIT_GLES_FUNC(glGetnUniformfv) + INIT_GLES_FUNC(glGetnUniformiv) + INIT_GLES_FUNC(glGetnUniformuiv) + INIT_GLES_FUNC(glMinSampleShading) + INIT_GLES_FUNC(glPatchParameteri) + INIT_GLES_FUNC(glTexParameterIiv) + INIT_GLES_FUNC(glTexParameterIuiv) + INIT_GLES_FUNC(glGetTexParameterIiv) + INIT_GLES_FUNC(glGetTexParameterIuiv) + INIT_GLES_FUNC(glSamplerParameterIiv) + INIT_GLES_FUNC(glSamplerParameterIuiv) + INIT_GLES_FUNC(glGetSamplerParameterIiv) + INIT_GLES_FUNC(glGetSamplerParameterIuiv) + INIT_GLES_FUNC(glTexBuffer) + INIT_GLES_FUNC(glTexBufferRange) + INIT_GLES_FUNC(glTexStorage3DMultisample) + INIT_GLES_FUNC(glMapBufferRange) + INIT_GLES_FUNC(glBufferStorageEXT) + INIT_GLES_FUNC(glGetQueryObjectivEXT) + INIT_GLES_FUNC(glGetQueryObjecti64vEXT) + INIT_GLES_FUNC(glBindFragDataLocationEXT) + INIT_GLES_FUNC(glMapBufferOES) + INIT_GLES_FUNC(glMultiDrawArraysIndirectEXT) + INIT_GLES_FUNC(glMultiDrawElementsIndirectEXT) + INIT_GLES_FUNC(glMultiDrawElementsBaseVertexEXT) + } + return true; + } - eglDisplay = MG_External::EGL::eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (eglDisplay == EGL_NO_DISPLAY) { - goto cleanup; + Bool AcquireEGLFunctions(MG_External::EGLFunctionsTable& funcs) { + static const Vector EGLLibNames = {"libEGL.so"}; + void* eglLib = OpenLib(EGLLibNames); + if (!eglLib) { + MGLOG_E("Failed to open libEGL.so"); + return false; + } +#define INIT_EGL_FUNC(name) \ + do { \ + funcs.name = (MG_External::EGL::name##_PTR)ProcAddress(eglLib, #name); \ + if (!funcs.name) { \ + MGLOG_E("Failed to load EGL function: %s", #name); \ + } \ + } while (0); + + { + INIT_EGL_FUNC(eglBindAPI) + INIT_EGL_FUNC(eglBindTexImage) + INIT_EGL_FUNC(eglChooseConfig) + INIT_EGL_FUNC(eglCopyBuffers) + INIT_EGL_FUNC(eglCreateContext) + INIT_EGL_FUNC(eglCreatePbufferFromClientBuffer) + INIT_EGL_FUNC(eglCreatePbufferSurface) + INIT_EGL_FUNC(eglCreatePixmapSurface) + INIT_EGL_FUNC(eglCreatePlatformPixmapSurface) + INIT_EGL_FUNC(eglCreatePlatformWindowSurface) + INIT_EGL_FUNC(eglCreateWindowSurface) + INIT_EGL_FUNC(eglDestroyContext) + INIT_EGL_FUNC(eglDestroySurface) + INIT_EGL_FUNC(eglGetConfigAttrib) + INIT_EGL_FUNC(eglGetConfigs) + INIT_EGL_FUNC(eglGetCurrentContext) + INIT_EGL_FUNC(eglGetCurrentDisplay) + INIT_EGL_FUNC(eglGetCurrentSurface) + INIT_EGL_FUNC(eglGetDisplay) + INIT_EGL_FUNC(eglGetPlatformDisplay) + INIT_EGL_FUNC(eglGetError) + INIT_EGL_FUNC(eglGetProcAddress) + INIT_EGL_FUNC(eglInitialize) + INIT_EGL_FUNC(eglMakeCurrent) + INIT_EGL_FUNC(eglQueryAPI) + INIT_EGL_FUNC(eglQueryContext) + INIT_EGL_FUNC(eglQueryString) + INIT_EGL_FUNC(eglQuerySurface) + INIT_EGL_FUNC(eglReleaseTexImage) + INIT_EGL_FUNC(eglReleaseThread) + INIT_EGL_FUNC(eglSurfaceAttrib) + INIT_EGL_FUNC(eglSwapBuffers) + INIT_EGL_FUNC(eglSwapBuffersWithDamageEXT) + INIT_EGL_FUNC(eglSwapInterval) + INIT_EGL_FUNC(eglTerminate) + INIT_EGL_FUNC(eglUnlockSurfaceKHR) + INIT_EGL_FUNC(eglWaitClient) + INIT_EGL_FUNC(eglWaitGL) + INIT_EGL_FUNC(eglWaitNative) + INIT_EGL_FUNC(eglCreateSync) + INIT_EGL_FUNC(eglDestroySync) + INIT_EGL_FUNC(eglClientWaitSync) + INIT_EGL_FUNC(eglGetSyncAttrib) + INIT_EGL_FUNC(eglCreateImage) + INIT_EGL_FUNC(eglDestroyImage) + INIT_EGL_FUNC(eglGetPlatformDisplay) + INIT_EGL_FUNC(eglWaitSync) + } + return true; + } + + static EGLDisplay eglDisplay = EGL_NO_DISPLAY; + static EGLSurface eglSurface = EGL_NO_SURFACE; + static EGLContext eglContext = EGL_NO_CONTEXT; + inline void DestroyTempEGLCtx(const MG_External::EGLFunctionsTable& eglFuncs) { + if (eglSurface != EGL_NO_SURFACE) { + eglFuncs.eglDestroySurface(eglDisplay, eglSurface); + eglSurface = EGL_NO_SURFACE; + } + if (eglContext != EGL_NO_CONTEXT) { + eglFuncs.eglDestroyContext(eglDisplay, eglContext); + eglContext = EGL_NO_CONTEXT; + } + if (eglDisplay != EGL_NO_DISPLAY) { + eglFuncs.eglTerminate(eglDisplay); + eglDisplay = EGL_NO_DISPLAY; + } + } + inline Bool InitTmpEGLContext(const MG_External::EGLFunctionsTable& eglFuncs) { + EGLint configAttribs[] = {EGL_RED_SIZE, + 8, + EGL_GREEN_SIZE, + 8, + EGL_BLUE_SIZE, + 8, + EGL_ALPHA_SIZE, + 8, + EGL_SURFACE_TYPE, + EGL_PBUFFER_BIT, + EGL_RENDERABLE_TYPE, + EGL_OPENGL_ES2_BIT, + EGL_NONE}; + + EGLint ctxAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; + + EGLint pbAttribs[] = {EGL_WIDTH, 32, EGL_HEIGHT, 32, EGL_NONE}; + + EGLConfig pbufConfig; + EGLint configsFound = 0; + + eglDisplay = eglFuncs.eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (eglDisplay == EGL_NO_DISPLAY) { + DestroyTempEGLCtx(eglFuncs); + return false; + } + + if (eglFuncs.eglInitialize(eglDisplay, nullptr, nullptr) != EGL_TRUE) { + DestroyTempEGLCtx(eglFuncs); + return false; + } + + if (eglFuncs.eglBindAPI(EGL_OPENGL_ES_API) != EGL_TRUE) { + DestroyTempEGLCtx(eglFuncs); + return false; + } + + if (eglFuncs.eglChooseConfig(eglDisplay, configAttribs, &pbufConfig, 1, &configsFound) != EGL_TRUE) { + DestroyTempEGLCtx(eglFuncs); + return false; + } + + if (configsFound == 0) { + configAttribs[6] = 0; + if (eglFuncs.eglChooseConfig(eglDisplay, configAttribs, &pbufConfig, 1, &configsFound) != EGL_TRUE) { + DestroyTempEGLCtx(eglFuncs); + return false; + } + if (!configsFound) { + DestroyTempEGLCtx(eglFuncs); + return false; + } + } + + eglContext = eglFuncs.eglCreateContext(eglDisplay, pbufConfig, EGL_NO_CONTEXT, ctxAttribs); + if (eglContext == EGL_NO_CONTEXT) { + DestroyTempEGLCtx(eglFuncs); + return false; + } + + eglSurface = eglFuncs.eglCreatePbufferSurface(eglDisplay, pbufConfig, pbAttribs); + if (eglSurface == EGL_NO_SURFACE) { + DestroyTempEGLCtx(eglFuncs); + return false; + } + + if (eglFuncs.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE) { + DestroyTempEGLCtx(eglFuncs); + return false; + } + return true; + } + + Bool FillInGLESCapabilities(MG_External::GLESCapabilities& caps, const MG_External::GLESFunctionsTable& glesFuncs, + const MG_External::EGLFunctionsTable& eglFuncs) { + if (!glesFuncs.glGetString || !glesFuncs.glGetIntegerv) { + MGLOG_E("Required GLES functions are not loaded, cannot query capabilities"); + return false; + } + if (!eglFuncs.eglGetDisplay || !eglFuncs.eglInitialize || !eglFuncs.eglChooseConfig || + !eglFuncs.eglCreateContext || !eglFuncs.eglCreatePbufferSurface || !eglFuncs.eglMakeCurrent) { + MGLOG_E("Required EGL functions are not loaded, cannot create temporary EGL context"); + return false; + } + + Bool eglCtxCreated = InitTmpEGLContext(eglFuncs); + if (!eglCtxCreated) { + MGLOG_E("Failed to create temporary EGL context, cannot query GLES capabilities"); + return false; + } + + auto* vendorName = glesFuncs.glGetString(GL_VENDOR); + MGLOG_I("GL_VENDOR: %s", vendorName); + auto* gpuName = glesFuncs.glGetString(GL_RENDERER); + MGLOG_I("GL_RENDERER: %s", gpuName); + glesFuncs.glGetIntegerv(GL_MAJOR_VERSION, &caps.GLESVersion.Major); + glesFuncs.glGetIntegerv(GL_MINOR_VERSION, &caps.GLESVersion.Minor); + + caps.GLESVersionString = ToString(glesFuncs.glGetString(GL_VERSION)); + caps.GLESRendererString = ToString(gpuName); + caps.GLESVendorString = ToString(vendorName); + caps.GLESShadingLanguageVersionString = ToString(glesFuncs.glGetString(GL_SHADING_LANGUAGE_VERSION)); + + GLint extCount = 0; + glesFuncs.glGetIntegerv(GL_NUM_EXTENSIONS, &extCount); + MGLOG_I("Detected %d OpenGL ES extensions:", extCount); + for (GLint i = 0; i < extCount; ++i) { + const char* extension = (const char*)glesFuncs.glGetStringi(GL_EXTENSIONS, i); + if (extension) { + MGLOG_I(" %s", extension); + if (std::strcmp(extension, "GL_EXT_buffer_storage") == 0) { + caps.SupportsPersistentMapping = true; } - - if (MG_External::EGL::eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE) { - goto cleanup; - } - - if (MG_External::EGL::eglBindAPI(EGL_OPENGL_ES_API) != EGL_TRUE) { - goto cleanup; - } - - if (MG_External::EGL::eglChooseConfig(eglDisplay, configAttribs, &pbufConfig, 1, &configsFound) != - EGL_TRUE) { - goto cleanup; - } - - if (configsFound == 0) { - configAttribs[6] = 0; - if (MG_External::EGL::eglChooseConfig(eglDisplay, configAttribs, &pbufConfig, 1, &configsFound) != - EGL_TRUE) { - goto cleanup; - } - if (!configsFound) { - goto cleanup; - } - } - - eglContext = MG_External::EGL::eglCreateContext(eglDisplay, pbufConfig, EGL_NO_CONTEXT, ctxAttribs); - if (eglContext == EGL_NO_CONTEXT) { - goto cleanup; - } - - eglSurface = MG_External::EGL::eglCreatePbufferSurface(eglDisplay, pbufConfig, pbAttribs); - if (eglSurface == EGL_NO_SURFACE) { - goto cleanup; - } - - if (MG_External::EGL::eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE) { - goto cleanup; - } - - return; - - cleanup: - if (eglSurface != EGL_NO_SURFACE) { - MG_External::EGL::eglDestroySurface(eglDisplay, eglSurface); - } - if (eglContext != EGL_NO_CONTEXT) { - MG_External::EGL::eglDestroyContext(eglDisplay, eglContext); - } - if (eglDisplay != EGL_NO_DISPLAY) { - MG_External::EGL::eglTerminate(eglDisplay); + if (std::strcmp(extension, "GL_EXT_texture_norm16") == 0) { + caps.SupportsNorm16Texture = true; } } + } - void DestroyTempEGLCtx() { - INIT_EGL_FUNC(eglDestroySurface) - INIT_EGL_FUNC(eglDestroyContext) - INIT_EGL_FUNC(eglMakeCurrent) - INIT_EGL_FUNC(eglTerminate) + MGLOG_I("OpenGL ES capabilities:"); + glesFuncs.glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &caps.UniformBufferOffsetAlignment); + MGLOG_I(" GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: %d", caps.UniformBufferOffsetAlignment); - MG_External::EGL::eglMakeCurrent(eglDisplay, 0, 0, EGL_NO_CONTEXT); - MG_External::EGL::eglDestroySurface(eglDisplay, eglSurface); - MG_External::EGL::eglDestroyContext(eglDisplay, eglContext); - - MG_External::EGL::eglTerminate(eglDisplay); - } - -#undef LOAD_EGL - - } // namespace BackendLoader::GLES - } // namespace MG_Util -} // namespace MobileGL + DestroyTempEGLCtx(eglFuncs); + return true; + } +} // namespace MobileGL::MG_Util::BackendLoader diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h index 7b548b7e..8b6441b4 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h @@ -6,455 +6,15 @@ // SPDX-License-Identifier: LGPL-3.0-only // End of Source File Header +#pragma once #include #define MOBILEGL_EXTERNAL_GLES #define GL_FUNC_TYPEDEF(type, name, ...) typedef type(MOBILEGL_EXTERNAL_GLES* name##_PTR)(__VA_ARGS__); -GL_FUNC_TYPEDEF(void, glActiveTexture, GLenum texture) -GL_FUNC_TYPEDEF(void, glAttachShader, GLuint program, GLuint shader) -GL_FUNC_TYPEDEF(void, glBindAttribLocation, GLuint program, GLuint index, const GLchar* name) -GL_FUNC_TYPEDEF(void, glBindBuffer, GLenum target, GLuint buffer) -GL_FUNC_TYPEDEF(void, glBindFramebuffer, GLenum target, GLuint framebuffer) -GL_FUNC_TYPEDEF(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer) -GL_FUNC_TYPEDEF(void, glBindTexture, GLenum target, GLuint texture) -GL_FUNC_TYPEDEF(void, glBlendColor, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) -GL_FUNC_TYPEDEF(void, glBlendEquation, GLenum mode) -GL_FUNC_TYPEDEF(void, glBlendEquationSeparate, GLenum modeRGB, GLenum modeAlpha) -GL_FUNC_TYPEDEF(void, glBlendFunc, GLenum sfactor, GLenum dfactor) -GL_FUNC_TYPEDEF(void, glBlendFuncSeparate, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, - GLenum dfactorAlpha) -GL_FUNC_TYPEDEF(void, glBufferData, GLenum target, GLsizeiptr size, const void* data, GLenum usage) -GL_FUNC_TYPEDEF(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void* data) -GL_FUNC_TYPEDEF(GLenum, glCheckFramebufferStatus, GLenum target) -GL_FUNC_TYPEDEF(void, glClear, GLbitfield mask) -GL_FUNC_TYPEDEF(void, glClearColor, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) -GL_FUNC_TYPEDEF(void, glClearDepthf, GLfloat d) -GL_FUNC_TYPEDEF(void, glClearStencil, GLint s) -GL_FUNC_TYPEDEF(void, glColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) -GL_FUNC_TYPEDEF(void, glCompileShader, GLuint shader) -GL_FUNC_TYPEDEF(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, - GLsizei height, GLint border, GLsizei imageSize, const void* data) -GL_FUNC_TYPEDEF(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) -GL_FUNC_TYPEDEF(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, - GLsizei width, GLsizei height, GLint border) -GL_FUNC_TYPEDEF(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, - GLsizei width, GLsizei height) -GL_FUNC_TYPEDEF(GLuint, glCreateProgram) -GL_FUNC_TYPEDEF(GLuint, glCreateShader, GLenum type) -GL_FUNC_TYPEDEF(void, glCullFace, GLenum mode) -GL_FUNC_TYPEDEF(void, glDeleteBuffers, GLsizei n, const GLuint* buffers) -GL_FUNC_TYPEDEF(void, glDeleteFramebuffers, GLsizei n, const GLuint* framebuffers) -GL_FUNC_TYPEDEF(void, glDeleteProgram, GLuint program) -GL_FUNC_TYPEDEF(void, glDeleteRenderbuffers, GLsizei n, const GLuint* renderbuffers) -GL_FUNC_TYPEDEF(void, glDeleteShader, GLuint shader) -GL_FUNC_TYPEDEF(void, glDeleteTextures, GLsizei n, const GLuint* textures) -GL_FUNC_TYPEDEF(void, glDepthFunc, GLenum func) -GL_FUNC_TYPEDEF(void, glDepthMask, GLboolean flag) -GL_FUNC_TYPEDEF(void, glDepthRangef, GLfloat n, GLfloat f) -GL_FUNC_TYPEDEF(void, glDetachShader, GLuint program, GLuint shader) -GL_FUNC_TYPEDEF(void, glDisable, GLenum cap) -GL_FUNC_TYPEDEF(void, glDisableVertexAttribArray, GLuint index) -GL_FUNC_TYPEDEF(void, glDrawArrays, GLenum mode, GLint first, GLsizei count) -GL_FUNC_TYPEDEF(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const void* indices) -GL_FUNC_TYPEDEF(void, glEnable, GLenum cap) -GL_FUNC_TYPEDEF(void, glEnableVertexAttribArray, GLuint index) -GL_FUNC_TYPEDEF(void, glFinish) -GL_FUNC_TYPEDEF(void, glFlush) -GL_FUNC_TYPEDEF(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, - GLuint renderbuffer) -GL_FUNC_TYPEDEF(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, - GLint level) -GL_FUNC_TYPEDEF(void, glFrontFace, GLenum mode) -GL_FUNC_TYPEDEF(void, glGenBuffers, GLsizei n, GLuint* buffers) -GL_FUNC_TYPEDEF(void, glGenerateMipmap, GLenum target) -GL_FUNC_TYPEDEF(void, glGenFramebuffers, GLsizei n, GLuint* framebuffers) -GL_FUNC_TYPEDEF(void, glGenRenderbuffers, GLsizei n, GLuint* renderbuffers) -GL_FUNC_TYPEDEF(void, glGenTextures, GLsizei n, GLuint* textures) -GL_FUNC_TYPEDEF(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, - GLenum* type, GLchar* name) -GL_FUNC_TYPEDEF(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, - GLenum* type, GLchar* name) -GL_FUNC_TYPEDEF(void, glGetAttachedShaders, GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) -GL_FUNC_TYPEDEF(GLint, glGetAttribLocation, GLuint program, const GLchar* name) -GL_FUNC_TYPEDEF(void, glGetBooleanv, GLenum pname, GLboolean* data) -GL_FUNC_TYPEDEF(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(GLenum, glGetError) -GL_FUNC_TYPEDEF(const GLubyte*, glGetString, GLenum) -GL_FUNC_TYPEDEF(const GLubyte*, glGetStringi, GLenum, GLuint) -GL_FUNC_TYPEDEF(void, glGetFloatv, GLenum pname, GLfloat* data) -GL_FUNC_TYPEDEF(void, glGetFramebufferAttachmentParameteriv, GLenum target, GLenum attachment, GLenum pname, - GLint* params) -GL_FUNC_TYPEDEF(void, glGetIntegerv, GLenum pname, GLint* data) -GL_FUNC_TYPEDEF(void, glGetProgramiv, GLuint program, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetProgramInfoLog, GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog) -GL_FUNC_TYPEDEF(void, glGetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetShaderiv, GLuint shader, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetShaderInfoLog, GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) -GL_FUNC_TYPEDEF(void, glGetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint* range, - GLint* precision) -GL_FUNC_TYPEDEF(void, glGetShaderSource, GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source) -GL_FUNC_TYPEDEF(void, glGetTexParameterfv, GLenum target, GLenum pname, GLfloat* params) -GL_FUNC_TYPEDEF(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetUniformfv, GLuint program, GLint location, GLfloat* params) -GL_FUNC_TYPEDEF(void, glGetUniformiv, GLuint program, GLint location, GLint* params) -GL_FUNC_TYPEDEF(GLint, glGetUniformLocation, GLuint program, const GLchar* name) -GL_FUNC_TYPEDEF(void, glGetVertexAttribfv, GLuint index, GLenum pname, GLfloat* params) -GL_FUNC_TYPEDEF(void, glGetVertexAttribiv, GLuint index, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, void** pointer) -GL_FUNC_TYPEDEF(void, glHint, GLenum target, GLenum mode) -GL_FUNC_TYPEDEF(GLboolean, glIsBuffer, GLuint buffer) -GL_FUNC_TYPEDEF(GLboolean, glIsEnabled, GLenum cap) -GL_FUNC_TYPEDEF(GLboolean, glIsFramebuffer, GLuint framebuffer) -GL_FUNC_TYPEDEF(GLboolean, glIsProgram, GLuint program) -GL_FUNC_TYPEDEF(GLboolean, glIsRenderbuffer, GLuint renderbuffer) -GL_FUNC_TYPEDEF(GLboolean, glIsShader, GLuint shader) -GL_FUNC_TYPEDEF(GLboolean, glIsTexture, GLuint texture) -GL_FUNC_TYPEDEF(void, glLineWidth, GLfloat width) -GL_FUNC_TYPEDEF(void, glLinkProgram, GLuint program) -GL_FUNC_TYPEDEF(void, glPixelStorei, GLenum pname, GLint param) -GL_FUNC_TYPEDEF(void, glPolygonOffset, GLfloat factor, GLfloat units) -GL_FUNC_TYPEDEF(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - void* pixels) -GL_FUNC_TYPEDEF(void, glReleaseShaderCompiler) -GL_FUNC_TYPEDEF(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) -GL_FUNC_TYPEDEF(void, glSampleCoverage, GLfloat value, GLboolean invert) -GL_FUNC_TYPEDEF(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height) -GL_FUNC_TYPEDEF(void, glShaderBinary, GLsizei count, const GLuint* shaders, GLenum binaryformat, const void* binary, - GLsizei length) -GL_FUNC_TYPEDEF(void, glShaderSource, GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) -GL_FUNC_TYPEDEF(void, glStencilFunc, GLenum func, GLint ref, GLuint mask) -GL_FUNC_TYPEDEF(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask) -GL_FUNC_TYPEDEF(void, glStencilMask, GLuint mask) -GL_FUNC_TYPEDEF(void, glStencilMaskSeparate, GLenum face, GLuint mask) -GL_FUNC_TYPEDEF(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass) -GL_FUNC_TYPEDEF(void, glStencilOpSeparate, GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) -GL_FUNC_TYPEDEF(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, const void* pixels) -GL_FUNC_TYPEDEF(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param) -GL_FUNC_TYPEDEF(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat* params) -GL_FUNC_TYPEDEF(void, glTexParameteri, GLenum target, GLenum pname, GLint param) -GL_FUNC_TYPEDEF(void, glTexParameteriv, GLenum target, GLenum pname, const GLint* params) -GL_FUNC_TYPEDEF(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, - GLsizei height, GLenum format, GLenum type, const void* pixels) -GL_FUNC_TYPEDEF(void, glUniform1f, GLint location, GLfloat v0) -GL_FUNC_TYPEDEF(void, glUniform1fv, GLint location, GLsizei count, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glUniform1i, GLint location, GLint v0) -GL_FUNC_TYPEDEF(void, glUniform1iv, GLint location, GLsizei count, const GLint* value) -GL_FUNC_TYPEDEF(void, glUniform2f, GLint location, GLfloat v0, GLfloat v1) -GL_FUNC_TYPEDEF(void, glUniform2fv, GLint location, GLsizei count, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glUniform2i, GLint location, GLint v0, GLint v1) -GL_FUNC_TYPEDEF(void, glUniform2iv, GLint location, GLsizei count, const GLint* value) -GL_FUNC_TYPEDEF(void, glUniform3f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) -GL_FUNC_TYPEDEF(void, glUniform3fv, GLint location, GLsizei count, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glUniform3i, GLint location, GLint v0, GLint v1, GLint v2) -GL_FUNC_TYPEDEF(void, glUniform3iv, GLint location, GLsizei count, const GLint* value) -GL_FUNC_TYPEDEF(void, glUniform4f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) -GL_FUNC_TYPEDEF(void, glUniform4fv, GLint location, GLsizei count, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glUniform4i, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) -GL_FUNC_TYPEDEF(void, glUniform4iv, GLint location, GLsizei count, const GLint* value) -GL_FUNC_TYPEDEF(void, glUniformMatrix2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glUniformMatrix3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glUniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glUseProgram, GLuint program) -GL_FUNC_TYPEDEF(void, glValidateProgram, GLuint program) -GL_FUNC_TYPEDEF(void, glVertexAttrib1f, GLuint index, GLfloat x) -GL_FUNC_TYPEDEF(void, glVertexAttrib1fv, GLuint index, const GLfloat* v) -GL_FUNC_TYPEDEF(void, glVertexAttrib2f, GLuint index, GLfloat x, GLfloat y) -GL_FUNC_TYPEDEF(void, glVertexAttrib2fv, GLuint index, const GLfloat* v) -GL_FUNC_TYPEDEF(void, glVertexAttrib3f, GLuint index, GLfloat x, GLfloat y, GLfloat z) -GL_FUNC_TYPEDEF(void, glVertexAttrib3fv, GLuint index, const GLfloat* v) -GL_FUNC_TYPEDEF(void, glVertexAttrib4f, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -GL_FUNC_TYPEDEF(void, glVertexAttrib4fv, GLuint index, const GLfloat* v) -GL_FUNC_TYPEDEF(void, glVertexAttribPointer, GLuint index, GLint size, GLenum type, GLboolean normalized, - GLsizei stride, const void* pointer) -GL_FUNC_TYPEDEF(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height) -GL_FUNC_TYPEDEF(void, glReadBuffer, GLenum src) -GL_FUNC_TYPEDEF(void, glDrawRangeElements, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, - const void* indices) -GL_FUNC_TYPEDEF(void, glTexImage3D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, - GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) -GL_FUNC_TYPEDEF(void, glTexSubImage3D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) -GL_FUNC_TYPEDEF(void, glCopyTexSubImage3D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, - GLint x, GLint y, GLsizei width, GLsizei height) -GL_FUNC_TYPEDEF(void, glCompressedTexImage3D, GLenum target, GLint level, GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data) -GL_FUNC_TYPEDEF(void, glCompressedTexSubImage3D, GLenum target, GLint level, GLint xoffset, GLint yoffset, - GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, - const void* data) -GL_FUNC_TYPEDEF(void, glGenQueries, GLsizei n, GLuint* ids) -GL_FUNC_TYPEDEF(void, glDeleteQueries, GLsizei n, const GLuint* ids) -GL_FUNC_TYPEDEF(GLboolean, glIsQuery, GLuint id) -GL_FUNC_TYPEDEF(void, glBeginQuery, GLenum target, GLuint id) -GL_FUNC_TYPEDEF(void, glEndQuery, GLenum target) -GL_FUNC_TYPEDEF(void, glGetQueryiv, GLenum target, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetQueryObjectuiv, GLuint id, GLenum pname, GLuint* params) -GL_FUNC_TYPEDEF(GLboolean, glUnmapBuffer, GLenum target) -GL_FUNC_TYPEDEF(void, glGetBufferPointerv, GLenum target, GLenum pname, void** params) -GL_FUNC_TYPEDEF(void, glDrawBuffers, GLsizei n, const GLenum* bufs) -GL_FUNC_TYPEDEF(void, glUniformMatrix2x3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glUniformMatrix3x2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glUniformMatrix2x4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glUniformMatrix4x2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glUniformMatrix3x4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glUniformMatrix4x3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glBlitFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, - GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) -GL_FUNC_TYPEDEF(void, glRenderbufferStorageMultisample, GLenum target, GLsizei samples, GLenum internalformat, - GLsizei width, GLsizei height) -GL_FUNC_TYPEDEF(void, glFramebufferTextureLayer, GLenum target, GLenum attachment, GLuint texture, GLint level, - GLint layer) -GL_FUNC_TYPEDEF(void, glFlushMappedBufferRange, GLenum target, GLintptr offset, GLsizeiptr length) -GL_FUNC_TYPEDEF(void, glBindVertexArray, GLuint array) -GL_FUNC_TYPEDEF(void, glDeleteVertexArrays, GLsizei n, const GLuint* arrays) -GL_FUNC_TYPEDEF(void, glGenVertexArrays, GLsizei n, GLuint* arrays) -GL_FUNC_TYPEDEF(GLboolean, glIsVertexArray, GLuint array) -GL_FUNC_TYPEDEF(void, glGetIntegeri_v, GLenum target, GLuint index, GLint* data) -GL_FUNC_TYPEDEF(void, glBeginTransformFeedback, GLenum primitiveMode) -GL_FUNC_TYPEDEF(void, glEndTransformFeedback) -GL_FUNC_TYPEDEF(void, glBindBufferRange, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) -GL_FUNC_TYPEDEF(void, glBindBufferBase, GLenum target, GLuint index, GLuint buffer) -GL_FUNC_TYPEDEF(void, glTransformFeedbackVaryings, GLuint program, GLsizei count, const GLchar* const* varyings, - GLenum bufferMode) -GL_FUNC_TYPEDEF(void, glGetTransformFeedbackVarying, GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, - GLsizei* size, GLenum* type, GLchar* name) -GL_FUNC_TYPEDEF(void, glVertexAttribIPointer, GLuint index, GLint size, GLenum type, GLsizei stride, - const void* pointer) -GL_FUNC_TYPEDEF(void, glGetVertexAttribIiv, GLuint index, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetVertexAttribIuiv, GLuint index, GLenum pname, GLuint* params) -GL_FUNC_TYPEDEF(void, glVertexAttribI4i, GLuint index, GLint x, GLint y, GLint z, GLint w) -GL_FUNC_TYPEDEF(void, glVertexAttribI4ui, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) -GL_FUNC_TYPEDEF(void, glVertexAttribI4iv, GLuint index, const GLint* v) -GL_FUNC_TYPEDEF(void, glVertexAttribI4uiv, GLuint index, const GLuint* v) -GL_FUNC_TYPEDEF(void, glGetUniformuiv, GLuint program, GLint location, GLuint* params) -GL_FUNC_TYPEDEF(GLint, glGetFragDataLocation, GLuint program, const GLchar* name) -GL_FUNC_TYPEDEF(void, glUniform1ui, GLint location, GLuint v0) -GL_FUNC_TYPEDEF(void, glUniform2ui, GLint location, GLuint v0, GLuint v1) -GL_FUNC_TYPEDEF(void, glUniform3ui, GLint location, GLuint v0, GLuint v1, GLuint v2) -GL_FUNC_TYPEDEF(void, glUniform4ui, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) -GL_FUNC_TYPEDEF(void, glUniform1uiv, GLint location, GLsizei count, const GLuint* value) -GL_FUNC_TYPEDEF(void, glUniform2uiv, GLint location, GLsizei count, const GLuint* value) -GL_FUNC_TYPEDEF(void, glUniform3uiv, GLint location, GLsizei count, const GLuint* value) -GL_FUNC_TYPEDEF(void, glUniform4uiv, GLint location, GLsizei count, const GLuint* value) -GL_FUNC_TYPEDEF(void, glClearBufferiv, GLenum buffer, GLint drawbuffer, const GLint* value) -GL_FUNC_TYPEDEF(void, glClearBufferuiv, GLenum buffer, GLint drawbuffer, const GLuint* value) -GL_FUNC_TYPEDEF(void, glClearBufferfv, GLenum buffer, GLint drawbuffer, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glClearBufferfi, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) -GL_FUNC_TYPEDEF(void, glCopyBufferSubData, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, - GLintptr writeOffset, GLsizeiptr size) -GL_FUNC_TYPEDEF(void, glGetUniformIndices, GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, - GLuint* uniformIndices) -GL_FUNC_TYPEDEF(void, glGetActiveUniformsiv, GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, - GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(GLuint, glGetUniformBlockIndex, GLuint program, const GLchar* uniformBlockName) -GL_FUNC_TYPEDEF(void, glGetActiveUniformBlockiv, GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetActiveUniformBlockName, GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, - GLsizei* length, GLchar* uniformBlockName) -GL_FUNC_TYPEDEF(void, glUniformBlockBinding, GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) -GL_FUNC_TYPEDEF(void, glDrawArraysInstanced, GLenum mode, GLint first, GLsizei count, GLsizei instancecount) -GL_FUNC_TYPEDEF(void, glDrawElementsInstanced, GLenum mode, GLsizei count, GLenum type, const void* indices, - GLsizei instancecount) -GL_FUNC_TYPEDEF(GLsync, glFenceSync, GLenum condition, GLbitfield flags) -GL_FUNC_TYPEDEF(GLboolean, glIsSync, GLsync sync) -GL_FUNC_TYPEDEF(void, glDeleteSync, GLsync sync) -GL_FUNC_TYPEDEF(GLenum, glClientWaitSync, GLsync sync, GLbitfield flags, GLuint64 timeout) -GL_FUNC_TYPEDEF(void, glWaitSync, GLsync sync, GLbitfield flags, GLuint64 timeout) -GL_FUNC_TYPEDEF(void, glGetInteger64v, GLenum pname, GLint64* data) -GL_FUNC_TYPEDEF(void, glGetSynciv, GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) -GL_FUNC_TYPEDEF(void, glGetInteger64i_v, GLenum target, GLuint index, GLint64* data) -GL_FUNC_TYPEDEF(void, glGetBufferParameteri64v, GLenum target, GLenum pname, GLint64* params) -GL_FUNC_TYPEDEF(void, glGenSamplers, GLsizei count, GLuint* samplers) -GL_FUNC_TYPEDEF(void, glDeleteSamplers, GLsizei count, const GLuint* samplers) -GL_FUNC_TYPEDEF(GLboolean, glIsSampler, GLuint sampler) -GL_FUNC_TYPEDEF(void, glBindSampler, GLuint unit, GLuint sampler) -GL_FUNC_TYPEDEF(void, glSamplerParameteri, GLuint sampler, GLenum pname, GLint param) -GL_FUNC_TYPEDEF(void, glSamplerParameteriv, GLuint sampler, GLenum pname, const GLint* param) -GL_FUNC_TYPEDEF(void, glSamplerParameterf, GLuint sampler, GLenum pname, GLfloat param) -GL_FUNC_TYPEDEF(void, glSamplerParameterfv, GLuint sampler, GLenum pname, const GLfloat* param) -GL_FUNC_TYPEDEF(void, glGetSamplerParameteriv, GLuint sampler, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetSamplerParameterfv, GLuint sampler, GLenum pname, GLfloat* params) -GL_FUNC_TYPEDEF(void, glVertexAttribDivisor, GLuint index, GLuint divisor) -GL_FUNC_TYPEDEF(void, glBindTransformFeedback, GLenum target, GLuint id) -GL_FUNC_TYPEDEF(void, glDeleteTransformFeedbacks, GLsizei n, const GLuint* ids) -GL_FUNC_TYPEDEF(void, glGenTransformFeedbacks, GLsizei n, GLuint* ids) -GL_FUNC_TYPEDEF(GLboolean, glIsTransformFeedback, GLuint id) -GL_FUNC_TYPEDEF(void, glPauseTransformFeedback) -GL_FUNC_TYPEDEF(void, glResumeTransformFeedback) -GL_FUNC_TYPEDEF(void, glGetProgramBinary, GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, - void* binary) -GL_FUNC_TYPEDEF(void, glProgramBinary, GLuint program, GLenum binaryFormat, const void* binary, GLsizei length) -GL_FUNC_TYPEDEF(void, glProgramParameteri, GLuint program, GLenum pname, GLint value) -GL_FUNC_TYPEDEF(void, glInvalidateFramebuffer, GLenum target, GLsizei numAttachments, const GLenum* attachments) -GL_FUNC_TYPEDEF(void, glInvalidateSubFramebuffer, GLenum target, GLsizei numAttachments, const GLenum* attachments, - GLint x, GLint y, GLsizei width, GLsizei height) -GL_FUNC_TYPEDEF(void, glTexStorage2D, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, - GLsizei height) -GL_FUNC_TYPEDEF(void, glTexStorage3D, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth) -GL_FUNC_TYPEDEF(void, glGetInternalformativ, GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, - GLint* params) -GL_FUNC_TYPEDEF(void, glDispatchCompute, GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) -GL_FUNC_TYPEDEF(void, glDispatchComputeIndirect, GLintptr indirect) -GL_FUNC_TYPEDEF(void, glDrawArraysIndirect, GLenum mode, const void* indirect) -GL_FUNC_TYPEDEF(void, glDrawElementsIndirect, GLenum mode, GLenum type, const void* indirect) -GL_FUNC_TYPEDEF(void, glFramebufferParameteri, GLenum target, GLenum pname, GLint param) -GL_FUNC_TYPEDEF(void, glGetFramebufferParameteriv, GLenum target, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetProgramInterfaceiv, GLuint program, GLenum programInterface, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(GLuint, glGetProgramResourceIndex, GLuint program, GLenum programInterface, const GLchar* name) -GL_FUNC_TYPEDEF(void, glGetProgramResourceName, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, - GLsizei* length, GLchar* name) -GL_FUNC_TYPEDEF(void, glGetProgramResourceiv, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, - const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params) -GL_FUNC_TYPEDEF(GLint, glGetProgramResourceLocation, GLuint program, GLenum programInterface, const GLchar* name) -GL_FUNC_TYPEDEF(void, glUseProgramStages, GLuint pipeline, GLbitfield stages, GLuint program) -GL_FUNC_TYPEDEF(void, glActiveShaderProgram, GLuint pipeline, GLuint program) -GL_FUNC_TYPEDEF(GLuint, glCreateShaderProgramv, GLenum type, GLsizei count, const GLchar* const* strings) -GL_FUNC_TYPEDEF(void, glBindProgramPipeline, GLuint pipeline) -GL_FUNC_TYPEDEF(void, glDeleteProgramPipelines, GLsizei n, const GLuint* pipelines) -GL_FUNC_TYPEDEF(void, glGenProgramPipelines, GLsizei n, GLuint* pipelines) -GL_FUNC_TYPEDEF(GLboolean, glIsProgramPipeline, GLuint pipeline) -GL_FUNC_TYPEDEF(void, glGetProgramPipelineiv, GLuint pipeline, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glProgramUniform1i, GLuint program, GLint location, GLint v0) -GL_FUNC_TYPEDEF(void, glProgramUniform2i, GLuint program, GLint location, GLint v0, GLint v1) -GL_FUNC_TYPEDEF(void, glProgramUniform3i, GLuint program, GLint location, GLint v0, GLint v1, GLint v2) -GL_FUNC_TYPEDEF(void, glProgramUniform4i, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) -GL_FUNC_TYPEDEF(void, glProgramUniform1ui, GLuint program, GLint location, GLuint v0) -GL_FUNC_TYPEDEF(void, glProgramUniform2ui, GLuint program, GLint location, GLuint v0, GLuint v1) -GL_FUNC_TYPEDEF(void, glProgramUniform3ui, GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) -GL_FUNC_TYPEDEF(void, glProgramUniform4ui, GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) -GL_FUNC_TYPEDEF(void, glProgramUniform1f, GLuint program, GLint location, GLfloat v0) -GL_FUNC_TYPEDEF(void, glProgramUniform2f, GLuint program, GLint location, GLfloat v0, GLfloat v1) -GL_FUNC_TYPEDEF(void, glProgramUniform3f, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) -GL_FUNC_TYPEDEF(void, glProgramUniform4f, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, - GLfloat v3) -GL_FUNC_TYPEDEF(void, glProgramUniform1iv, GLuint program, GLint location, GLsizei count, const GLint* value) -GL_FUNC_TYPEDEF(void, glProgramUniform2iv, GLuint program, GLint location, GLsizei count, const GLint* value) -GL_FUNC_TYPEDEF(void, glProgramUniform3iv, GLuint program, GLint location, GLsizei count, const GLint* value) -GL_FUNC_TYPEDEF(void, glProgramUniform4iv, GLuint program, GLint location, GLsizei count, const GLint* value) -GL_FUNC_TYPEDEF(void, glProgramUniform1uiv, GLuint program, GLint location, GLsizei count, const GLuint* value) -GL_FUNC_TYPEDEF(void, glProgramUniform2uiv, GLuint program, GLint location, GLsizei count, const GLuint* value) -GL_FUNC_TYPEDEF(void, glProgramUniform3uiv, GLuint program, GLint location, GLsizei count, const GLuint* value) -GL_FUNC_TYPEDEF(void, glProgramUniform4uiv, GLuint program, GLint location, GLsizei count, const GLuint* value) -GL_FUNC_TYPEDEF(void, glProgramUniform1fv, GLuint program, GLint location, GLsizei count, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glProgramUniform2fv, GLuint program, GLint location, GLsizei count, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glProgramUniform3fv, GLuint program, GLint location, GLsizei count, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glProgramUniform4fv, GLuint program, GLint location, GLsizei count, const GLfloat* value) -GL_FUNC_TYPEDEF(void, glProgramUniformMatrix2fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, - const GLfloat* value) -GL_FUNC_TYPEDEF(void, glProgramUniformMatrix3fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, - const GLfloat* value) -GL_FUNC_TYPEDEF(void, glProgramUniformMatrix4fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, - const GLfloat* value) -GL_FUNC_TYPEDEF(void, glProgramUniformMatrix2x3fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, - const GLfloat* value) -GL_FUNC_TYPEDEF(void, glProgramUniformMatrix3x2fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, - const GLfloat* value) -GL_FUNC_TYPEDEF(void, glProgramUniformMatrix2x4fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, - const GLfloat* value) -GL_FUNC_TYPEDEF(void, glProgramUniformMatrix4x2fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, - const GLfloat* value) -GL_FUNC_TYPEDEF(void, glProgramUniformMatrix3x4fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, - const GLfloat* value) -GL_FUNC_TYPEDEF(void, glProgramUniformMatrix4x3fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, - const GLfloat* value) -GL_FUNC_TYPEDEF(void, glValidateProgramPipeline, GLuint pipeline) -GL_FUNC_TYPEDEF(void, glGetProgramPipelineInfoLog, GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) -GL_FUNC_TYPEDEF(void, glBindImageTexture, GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, - GLenum access, GLenum format) -GL_FUNC_TYPEDEF(void, glGetBooleani_v, GLenum target, GLuint index, GLboolean* data) -GL_FUNC_TYPEDEF(void, glMemoryBarrier, GLbitfield barriers) -GL_FUNC_TYPEDEF(void, glMemoryBarrierByRegion, GLbitfield barriers) -GL_FUNC_TYPEDEF(void, glTexStorage2DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, - GLsizei height, GLboolean fixedsamplelocations) -GL_FUNC_TYPEDEF(void, glGetMultisamplefv, GLenum pname, GLuint index, GLfloat* val) -GL_FUNC_TYPEDEF(void, glSampleMaski, GLuint maskNumber, GLbitfield mask) -GL_FUNC_TYPEDEF(void, glGetTexLevelParameteriv, GLenum target, GLint level, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetTexLevelParameterfv, GLenum target, GLint level, GLenum pname, GLfloat* params) -GL_FUNC_TYPEDEF(void, glBindVertexBuffer, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) -GL_FUNC_TYPEDEF(void, glVertexAttribFormat, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, - GLuint relativeoffset) -GL_FUNC_TYPEDEF(void, glVertexAttribIFormat, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) -GL_FUNC_TYPEDEF(void, glVertexAttribBinding, GLuint attribindex, GLuint bindingindex) -GL_FUNC_TYPEDEF(void, glVertexBindingDivisor, GLuint bindingindex, GLuint divisor) -GL_FUNC_TYPEDEF(void, glBlendBarrier) -GL_FUNC_TYPEDEF(void, glCopyImageSubData, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, - GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, - GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) -GL_FUNC_TYPEDEF(void, glDebugMessageControl, GLenum source, GLenum type, GLenum severity, GLsizei count, - const GLuint* ids, GLboolean enabled) -GL_FUNC_TYPEDEF(void, glDebugMessageInsert, GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, - const GLchar* buf) -GL_FUNC_TYPEDEF(void, glDebugMessageCallback, GLDEBUGPROC callback, const void* userParam) -GL_FUNC_TYPEDEF(GLuint, glGetDebugMessageLog, GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, - GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog) -GL_FUNC_TYPEDEF(void, glPushDebugGroup, GLenum source, GLuint id, GLsizei length, const GLchar* message) -GL_FUNC_TYPEDEF(void, glPopDebugGroup) -GL_FUNC_TYPEDEF(void, glObjectLabel, GLenum identifier, GLuint name, GLsizei length, const GLchar* label) -GL_FUNC_TYPEDEF(void, glGetObjectLabel, GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label) -GL_FUNC_TYPEDEF(void, glObjectPtrLabel, const void* ptr, GLsizei length, const GLchar* label) -GL_FUNC_TYPEDEF(void, glGetObjectPtrLabel, const void* ptr, GLsizei bufSize, GLsizei* length, GLchar* label) -GL_FUNC_TYPEDEF(void, glGetPointerv, GLenum pname, void** params) -GL_FUNC_TYPEDEF(void, glEnablei, GLenum target, GLuint index) -GL_FUNC_TYPEDEF(void, glDisablei, GLenum target, GLuint index) -GL_FUNC_TYPEDEF(void, glBlendEquationi, GLuint buf, GLenum mode) -GL_FUNC_TYPEDEF(void, glBlendEquationSeparatei, GLuint buf, GLenum modeRGB, GLenum modeAlpha) -GL_FUNC_TYPEDEF(void, glBlendFunci, GLuint buf, GLenum src, GLenum dst) -GL_FUNC_TYPEDEF(void, glBlendFuncSeparatei, GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) -GL_FUNC_TYPEDEF(void, glColorMaski, GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) -GL_FUNC_TYPEDEF(GLboolean, glIsEnabledi, GLenum target, GLuint index) -GL_FUNC_TYPEDEF(void, glDrawElementsBaseVertex, GLenum mode, GLsizei count, GLenum type, const void* indices, - GLint basevertex) -GL_FUNC_TYPEDEF(void, glDrawRangeElementsBaseVertex, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, - const void* indices, GLint basevertex) -GL_FUNC_TYPEDEF(void, glDrawElementsInstancedBaseVertex, GLenum mode, GLsizei count, GLenum type, const void* indices, - GLsizei instancecount, GLint basevertex) -GL_FUNC_TYPEDEF(void, glFramebufferTexture, GLenum target, GLenum attachment, GLuint texture, GLint level) -GL_FUNC_TYPEDEF(void, glPrimitiveBoundingBox, GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, - GLfloat maxY, GLfloat maxZ, GLfloat maxW) -GL_FUNC_TYPEDEF(GLenum, glGetGraphicsResetStatus) -GL_FUNC_TYPEDEF(void, glReadnPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - GLsizei bufSize, void* data) -GL_FUNC_TYPEDEF(void, glGetnUniformfv, GLuint program, GLint location, GLsizei bufSize, GLfloat* params) -GL_FUNC_TYPEDEF(void, glGetnUniformiv, GLuint program, GLint location, GLsizei bufSize, GLint* params) -GL_FUNC_TYPEDEF(void, glGetnUniformuiv, GLuint program, GLint location, GLsizei bufSize, GLuint* params) -GL_FUNC_TYPEDEF(void, glMinSampleShading, GLfloat value) -GL_FUNC_TYPEDEF(void, glPatchParameteri, GLenum pname, GLint value) -GL_FUNC_TYPEDEF(void, glTexParameterIiv, GLenum target, GLenum pname, const GLint* params) -GL_FUNC_TYPEDEF(void, glTexParameterIuiv, GLenum target, GLenum pname, const GLuint* params) -GL_FUNC_TYPEDEF(void, glGetTexParameterIiv, GLenum target, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetTexParameterIuiv, GLenum target, GLenum pname, GLuint* params) -GL_FUNC_TYPEDEF(void, glSamplerParameterIiv, GLuint sampler, GLenum pname, const GLint* param) -GL_FUNC_TYPEDEF(void, glSamplerParameterIuiv, GLuint sampler, GLenum pname, const GLuint* param) -GL_FUNC_TYPEDEF(void, glGetSamplerParameterIiv, GLuint sampler, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetSamplerParameterIuiv, GLuint sampler, GLenum pname, GLuint* params) -GL_FUNC_TYPEDEF(void, glTexBuffer, GLenum target, GLenum internalformat, GLuint buffer) -GL_FUNC_TYPEDEF(void, glTexBufferRange, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, - GLsizeiptr size) -GL_FUNC_TYPEDEF(void, glTexStorage3DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) -GL_FUNC_TYPEDEF(void*, glMapBufferRange, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) -GL_FUNC_TYPEDEF(void, glBufferStorageEXT, GLenum target, GLsizeiptr size, const void* data, GLbitfield flags) -GL_FUNC_TYPEDEF(void, glGetQueryObjectivEXT, GLuint id, GLenum pname, GLint* params) -GL_FUNC_TYPEDEF(void, glGetQueryObjecti64vEXT, GLuint id, GLenum pname, GLint64* params) -GL_FUNC_TYPEDEF(void, glBindFragDataLocationEXT, GLuint program, GLuint colorNumber, const GLchar* name) -GL_FUNC_TYPEDEF(void*, glMapBufferOES, GLenum target, GLenum access) - -GL_FUNC_TYPEDEF(void, glMultiDrawArraysIndirectEXT, GLenum mode, const void* indirect, GLsizei drawcount, - GLsizei stride) -GL_FUNC_TYPEDEF(void, glMultiDrawElementsIndirectEXT, GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, - GLsizei stride) -GL_FUNC_TYPEDEF(void, glBruh) -GL_FUNC_TYPEDEF(void, glMultiDrawElementsBaseVertexEXT, GLenum mode, const GLsizei* count, GLenum type, - const void* const* indices, GLsizei drawcount, const GLint* basevertex) - -#undef MOBILEGL_EXTERNAL_GLES -#undef GL_FUNC_TYPEDEF - -#define GL_FUNC_DECL(name) extern name##_PTR name; -#define EGL_FUNC_DECL(name) extern name##_PTR name; +#define GL_FUNC_DECL(name) GLES::name##_PTR name; +#define EGL_FUNC_DECL(name) EGL::name##_PTR name; namespace MobileGL { namespace MG_External { @@ -522,7 +82,9 @@ namespace MobileGL { typedef EGLSurface (*eglCreatePlatformPixmapSurface_PTR)(EGLDisplay dpy, EGLConfig config, void* native_pixmap, const EGLAttrib* attrib_list); typedef EGLBoolean (*eglWaitSync_PTR)(EGLDisplay dpy, EGLSync sync, EGLint flags); + } // namespace EGL + struct EGLFunctionsTable { EGL_FUNC_DECL(eglBindAPI) EGL_FUNC_DECL(eglBindTexImage) EGL_FUNC_DECL(eglChooseConfig) @@ -569,22 +131,507 @@ namespace MobileGL { EGL_FUNC_DECL(eglDestroyImage) EGL_FUNC_DECL(eglCreatePlatformPixmapSurface) EGL_FUNC_DECL(eglWaitSync) - - }; // namespace EGL + }; namespace GLES { - namespace Caps { - struct GLESCaps { - Version version; - Bool hasPersistentMapping; - Bool hasNorm16Texture; + GL_FUNC_TYPEDEF(void, glActiveTexture, GLenum texture) + GL_FUNC_TYPEDEF(void, glAttachShader, GLuint program, GLuint shader) + GL_FUNC_TYPEDEF(void, glBindAttribLocation, GLuint program, GLuint index, const GLchar* name) + GL_FUNC_TYPEDEF(void, glBindBuffer, GLenum target, GLuint buffer) + GL_FUNC_TYPEDEF(void, glBindFramebuffer, GLenum target, GLuint framebuffer) + GL_FUNC_TYPEDEF(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer) + GL_FUNC_TYPEDEF(void, glBindTexture, GLenum target, GLuint texture) + GL_FUNC_TYPEDEF(void, glBlendColor, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) + GL_FUNC_TYPEDEF(void, glBlendEquation, GLenum mode) + GL_FUNC_TYPEDEF(void, glBlendEquationSeparate, GLenum modeRGB, GLenum modeAlpha) + GL_FUNC_TYPEDEF(void, glBlendFunc, GLenum sfactor, GLenum dfactor) + GL_FUNC_TYPEDEF(void, glBlendFuncSeparate, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, + GLenum dfactorAlpha) + GL_FUNC_TYPEDEF(void, glBufferData, GLenum target, GLsizeiptr size, const void* data, GLenum usage) + GL_FUNC_TYPEDEF(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void* data) + GL_FUNC_TYPEDEF(GLenum, glCheckFramebufferStatus, GLenum target) + GL_FUNC_TYPEDEF(void, glClear, GLbitfield mask) + GL_FUNC_TYPEDEF(void, glClearColor, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) + GL_FUNC_TYPEDEF(void, glClearDepthf, GLfloat d) + GL_FUNC_TYPEDEF(void, glClearStencil, GLint s) + GL_FUNC_TYPEDEF(void, glColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) + GL_FUNC_TYPEDEF(void, glCompileShader, GLuint shader) + GL_FUNC_TYPEDEF(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) + GL_FUNC_TYPEDEF(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) + GL_FUNC_TYPEDEF(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border) + GL_FUNC_TYPEDEF(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height) + GL_FUNC_TYPEDEF(GLuint, glCreateProgram) + GL_FUNC_TYPEDEF(GLuint, glCreateShader, GLenum type) + GL_FUNC_TYPEDEF(void, glCullFace, GLenum mode) + GL_FUNC_TYPEDEF(void, glDeleteBuffers, GLsizei n, const GLuint* buffers) + GL_FUNC_TYPEDEF(void, glDeleteFramebuffers, GLsizei n, const GLuint* framebuffers) + GL_FUNC_TYPEDEF(void, glDeleteProgram, GLuint program) + GL_FUNC_TYPEDEF(void, glDeleteRenderbuffers, GLsizei n, const GLuint* renderbuffers) + GL_FUNC_TYPEDEF(void, glDeleteShader, GLuint shader) + GL_FUNC_TYPEDEF(void, glDeleteTextures, GLsizei n, const GLuint* textures) + GL_FUNC_TYPEDEF(void, glDepthFunc, GLenum func) + GL_FUNC_TYPEDEF(void, glDepthMask, GLboolean flag) + GL_FUNC_TYPEDEF(void, glDepthRangef, GLfloat n, GLfloat f) + GL_FUNC_TYPEDEF(void, glDetachShader, GLuint program, GLuint shader) + GL_FUNC_TYPEDEF(void, glDisable, GLenum cap) + GL_FUNC_TYPEDEF(void, glDisableVertexAttribArray, GLuint index) + GL_FUNC_TYPEDEF(void, glDrawArrays, GLenum mode, GLint first, GLsizei count) + GL_FUNC_TYPEDEF(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const void* indices) + GL_FUNC_TYPEDEF(void, glEnable, GLenum cap) + GL_FUNC_TYPEDEF(void, glEnableVertexAttribArray, GLuint index) + GL_FUNC_TYPEDEF(void, glFinish) + GL_FUNC_TYPEDEF(void, glFlush) + GL_FUNC_TYPEDEF(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, + GLenum renderbuffertarget, GLuint renderbuffer) + GL_FUNC_TYPEDEF(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, + GLuint texture, GLint level) + GL_FUNC_TYPEDEF(void, glFrontFace, GLenum mode) + GL_FUNC_TYPEDEF(void, glGenBuffers, GLsizei n, GLuint* buffers) + GL_FUNC_TYPEDEF(void, glGenerateMipmap, GLenum target) + GL_FUNC_TYPEDEF(void, glGenFramebuffers, GLsizei n, GLuint* framebuffers) + GL_FUNC_TYPEDEF(void, glGenRenderbuffers, GLsizei n, GLuint* renderbuffers) + GL_FUNC_TYPEDEF(void, glGenTextures, GLsizei n, GLuint* textures) + GL_FUNC_TYPEDEF(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, + GLint* size, GLenum* type, GLchar* name) + GL_FUNC_TYPEDEF(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, + GLint* size, GLenum* type, GLchar* name) + GL_FUNC_TYPEDEF(void, glGetAttachedShaders, GLuint program, GLsizei maxCount, GLsizei* count, + GLuint* shaders) + GL_FUNC_TYPEDEF(GLint, glGetAttribLocation, GLuint program, const GLchar* name) + GL_FUNC_TYPEDEF(void, glGetBooleanv, GLenum pname, GLboolean* data) + GL_FUNC_TYPEDEF(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(GLenum, glGetError) + GL_FUNC_TYPEDEF(const GLubyte*, glGetString, GLenum) + GL_FUNC_TYPEDEF(const GLubyte*, glGetStringi, GLenum, GLuint) + GL_FUNC_TYPEDEF(void, glGetFloatv, GLenum pname, GLfloat* data) + GL_FUNC_TYPEDEF(void, glGetFramebufferAttachmentParameteriv, GLenum target, GLenum attachment, GLenum pname, + GLint* params) + GL_FUNC_TYPEDEF(void, glGetIntegerv, GLenum pname, GLint* data) + GL_FUNC_TYPEDEF(void, glGetProgramiv, GLuint program, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glGetProgramInfoLog, GLuint program, GLsizei bufSize, GLsizei* length, + GLchar* infoLog) + GL_FUNC_TYPEDEF(void, glGetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glGetShaderiv, GLuint shader, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glGetShaderInfoLog, GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) + GL_FUNC_TYPEDEF(void, glGetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint* range, + GLint* precision) + GL_FUNC_TYPEDEF(void, glGetShaderSource, GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source) + GL_FUNC_TYPEDEF(void, glGetTexParameterfv, GLenum target, GLenum pname, GLfloat* params) + GL_FUNC_TYPEDEF(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glGetUniformfv, GLuint program, GLint location, GLfloat* params) + GL_FUNC_TYPEDEF(void, glGetUniformiv, GLuint program, GLint location, GLint* params) + GL_FUNC_TYPEDEF(GLint, glGetUniformLocation, GLuint program, const GLchar* name) + GL_FUNC_TYPEDEF(void, glGetVertexAttribfv, GLuint index, GLenum pname, GLfloat* params) + GL_FUNC_TYPEDEF(void, glGetVertexAttribiv, GLuint index, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, void** pointer) + GL_FUNC_TYPEDEF(void, glHint, GLenum target, GLenum mode) + GL_FUNC_TYPEDEF(GLboolean, glIsBuffer, GLuint buffer) + GL_FUNC_TYPEDEF(GLboolean, glIsEnabled, GLenum cap) + GL_FUNC_TYPEDEF(GLboolean, glIsFramebuffer, GLuint framebuffer) + GL_FUNC_TYPEDEF(GLboolean, glIsProgram, GLuint program) + GL_FUNC_TYPEDEF(GLboolean, glIsRenderbuffer, GLuint renderbuffer) + GL_FUNC_TYPEDEF(GLboolean, glIsShader, GLuint shader) + GL_FUNC_TYPEDEF(GLboolean, glIsTexture, GLuint texture) + GL_FUNC_TYPEDEF(void, glLineWidth, GLfloat width) + GL_FUNC_TYPEDEF(void, glLinkProgram, GLuint program) + GL_FUNC_TYPEDEF(void, glPixelStorei, GLenum pname, GLint param) + GL_FUNC_TYPEDEF(void, glPolygonOffset, GLfloat factor, GLfloat units) + GL_FUNC_TYPEDEF(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, void* pixels) + GL_FUNC_TYPEDEF(void, glReleaseShaderCompiler) + GL_FUNC_TYPEDEF(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, + GLsizei height) + GL_FUNC_TYPEDEF(void, glSampleCoverage, GLfloat value, GLboolean invert) + GL_FUNC_TYPEDEF(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height) + GL_FUNC_TYPEDEF(void, glShaderBinary, GLsizei count, const GLuint* shaders, GLenum binaryformat, + const void* binary, GLsizei length) + GL_FUNC_TYPEDEF(void, glShaderSource, GLuint shader, GLsizei count, const GLchar* const* string, + const GLint* length) + GL_FUNC_TYPEDEF(void, glStencilFunc, GLenum func, GLint ref, GLuint mask) + GL_FUNC_TYPEDEF(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask) + GL_FUNC_TYPEDEF(void, glStencilMask, GLuint mask) + GL_FUNC_TYPEDEF(void, glStencilMaskSeparate, GLenum face, GLuint mask) + GL_FUNC_TYPEDEF(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass) + GL_FUNC_TYPEDEF(void, glStencilOpSeparate, GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) + GL_FUNC_TYPEDEF(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) + GL_FUNC_TYPEDEF(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param) + GL_FUNC_TYPEDEF(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat* params) + GL_FUNC_TYPEDEF(void, glTexParameteri, GLenum target, GLenum pname, GLint param) + GL_FUNC_TYPEDEF(void, glTexParameteriv, GLenum target, GLenum pname, const GLint* params) + GL_FUNC_TYPEDEF(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) + GL_FUNC_TYPEDEF(void, glUniform1f, GLint location, GLfloat v0) + GL_FUNC_TYPEDEF(void, glUniform1fv, GLint location, GLsizei count, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glUniform1i, GLint location, GLint v0) + GL_FUNC_TYPEDEF(void, glUniform1iv, GLint location, GLsizei count, const GLint* value) + GL_FUNC_TYPEDEF(void, glUniform2f, GLint location, GLfloat v0, GLfloat v1) + GL_FUNC_TYPEDEF(void, glUniform2fv, GLint location, GLsizei count, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glUniform2i, GLint location, GLint v0, GLint v1) + GL_FUNC_TYPEDEF(void, glUniform2iv, GLint location, GLsizei count, const GLint* value) + GL_FUNC_TYPEDEF(void, glUniform3f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) + GL_FUNC_TYPEDEF(void, glUniform3fv, GLint location, GLsizei count, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glUniform3i, GLint location, GLint v0, GLint v1, GLint v2) + GL_FUNC_TYPEDEF(void, glUniform3iv, GLint location, GLsizei count, const GLint* value) + GL_FUNC_TYPEDEF(void, glUniform4f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) + GL_FUNC_TYPEDEF(void, glUniform4fv, GLint location, GLsizei count, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glUniform4i, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) + GL_FUNC_TYPEDEF(void, glUniform4iv, GLint location, GLsizei count, const GLint* value) + GL_FUNC_TYPEDEF(void, glUniformMatrix2fv, GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) + GL_FUNC_TYPEDEF(void, glUniformMatrix3fv, GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) + GL_FUNC_TYPEDEF(void, glUniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) + GL_FUNC_TYPEDEF(void, glUseProgram, GLuint program) + GL_FUNC_TYPEDEF(void, glValidateProgram, GLuint program) + GL_FUNC_TYPEDEF(void, glVertexAttrib1f, GLuint index, GLfloat x) + GL_FUNC_TYPEDEF(void, glVertexAttrib1fv, GLuint index, const GLfloat* v) + GL_FUNC_TYPEDEF(void, glVertexAttrib2f, GLuint index, GLfloat x, GLfloat y) + GL_FUNC_TYPEDEF(void, glVertexAttrib2fv, GLuint index, const GLfloat* v) + GL_FUNC_TYPEDEF(void, glVertexAttrib3f, GLuint index, GLfloat x, GLfloat y, GLfloat z) + GL_FUNC_TYPEDEF(void, glVertexAttrib3fv, GLuint index, const GLfloat* v) + GL_FUNC_TYPEDEF(void, glVertexAttrib4f, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) + GL_FUNC_TYPEDEF(void, glVertexAttrib4fv, GLuint index, const GLfloat* v) + GL_FUNC_TYPEDEF(void, glVertexAttribPointer, GLuint index, GLint size, GLenum type, GLboolean normalized, + GLsizei stride, const void* pointer) + GL_FUNC_TYPEDEF(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height) + GL_FUNC_TYPEDEF(void, glReadBuffer, GLenum src) + GL_FUNC_TYPEDEF(void, glDrawRangeElements, GLenum mode, GLuint start, GLuint end, GLsizei count, + GLenum type, const void* indices) + GL_FUNC_TYPEDEF(void, glTexImage3D, GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) + GL_FUNC_TYPEDEF(void, glTexSubImage3D, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + const void* pixels) + GL_FUNC_TYPEDEF(void, glCopyTexSubImage3D, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) + GL_FUNC_TYPEDEF(void, glCompressedTexImage3D, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, + const void* data) + GL_FUNC_TYPEDEF(void, glCompressedTexSubImage3D, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const void* data) + GL_FUNC_TYPEDEF(void, glGenQueries, GLsizei n, GLuint* ids) + GL_FUNC_TYPEDEF(void, glDeleteQueries, GLsizei n, const GLuint* ids) + GL_FUNC_TYPEDEF(GLboolean, glIsQuery, GLuint id) + GL_FUNC_TYPEDEF(void, glBeginQuery, GLenum target, GLuint id) + GL_FUNC_TYPEDEF(void, glEndQuery, GLenum target) + GL_FUNC_TYPEDEF(void, glGetQueryiv, GLenum target, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glGetQueryObjectuiv, GLuint id, GLenum pname, GLuint* params) + GL_FUNC_TYPEDEF(GLboolean, glUnmapBuffer, GLenum target) + GL_FUNC_TYPEDEF(void, glGetBufferPointerv, GLenum target, GLenum pname, void** params) + GL_FUNC_TYPEDEF(void, glDrawBuffers, GLsizei n, const GLenum* bufs) + GL_FUNC_TYPEDEF(void, glUniformMatrix2x3fv, GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) + GL_FUNC_TYPEDEF(void, glUniformMatrix3x2fv, GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) + GL_FUNC_TYPEDEF(void, glUniformMatrix2x4fv, GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) + GL_FUNC_TYPEDEF(void, glUniformMatrix4x2fv, GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) + GL_FUNC_TYPEDEF(void, glUniformMatrix3x4fv, GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) + GL_FUNC_TYPEDEF(void, glUniformMatrix4x3fv, GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) + GL_FUNC_TYPEDEF(void, glBlitFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, + GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) + GL_FUNC_TYPEDEF(void, glRenderbufferStorageMultisample, GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, GLsizei height) + GL_FUNC_TYPEDEF(void, glFramebufferTextureLayer, GLenum target, GLenum attachment, GLuint texture, + GLint level, GLint layer) + GL_FUNC_TYPEDEF(void, glFlushMappedBufferRange, GLenum target, GLintptr offset, GLsizeiptr length) + GL_FUNC_TYPEDEF(void, glBindVertexArray, GLuint array) + GL_FUNC_TYPEDEF(void, glDeleteVertexArrays, GLsizei n, const GLuint* arrays) + GL_FUNC_TYPEDEF(void, glGenVertexArrays, GLsizei n, GLuint* arrays) + GL_FUNC_TYPEDEF(GLboolean, glIsVertexArray, GLuint array) + GL_FUNC_TYPEDEF(void, glGetIntegeri_v, GLenum target, GLuint index, GLint* data) + GL_FUNC_TYPEDEF(void, glBeginTransformFeedback, GLenum primitiveMode) + GL_FUNC_TYPEDEF(void, glEndTransformFeedback) + GL_FUNC_TYPEDEF(void, glBindBufferRange, GLenum target, GLuint index, GLuint buffer, GLintptr offset, + GLsizeiptr size) + GL_FUNC_TYPEDEF(void, glBindBufferBase, GLenum target, GLuint index, GLuint buffer) + GL_FUNC_TYPEDEF(void, glTransformFeedbackVaryings, GLuint program, GLsizei count, + const GLchar* const* varyings, GLenum bufferMode) + GL_FUNC_TYPEDEF(void, glGetTransformFeedbackVarying, GLuint program, GLuint index, GLsizei bufSize, + GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) + GL_FUNC_TYPEDEF(void, glVertexAttribIPointer, GLuint index, GLint size, GLenum type, GLsizei stride, + const void* pointer) + GL_FUNC_TYPEDEF(void, glGetVertexAttribIiv, GLuint index, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glGetVertexAttribIuiv, GLuint index, GLenum pname, GLuint* params) + GL_FUNC_TYPEDEF(void, glVertexAttribI4i, GLuint index, GLint x, GLint y, GLint z, GLint w) + GL_FUNC_TYPEDEF(void, glVertexAttribI4ui, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) + GL_FUNC_TYPEDEF(void, glVertexAttribI4iv, GLuint index, const GLint* v) + GL_FUNC_TYPEDEF(void, glVertexAttribI4uiv, GLuint index, const GLuint* v) + GL_FUNC_TYPEDEF(void, glGetUniformuiv, GLuint program, GLint location, GLuint* params) + GL_FUNC_TYPEDEF(GLint, glGetFragDataLocation, GLuint program, const GLchar* name) + GL_FUNC_TYPEDEF(void, glUniform1ui, GLint location, GLuint v0) + GL_FUNC_TYPEDEF(void, glUniform2ui, GLint location, GLuint v0, GLuint v1) + GL_FUNC_TYPEDEF(void, glUniform3ui, GLint location, GLuint v0, GLuint v1, GLuint v2) + GL_FUNC_TYPEDEF(void, glUniform4ui, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) + GL_FUNC_TYPEDEF(void, glUniform1uiv, GLint location, GLsizei count, const GLuint* value) + GL_FUNC_TYPEDEF(void, glUniform2uiv, GLint location, GLsizei count, const GLuint* value) + GL_FUNC_TYPEDEF(void, glUniform3uiv, GLint location, GLsizei count, const GLuint* value) + GL_FUNC_TYPEDEF(void, glUniform4uiv, GLint location, GLsizei count, const GLuint* value) + GL_FUNC_TYPEDEF(void, glClearBufferiv, GLenum buffer, GLint drawbuffer, const GLint* value) + GL_FUNC_TYPEDEF(void, glClearBufferuiv, GLenum buffer, GLint drawbuffer, const GLuint* value) + GL_FUNC_TYPEDEF(void, glClearBufferfv, GLenum buffer, GLint drawbuffer, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glClearBufferfi, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) + GL_FUNC_TYPEDEF(void, glCopyBufferSubData, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, + GLintptr writeOffset, GLsizeiptr size) + GL_FUNC_TYPEDEF(void, glGetUniformIndices, GLuint program, GLsizei uniformCount, + const GLchar* const* uniformNames, GLuint* uniformIndices) + GL_FUNC_TYPEDEF(void, glGetActiveUniformsiv, GLuint program, GLsizei uniformCount, + const GLuint* uniformIndices, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(GLuint, glGetUniformBlockIndex, GLuint program, const GLchar* uniformBlockName) + GL_FUNC_TYPEDEF(void, glGetActiveUniformBlockiv, GLuint program, GLuint uniformBlockIndex, GLenum pname, + GLint* params) + GL_FUNC_TYPEDEF(void, glGetActiveUniformBlockName, GLuint program, GLuint uniformBlockIndex, + GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) + GL_FUNC_TYPEDEF(void, glUniformBlockBinding, GLuint program, GLuint uniformBlockIndex, + GLuint uniformBlockBinding) + GL_FUNC_TYPEDEF(void, glDrawArraysInstanced, GLenum mode, GLint first, GLsizei count, GLsizei instancecount) + GL_FUNC_TYPEDEF(void, glDrawElementsInstanced, GLenum mode, GLsizei count, GLenum type, const void* indices, + GLsizei instancecount) + GL_FUNC_TYPEDEF(GLsync, glFenceSync, GLenum condition, GLbitfield flags) + GL_FUNC_TYPEDEF(GLboolean, glIsSync, GLsync sync) + GL_FUNC_TYPEDEF(void, glDeleteSync, GLsync sync) + GL_FUNC_TYPEDEF(GLenum, glClientWaitSync, GLsync sync, GLbitfield flags, GLuint64 timeout) + GL_FUNC_TYPEDEF(void, glWaitSync, GLsync sync, GLbitfield flags, GLuint64 timeout) + GL_FUNC_TYPEDEF(void, glGetInteger64v, GLenum pname, GLint64* data) + GL_FUNC_TYPEDEF(void, glGetSynciv, GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, + GLint* values) + GL_FUNC_TYPEDEF(void, glGetInteger64i_v, GLenum target, GLuint index, GLint64* data) + GL_FUNC_TYPEDEF(void, glGetBufferParameteri64v, GLenum target, GLenum pname, GLint64* params) + GL_FUNC_TYPEDEF(void, glGenSamplers, GLsizei count, GLuint* samplers) + GL_FUNC_TYPEDEF(void, glDeleteSamplers, GLsizei count, const GLuint* samplers) + GL_FUNC_TYPEDEF(GLboolean, glIsSampler, GLuint sampler) + GL_FUNC_TYPEDEF(void, glBindSampler, GLuint unit, GLuint sampler) + GL_FUNC_TYPEDEF(void, glSamplerParameteri, GLuint sampler, GLenum pname, GLint param) + GL_FUNC_TYPEDEF(void, glSamplerParameteriv, GLuint sampler, GLenum pname, const GLint* param) + GL_FUNC_TYPEDEF(void, glSamplerParameterf, GLuint sampler, GLenum pname, GLfloat param) + GL_FUNC_TYPEDEF(void, glSamplerParameterfv, GLuint sampler, GLenum pname, const GLfloat* param) + GL_FUNC_TYPEDEF(void, glGetSamplerParameteriv, GLuint sampler, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glGetSamplerParameterfv, GLuint sampler, GLenum pname, GLfloat* params) + GL_FUNC_TYPEDEF(void, glVertexAttribDivisor, GLuint index, GLuint divisor) + GL_FUNC_TYPEDEF(void, glBindTransformFeedback, GLenum target, GLuint id) + GL_FUNC_TYPEDEF(void, glDeleteTransformFeedbacks, GLsizei n, const GLuint* ids) + GL_FUNC_TYPEDEF(void, glGenTransformFeedbacks, GLsizei n, GLuint* ids) + GL_FUNC_TYPEDEF(GLboolean, glIsTransformFeedback, GLuint id) + GL_FUNC_TYPEDEF(void, glPauseTransformFeedback) + GL_FUNC_TYPEDEF(void, glResumeTransformFeedback) + GL_FUNC_TYPEDEF(void, glGetProgramBinary, GLuint program, GLsizei bufSize, GLsizei* length, + GLenum* binaryFormat, void* binary) + GL_FUNC_TYPEDEF(void, glProgramBinary, GLuint program, GLenum binaryFormat, const void* binary, + GLsizei length) + GL_FUNC_TYPEDEF(void, glProgramParameteri, GLuint program, GLenum pname, GLint value) + GL_FUNC_TYPEDEF(void, glInvalidateFramebuffer, GLenum target, GLsizei numAttachments, + const GLenum* attachments) + GL_FUNC_TYPEDEF(void, glInvalidateSubFramebuffer, GLenum target, GLsizei numAttachments, + const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) + GL_FUNC_TYPEDEF(void, glTexStorage2D, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, + GLsizei height) + GL_FUNC_TYPEDEF(void, glTexStorage3D, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth) + GL_FUNC_TYPEDEF(void, glGetInternalformativ, GLenum target, GLenum internalformat, GLenum pname, + GLsizei bufSize, GLint* params) + GL_FUNC_TYPEDEF(void, glDispatchCompute, GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) + GL_FUNC_TYPEDEF(void, glDispatchComputeIndirect, GLintptr indirect) + GL_FUNC_TYPEDEF(void, glDrawArraysIndirect, GLenum mode, const void* indirect) + GL_FUNC_TYPEDEF(void, glDrawElementsIndirect, GLenum mode, GLenum type, const void* indirect) + GL_FUNC_TYPEDEF(void, glFramebufferParameteri, GLenum target, GLenum pname, GLint param) + GL_FUNC_TYPEDEF(void, glGetFramebufferParameteriv, GLenum target, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glGetProgramInterfaceiv, GLuint program, GLenum programInterface, GLenum pname, + GLint* params) + GL_FUNC_TYPEDEF(GLuint, glGetProgramResourceIndex, GLuint program, GLenum programInterface, + const GLchar* name) + GL_FUNC_TYPEDEF(void, glGetProgramResourceName, GLuint program, GLenum programInterface, GLuint index, + GLsizei bufSize, GLsizei* length, GLchar* name) + GL_FUNC_TYPEDEF(void, glGetProgramResourceiv, GLuint program, GLenum programInterface, GLuint index, + GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params) + GL_FUNC_TYPEDEF(GLint, glGetProgramResourceLocation, GLuint program, GLenum programInterface, + const GLchar* name) + GL_FUNC_TYPEDEF(void, glUseProgramStages, GLuint pipeline, GLbitfield stages, GLuint program) + GL_FUNC_TYPEDEF(void, glActiveShaderProgram, GLuint pipeline, GLuint program) + GL_FUNC_TYPEDEF(GLuint, glCreateShaderProgramv, GLenum type, GLsizei count, const GLchar* const* strings) + GL_FUNC_TYPEDEF(void, glBindProgramPipeline, GLuint pipeline) + GL_FUNC_TYPEDEF(void, glDeleteProgramPipelines, GLsizei n, const GLuint* pipelines) + GL_FUNC_TYPEDEF(void, glGenProgramPipelines, GLsizei n, GLuint* pipelines) + GL_FUNC_TYPEDEF(GLboolean, glIsProgramPipeline, GLuint pipeline) + GL_FUNC_TYPEDEF(void, glGetProgramPipelineiv, GLuint pipeline, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glProgramUniform1i, GLuint program, GLint location, GLint v0) + GL_FUNC_TYPEDEF(void, glProgramUniform2i, GLuint program, GLint location, GLint v0, GLint v1) + GL_FUNC_TYPEDEF(void, glProgramUniform3i, GLuint program, GLint location, GLint v0, GLint v1, GLint v2) + GL_FUNC_TYPEDEF(void, glProgramUniform4i, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, + GLint v3) + GL_FUNC_TYPEDEF(void, glProgramUniform1ui, GLuint program, GLint location, GLuint v0) + GL_FUNC_TYPEDEF(void, glProgramUniform2ui, GLuint program, GLint location, GLuint v0, GLuint v1) + GL_FUNC_TYPEDEF(void, glProgramUniform3ui, GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) + GL_FUNC_TYPEDEF(void, glProgramUniform4ui, GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, + GLuint v3) + GL_FUNC_TYPEDEF(void, glProgramUniform1f, GLuint program, GLint location, GLfloat v0) + GL_FUNC_TYPEDEF(void, glProgramUniform2f, GLuint program, GLint location, GLfloat v0, GLfloat v1) + GL_FUNC_TYPEDEF(void, glProgramUniform3f, GLuint program, GLint location, GLfloat v0, GLfloat v1, + GLfloat v2) + GL_FUNC_TYPEDEF(void, glProgramUniform4f, GLuint program, GLint location, GLfloat v0, GLfloat v1, + GLfloat v2, GLfloat v3) + GL_FUNC_TYPEDEF(void, glProgramUniform1iv, GLuint program, GLint location, GLsizei count, + const GLint* value) + GL_FUNC_TYPEDEF(void, glProgramUniform2iv, GLuint program, GLint location, GLsizei count, + const GLint* value) + GL_FUNC_TYPEDEF(void, glProgramUniform3iv, GLuint program, GLint location, GLsizei count, + const GLint* value) + GL_FUNC_TYPEDEF(void, glProgramUniform4iv, GLuint program, GLint location, GLsizei count, + const GLint* value) + GL_FUNC_TYPEDEF(void, glProgramUniform1uiv, GLuint program, GLint location, GLsizei count, + const GLuint* value) + GL_FUNC_TYPEDEF(void, glProgramUniform2uiv, GLuint program, GLint location, GLsizei count, + const GLuint* value) + GL_FUNC_TYPEDEF(void, glProgramUniform3uiv, GLuint program, GLint location, GLsizei count, + const GLuint* value) + GL_FUNC_TYPEDEF(void, glProgramUniform4uiv, GLuint program, GLint location, GLsizei count, + const GLuint* value) + GL_FUNC_TYPEDEF(void, glProgramUniform1fv, GLuint program, GLint location, GLsizei count, + const GLfloat* value) + GL_FUNC_TYPEDEF(void, glProgramUniform2fv, GLuint program, GLint location, GLsizei count, + const GLfloat* value) + GL_FUNC_TYPEDEF(void, glProgramUniform3fv, GLuint program, GLint location, GLsizei count, + const GLfloat* value) + GL_FUNC_TYPEDEF(void, glProgramUniform4fv, GLuint program, GLint location, GLsizei count, + const GLfloat* value) + GL_FUNC_TYPEDEF(void, glProgramUniformMatrix2fv, GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glProgramUniformMatrix3fv, GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glProgramUniformMatrix4fv, GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glProgramUniformMatrix2x3fv, GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glProgramUniformMatrix3x2fv, GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glProgramUniformMatrix2x4fv, GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glProgramUniformMatrix4x2fv, GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glProgramUniformMatrix3x4fv, GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glProgramUniformMatrix4x3fv, GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLfloat* value) + GL_FUNC_TYPEDEF(void, glValidateProgramPipeline, GLuint pipeline) + GL_FUNC_TYPEDEF(void, glGetProgramPipelineInfoLog, GLuint pipeline, GLsizei bufSize, GLsizei* length, + GLchar* infoLog) + GL_FUNC_TYPEDEF(void, glBindImageTexture, GLuint unit, GLuint texture, GLint level, GLboolean layered, + GLint layer, GLenum access, GLenum format) + GL_FUNC_TYPEDEF(void, glGetBooleani_v, GLenum target, GLuint index, GLboolean* data) + GL_FUNC_TYPEDEF(void, glMemoryBarrier, GLbitfield barriers) + GL_FUNC_TYPEDEF(void, glMemoryBarrierByRegion, GLbitfield barriers) + GL_FUNC_TYPEDEF(void, glTexStorage2DMultisample, GLenum target, GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height, GLboolean fixedsamplelocations) + GL_FUNC_TYPEDEF(void, glGetMultisamplefv, GLenum pname, GLuint index, GLfloat* val) + GL_FUNC_TYPEDEF(void, glSampleMaski, GLuint maskNumber, GLbitfield mask) + GL_FUNC_TYPEDEF(void, glGetTexLevelParameteriv, GLenum target, GLint level, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glGetTexLevelParameterfv, GLenum target, GLint level, GLenum pname, GLfloat* params) + GL_FUNC_TYPEDEF(void, glBindVertexBuffer, GLuint bindingindex, GLuint buffer, GLintptr offset, + GLsizei stride) + GL_FUNC_TYPEDEF(void, glVertexAttribFormat, GLuint attribindex, GLint size, GLenum type, + GLboolean normalized, GLuint relativeoffset) + GL_FUNC_TYPEDEF(void, glVertexAttribIFormat, GLuint attribindex, GLint size, GLenum type, + GLuint relativeoffset) + GL_FUNC_TYPEDEF(void, glVertexAttribBinding, GLuint attribindex, GLuint bindingindex) + GL_FUNC_TYPEDEF(void, glVertexBindingDivisor, GLuint bindingindex, GLuint divisor) + GL_FUNC_TYPEDEF(void, glBlendBarrier) + GL_FUNC_TYPEDEF(void, glCopyImageSubData, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, + GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, + GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) + GL_FUNC_TYPEDEF(void, glDebugMessageControl, GLenum source, GLenum type, GLenum severity, GLsizei count, + const GLuint* ids, GLboolean enabled) + GL_FUNC_TYPEDEF(void, glDebugMessageInsert, GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei length, const GLchar* buf) + GL_FUNC_TYPEDEF(void, glDebugMessageCallback, GLDEBUGPROC callback, const void* userParam) + GL_FUNC_TYPEDEF(GLuint, glGetDebugMessageLog, GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, + GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog) + GL_FUNC_TYPEDEF(void, glPushDebugGroup, GLenum source, GLuint id, GLsizei length, const GLchar* message) + GL_FUNC_TYPEDEF(void, glPopDebugGroup) + GL_FUNC_TYPEDEF(void, glObjectLabel, GLenum identifier, GLuint name, GLsizei length, const GLchar* label) + GL_FUNC_TYPEDEF(void, glGetObjectLabel, GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, + GLchar* label) + GL_FUNC_TYPEDEF(void, glObjectPtrLabel, const void* ptr, GLsizei length, const GLchar* label) + GL_FUNC_TYPEDEF(void, glGetObjectPtrLabel, const void* ptr, GLsizei bufSize, GLsizei* length, GLchar* label) + GL_FUNC_TYPEDEF(void, glGetPointerv, GLenum pname, void** params) + GL_FUNC_TYPEDEF(void, glEnablei, GLenum target, GLuint index) + GL_FUNC_TYPEDEF(void, glDisablei, GLenum target, GLuint index) + GL_FUNC_TYPEDEF(void, glBlendEquationi, GLuint buf, GLenum mode) + GL_FUNC_TYPEDEF(void, glBlendEquationSeparatei, GLuint buf, GLenum modeRGB, GLenum modeAlpha) + GL_FUNC_TYPEDEF(void, glBlendFunci, GLuint buf, GLenum src, GLenum dst) + GL_FUNC_TYPEDEF(void, glBlendFuncSeparatei, GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, + GLenum dstAlpha) + GL_FUNC_TYPEDEF(void, glColorMaski, GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) + GL_FUNC_TYPEDEF(GLboolean, glIsEnabledi, GLenum target, GLuint index) + GL_FUNC_TYPEDEF(void, glDrawElementsBaseVertex, GLenum mode, GLsizei count, GLenum type, + const void* indices, GLint basevertex) + GL_FUNC_TYPEDEF(void, glDrawRangeElementsBaseVertex, GLenum mode, GLuint start, GLuint end, GLsizei count, + GLenum type, const void* indices, GLint basevertex) + GL_FUNC_TYPEDEF(void, glDrawElementsInstancedBaseVertex, GLenum mode, GLsizei count, GLenum type, + const void* indices, GLsizei instancecount, GLint basevertex) + GL_FUNC_TYPEDEF(void, glFramebufferTexture, GLenum target, GLenum attachment, GLuint texture, GLint level) + GL_FUNC_TYPEDEF(void, glPrimitiveBoundingBox, GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, + GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW) + GL_FUNC_TYPEDEF(GLenum, glGetGraphicsResetStatus) + GL_FUNC_TYPEDEF(void, glReadnPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLsizei bufSize, void* data) + GL_FUNC_TYPEDEF(void, glGetnUniformfv, GLuint program, GLint location, GLsizei bufSize, GLfloat* params) + GL_FUNC_TYPEDEF(void, glGetnUniformiv, GLuint program, GLint location, GLsizei bufSize, GLint* params) + GL_FUNC_TYPEDEF(void, glGetnUniformuiv, GLuint program, GLint location, GLsizei bufSize, GLuint* params) + GL_FUNC_TYPEDEF(void, glMinSampleShading, GLfloat value) + GL_FUNC_TYPEDEF(void, glPatchParameteri, GLenum pname, GLint value) + GL_FUNC_TYPEDEF(void, glTexParameterIiv, GLenum target, GLenum pname, const GLint* params) + GL_FUNC_TYPEDEF(void, glTexParameterIuiv, GLenum target, GLenum pname, const GLuint* params) + GL_FUNC_TYPEDEF(void, glGetTexParameterIiv, GLenum target, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glGetTexParameterIuiv, GLenum target, GLenum pname, GLuint* params) + GL_FUNC_TYPEDEF(void, glSamplerParameterIiv, GLuint sampler, GLenum pname, const GLint* param) + GL_FUNC_TYPEDEF(void, glSamplerParameterIuiv, GLuint sampler, GLenum pname, const GLuint* param) + GL_FUNC_TYPEDEF(void, glGetSamplerParameterIiv, GLuint sampler, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glGetSamplerParameterIuiv, GLuint sampler, GLenum pname, GLuint* params) + GL_FUNC_TYPEDEF(void, glTexBuffer, GLenum target, GLenum internalformat, GLuint buffer) + GL_FUNC_TYPEDEF(void, glTexBufferRange, GLenum target, GLenum internalformat, GLuint buffer, + GLintptr offset, GLsizeiptr size) + GL_FUNC_TYPEDEF(void, glTexStorage3DMultisample, GLenum target, GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) + GL_FUNC_TYPEDEF(void*, glMapBufferRange, GLenum target, GLintptr offset, GLsizeiptr length, + GLbitfield access) + GL_FUNC_TYPEDEF(void, glBufferStorageEXT, GLenum target, GLsizeiptr size, const void* data, + GLbitfield flags) + GL_FUNC_TYPEDEF(void, glGetQueryObjectivEXT, GLuint id, GLenum pname, GLint* params) + GL_FUNC_TYPEDEF(void, glGetQueryObjecti64vEXT, GLuint id, GLenum pname, GLint64* params) + GL_FUNC_TYPEDEF(void, glBindFragDataLocationEXT, GLuint program, GLuint colorNumber, const GLchar* name) + GL_FUNC_TYPEDEF(void*, glMapBufferOES, GLenum target, GLenum access) - Int uniformBufferOffsetAlignment; - }; - } // namespace Caps + GL_FUNC_TYPEDEF(void, glMultiDrawArraysIndirectEXT, GLenum mode, const void* indirect, GLsizei drawcount, + GLsizei stride) + GL_FUNC_TYPEDEF(void, glMultiDrawElementsIndirectEXT, GLenum mode, GLenum type, const void* indirect, + GLsizei drawcount, GLsizei stride) + GL_FUNC_TYPEDEF(void, glBruh) + GL_FUNC_TYPEDEF(void, glMultiDrawElementsBaseVertexEXT, GLenum mode, const GLsizei* count, GLenum type, + const void* const* indices, GLsizei drawcount, const GLint* basevertex) + /* + namespace Caps { + struct GLESCaps { + Version version; + Bool hasPersistentMapping; + Bool hasNorm16Texture; - extern Caps::GLESCaps g_glesCaps; + Int uniformBufferOffsetAlignment; + }; + } // namespace Caps + extern Caps::GLESCaps g_glesCaps;*/ // TODO: migrate this to BackendObject + } // namespace GLES + + struct GLESFunctionsTable { GL_FUNC_DECL(glActiveTexture) GL_FUNC_DECL(glAttachShader) GL_FUNC_DECL(glBindAttribLocation) @@ -954,29 +1001,30 @@ namespace MobileGL { GL_FUNC_DECL(glMultiDrawElementsBaseVertexEXT) GL_FUNC_DECL(glBruh) - } // namespace GLES + }; + + struct GLESCapabilities { + Version GLESVersion{3, 0, 0}; + String GLESVersionString; + String GLESVendorString; + String GLESRendererString; + String GLESShadingLanguageVersionString; + Bool SupportsPersistentMapping = false; + Bool SupportsNorm16Texture = false; + Int UniformBufferOffsetAlignment = 256; + }; } // namespace MG_External + namespace MG_Util::BackendLoader { + Bool AcquireGLESFunctions(MG_External::GLESFunctionsTable& funcs, + MG_External::EGL::eglGetProcAddress_PTR procAddress); + Bool AcquireEGLFunctions(MG_External::EGLFunctionsTable& funcs); + Bool FillInGLESCapabilities(MG_External::GLESCapabilities& caps, + const MG_External::GLESFunctionsTable& glesFuncs, + const MG_External::EGLFunctionsTable& eglFuncs); + } // namespace MG_Util::BackendLoader +} // namespace MobileGL +#undef MOBILEGL_EXTERNAL_GLES +#undef GL_FUNC_TYPEDEF #undef EGL_FUNC_DECL #undef GL_FUNC_DECL - - namespace MG_Util { - namespace BackendLoader { - namespace GLES { - Bool Init(); - extern void *libGLES, *libEGL; - - void* ProcAddress(void* lib, const char* name); - void InitGLES(); - void InitEGL(); - void DestroyTempEGLCtx(); - void LoadLibs(); - void* OpenLib(const char** names, const char* override); - - } // namespace GLES - } // namespace BackendLoader - } // namespace MG_Util -} // namespace MobileGL - -#define INIT_GLES_FUNC(name) \ - { MG_External::GLES::name = (name##_PTR)ProcAddress(libGLES, #name); } diff --git a/MobileGL/MG_Util/Converters/EGLToStr/EGLEnumConverter.h b/MobileGL/MG_Util/Converters/EGLToStr/EGLEnumConverter.h index 1d175d28..6da1641e 100644 --- a/MobileGL/MG_Util/Converters/EGLToStr/EGLEnumConverter.h +++ b/MobileGL/MG_Util/Converters/EGLToStr/EGLEnumConverter.h @@ -12,5 +12,5 @@ namespace MobileGL { namespace MG_Util { String ConvertEGLEnumToString(GLenum value); - } + } // namespace MG_Util } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/GLToGlslang/ProgramEnumConverter.h b/MobileGL/MG_Util/Converters/GLToGlslang/ProgramEnumConverter.h index a370b0e2..0fffcf5d 100644 --- a/MobileGL/MG_Util/Converters/GLToGlslang/ProgramEnumConverter.h +++ b/MobileGL/MG_Util/Converters/GLToGlslang/ProgramEnumConverter.h @@ -12,5 +12,5 @@ namespace MobileGL { namespace MG_Util { EShLanguage ConvertGLEnumToEShLanguage(GLenum shaderType); - } + } // namespace MG_Util } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.h b/MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.h index 4fbcf634..00863788 100644 --- a/MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.h +++ b/MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.h @@ -12,5 +12,5 @@ namespace MobileGL { namespace MG_Util { DataType ConvertGLEnumToDataType(GLenum type); - } + } // namespace MG_Util } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/GLToMG/FramebufferEnumConverter.cpp b/MobileGL/MG_Util/Converters/GLToMG/FramebufferEnumConverter.cpp index 4f094c0f..60718d75 100644 --- a/MobileGL/MG_Util/Converters/GLToMG/FramebufferEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/GLToMG/FramebufferEnumConverter.cpp @@ -30,22 +30,22 @@ namespace MobileGL { } switch (attachment) { - case GL_NONE: - return FramebufferAttachmentType::None; - case GL_DEPTH_ATTACHMENT: - return FramebufferAttachmentType::Depth; - case GL_STENCIL_ATTACHMENT: - return FramebufferAttachmentType::Stencil; - case GL_FRONT_LEFT: - return FramebufferAttachmentType::FrontLeft; - case GL_FRONT_RIGHT: - return FramebufferAttachmentType::FrontRight; - case GL_BACK_LEFT: - return FramebufferAttachmentType::BackLeft; - case GL_BACK_RIGHT: - return FramebufferAttachmentType::BackRight; - default: - return FramebufferAttachmentType::Unknown; + case GL_NONE: + return FramebufferAttachmentType::None; + case GL_DEPTH_ATTACHMENT: + return FramebufferAttachmentType::Depth; + case GL_STENCIL_ATTACHMENT: + return FramebufferAttachmentType::Stencil; + case GL_FRONT_LEFT: + return FramebufferAttachmentType::FrontLeft; + case GL_FRONT_RIGHT: + return FramebufferAttachmentType::FrontRight; + case GL_BACK_LEFT: + return FramebufferAttachmentType::BackLeft; + case GL_BACK_RIGHT: + return FramebufferAttachmentType::BackRight; + default: + return FramebufferAttachmentType::Unknown; } } diff --git a/MobileGL/MG_Util/Converters/GLToMG/ProgramEnumConverter.h b/MobileGL/MG_Util/Converters/GLToMG/ProgramEnumConverter.h index 0478be8c..249099df 100644 --- a/MobileGL/MG_Util/Converters/GLToMG/ProgramEnumConverter.h +++ b/MobileGL/MG_Util/Converters/GLToMG/ProgramEnumConverter.h @@ -13,5 +13,5 @@ namespace MobileGL { namespace MG_Util { ShaderStage ConvertGLEnumToShaderStage(GLenum type); - } + } // namespace MG_Util } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.cpp b/MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.cpp index 9b1da759..07cb4400 100644 --- a/MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.cpp @@ -1823,9 +1823,9 @@ namespace MobileGL { CASE(GL_FOG_SPECULAR_TEXTURE_WIN) default: - return std::format("0x%x", value); + return std::format("0x{:x}", value); } #undef CASE } } // namespace MG_Util -} // namespace MobileGL \ No newline at end of file +} // namespace MobileGL diff --git a/MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.h b/MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.h index 3fc68843..66255182 100644 --- a/MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.h +++ b/MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.h @@ -12,5 +12,5 @@ namespace MobileGL { namespace MG_Util { String ConvertGLEnumToString(GLenum value); - } + } // namespace MG_Util } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.h b/MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.h index 3812b2dd..4eb38655 100644 --- a/MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.h +++ b/MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.h @@ -12,5 +12,5 @@ namespace MobileGL { namespace MG_Util { GLenum ConvertDataTypeToGLEnum(DataType type); - } + } // namespace MG_Util } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/MGToGL/ErrorCodeConverter.h b/MobileGL/MG_Util/Converters/MGToGL/ErrorCodeConverter.h index dbcfac2e..764f3844 100644 --- a/MobileGL/MG_Util/Converters/MGToGL/ErrorCodeConverter.h +++ b/MobileGL/MG_Util/Converters/MGToGL/ErrorCodeConverter.h @@ -13,5 +13,5 @@ namespace MobileGL { namespace MG_Util { GLenum ConvertErrorCodeToGLEnum(ErrorCode code); - } + } // namespace MG_Util } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/MGToGL/FramebufferEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToGL/FramebufferEnumConverter.cpp index 18bced6d..de6cc7cc 100644 --- a/MobileGL/MG_Util/Converters/MGToGL/FramebufferEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToGL/FramebufferEnumConverter.cpp @@ -29,20 +29,20 @@ namespace MobileGL { } switch (type) { - case FramebufferAttachmentType::Depth: - return GL_DEPTH_ATTACHMENT; - case FramebufferAttachmentType::Stencil: - return GL_STENCIL_ATTACHMENT; - case FramebufferAttachmentType::FrontLeft: - return GL_FRONT_LEFT; - case FramebufferAttachmentType::FrontRight: - return GL_FRONT_RIGHT; - case FramebufferAttachmentType::BackLeft: - return GL_BACK_LEFT; - case FramebufferAttachmentType::BackRight: - return GL_BACK_RIGHT; - default: - return GL_NONE; + case FramebufferAttachmentType::Depth: + return GL_DEPTH_ATTACHMENT; + case FramebufferAttachmentType::Stencil: + return GL_STENCIL_ATTACHMENT; + case FramebufferAttachmentType::FrontLeft: + return GL_FRONT_LEFT; + case FramebufferAttachmentType::FrontRight: + return GL_FRONT_RIGHT; + case FramebufferAttachmentType::BackLeft: + return GL_BACK_LEFT; + case FramebufferAttachmentType::BackRight: + return GL_BACK_RIGHT; + default: + return GL_NONE; } } diff --git a/MobileGL/MG_Util/Converters/MGToGL/ProgramEnumConverter.h b/MobileGL/MG_Util/Converters/MGToGL/ProgramEnumConverter.h index 7fa0bec7..88c61299 100644 --- a/MobileGL/MG_Util/Converters/MGToGL/ProgramEnumConverter.h +++ b/MobileGL/MG_Util/Converters/MGToGL/ProgramEnumConverter.h @@ -13,5 +13,5 @@ namespace MobileGL { namespace MG_Util { GLenum ConvertShaderStageToGLEnum(ShaderStage stage); - } + } // namespace MG_Util } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/MGToStr/DataTypeConverter.h b/MobileGL/MG_Util/Converters/MGToStr/DataTypeConverter.h index 112b4531..839a34b0 100644 --- a/MobileGL/MG_Util/Converters/MGToStr/DataTypeConverter.h +++ b/MobileGL/MG_Util/Converters/MGToStr/DataTypeConverter.h @@ -12,5 +12,5 @@ namespace MobileGL { namespace MG_Util { String ConvertDataTypeToString(DataType type); - } + } // namespace MG_Util } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/MGToStr/GLExtensionConverter.h b/MobileGL/MG_Util/Converters/MGToStr/GLExtensionConverter.h index 3d032c59..a624eb2f 100644 --- a/MobileGL/MG_Util/Converters/MGToStr/GLExtensionConverter.h +++ b/MobileGL/MG_Util/Converters/MGToStr/GLExtensionConverter.h @@ -12,5 +12,5 @@ namespace MobileGL { namespace MG_Util { String ConvertGLExtToString(GLExtension extension); - } + } // namespace MG_Util } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_Util/Metrics/BufferMetrics.h b/MobileGL/MG_Util/Metrics/BufferMetrics.h index 53f0e1bc..08191c45 100644 --- a/MobileGL/MG_Util/Metrics/BufferMetrics.h +++ b/MobileGL/MG_Util/Metrics/BufferMetrics.h @@ -12,5 +12,5 @@ namespace MobileGL { namespace MG_Util { SizeT GetGLTypeSize(GLenum type); - } + } // namespace MG_Util } // namespace MobileGL diff --git a/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp b/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp index 74c532fe..60519cf4 100644 --- a/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp +++ b/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp @@ -208,11 +208,11 @@ namespace MobileGL::MG_Util::PixelStoreProcessor { bool needSwizzle = false; static Vector swizzle; - swizzle = { TextureSwizzleParam::Red, TextureSwizzleParam::Green, - TextureSwizzleParam::Blue, TextureSwizzleParam::Alpha }; + swizzle = {TextureSwizzleParam::Red, TextureSwizzleParam::Green, TextureSwizzleParam::Blue, + TextureSwizzleParam::Alpha}; if (srcInternalFormat == TextureInternalFormat::RGBA && dstInputFormat == TextureInputFormat::BGRA) { - swizzle = { TextureSwizzleParam::Blue, TextureSwizzleParam::Green, - TextureSwizzleParam::Red, TextureSwizzleParam::Alpha }; + swizzle = {TextureSwizzleParam::Blue, TextureSwizzleParam::Green, TextureSwizzleParam::Red, + TextureSwizzleParam::Alpha}; needSwizzle = true; } if (dstDataType == TexturePixelDataType::UnsignedInt8888) { diff --git a/MobileGL/MG_Util/Texture/TextureFormatProcessor.h b/MobileGL/MG_Util/Texture/TextureFormatProcessor.h index a8038d6b..6a2c9135 100644 --- a/MobileGL/MG_Util/Texture/TextureFormatProcessor.h +++ b/MobileGL/MG_Util/Texture/TextureFormatProcessor.h @@ -18,5 +18,5 @@ namespace MobileGL { namespace MG_Util::TextureFormatProcessor { void NormalizePixelFormat(GLenum internalFormat, Flags options, GLenum* outInternalFormat, GLenum* outFormat, GLenum* outType); - } + } // namespace MG_Util::TextureFormatProcessor } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_Util/Types.h b/MobileGL/MG_Util/Types.h index 725be14d..9ba2fc86 100644 --- a/MobileGL/MG_Util/Types.h +++ b/MobileGL/MG_Util/Types.h @@ -75,6 +75,10 @@ namespace MobileGL { using E = std::common_type_t; return std::array{{std::forward(elems)...}}; } + template + inline String ToString(const T& value) { + return std::to_string(value); + } class RuntimeError : public std::runtime_error { public: using std::runtime_error::runtime_error; @@ -252,7 +256,7 @@ namespace MobileGL { } }; - struct BackendCap { + struct StaticBackendCapabilityT { Bool AllowVSOnlyPrograms = false; }; @@ -268,7 +272,7 @@ namespace MobileGL { String BackendName; Optional ExtraVendor; GLInfo RendererGLInfo; - BackendCap BackendCapability; + StaticBackendCapabilityT StaticBackendCapability; }; template Date: Wed, 18 Feb 2026 11:02:36 +0800 Subject: [PATCH 09/12] [Fix] (MG_Util): Fix compilation. --- MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp index 05c3efd3..ec9b3865 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp @@ -612,10 +612,10 @@ namespace MobileGL::MG_Util::BackendLoader { glesFuncs.glGetIntegerv(GL_MAJOR_VERSION, &caps.GLESVersion.Major); glesFuncs.glGetIntegerv(GL_MINOR_VERSION, &caps.GLESVersion.Minor); - caps.GLESVersionString = ToString(glesFuncs.glGetString(GL_VERSION)); - caps.GLESRendererString = ToString(gpuName); - caps.GLESVendorString = ToString(vendorName); - caps.GLESShadingLanguageVersionString = ToString(glesFuncs.glGetString(GL_SHADING_LANGUAGE_VERSION)); + caps.GLESVersionString = String((char*)glesFuncs.glGetString(GL_VERSION)); + caps.GLESRendererString = Sttring((char*)gpuName); + caps.GLESVendorString = String((char*)vendorName); + caps.GLESShadingLanguageVersionString = String((char*)glesFuncs.glGetString(GL_SHADING_LANGUAGE_VERSION)); GLint extCount = 0; glesFuncs.glGetIntegerv(GL_NUM_EXTENSIONS, &extCount); From f65c71da2700a4d4546f1f375c56d3117c5a060c Mon Sep 17 00:00:00 2001 From: BZLZHH <69153940+BZLZHH@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:10:49 +0800 Subject: [PATCH 10/12] [Fix] (MG_Util): Fix typo. --- MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp index ec9b3865..7c8b7863 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp @@ -613,7 +613,7 @@ namespace MobileGL::MG_Util::BackendLoader { glesFuncs.glGetIntegerv(GL_MINOR_VERSION, &caps.GLESVersion.Minor); caps.GLESVersionString = String((char*)glesFuncs.glGetString(GL_VERSION)); - caps.GLESRendererString = Sttring((char*)gpuName); + caps.GLESRendererString = String((char*)gpuName); caps.GLESVendorString = String((char*)vendorName); caps.GLESShadingLanguageVersionString = String((char*)glesFuncs.glGetString(GL_SHADING_LANGUAGE_VERSION)); From e34f3d915c403d40adaff9aaf658aa6b6ed79e17 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Wed, 18 Feb 2026 22:28:20 +0800 Subject: [PATCH 11/12] [Fix] (MG_Impl/EGLImpl): Fix GetProcAddress. --- MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp | 11 +- .../MG_Impl/EGLImpl/Exporting/Definitions.cpp | 103 +++++++++--------- 2 files changed, 51 insertions(+), 63 deletions(-) diff --git a/MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp b/MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp index ef904cd7..973205e7 100644 --- a/MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp +++ b/MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp @@ -7,7 +7,7 @@ // End of Source File Header #include "EGLImpl.h" -#include "EGL/egl.h" +#include "../GetProcAddress.h" #include namespace MobileGL::MG_Impl::EGLImpl { @@ -21,9 +21,6 @@ namespace MobileGL::MG_Impl::EGLImpl { } activeBackendObject->SetWindowHandle({MG_Backend::WindowBackend::Android, reinterpret_cast(window)}); activeBackendObject->InitWindowSurface(); - glClearColor(1, 1, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); - SwapBuffers((EGLDisplay)1, (EGLSurface)1); return (EGLSurface)1; } @@ -239,11 +236,7 @@ namespace MobileGL::MG_Impl::EGLImpl { __eglMustCastToProperFunctionPointerType GetProcAddress(const char* name) { MGLOG_D("eglGetProcAddress(%s)", name); -#if !defined(WIN32) && !defined(__APPLE__) - void* proc = dlsym(RTLD_DEFAULT, (const char*)name); -#else - void* proc = NULL; -#endif + void* proc = MG_Impl::GetProcAddress(name); if (!proc) { MGLOG_W("Failed to get function: %s", (const char*)name); return nullptr; diff --git a/MobileGL/MG_Impl/EGLImpl/Exporting/Definitions.cpp b/MobileGL/MG_Impl/EGLImpl/Exporting/Definitions.cpp index 669da2ab..f155ba58 100644 --- a/MobileGL/MG_Impl/EGLImpl/Exporting/Definitions.cpp +++ b/MobileGL/MG_Impl/EGLImpl/Exporting/Definitions.cpp @@ -11,22 +11,20 @@ MOBILEGL_EGL_API EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint* attrib_list) { - MGLOG_D("[MobileGL] eglCreateWindowSurface(dpy=%p, config=%p, window=%p, attrib_list=%p)", dpy, config, window, - attrib_list); + MGLOG_D("eglCreateWindowSurface(dpy=%p, config=%p, window=%p, attrib_list=%p)", dpy, config, window, attrib_list); return MobileGL::MG_Impl::EGLImpl::CreateWindowSurface(dpy, config, window, attrib_list); } MOBILEGL_EGL_API EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config) { - MGLOG_D("[MobileGL] eglChooseConfig(dpy=%p, attrib_list=%p, configs=%p, config_size=%d, num_config=%p)", dpy, - attrib_list, configs, config_size, num_config); + MGLOG_D("eglChooseConfig(dpy=%p, attrib_list=%p, configs=%p, config_size=%d, num_config=%p)", dpy, attrib_list, + configs, config_size, num_config); return MobileGL::MG_Impl::EGLImpl::ChooseConfig(dpy, attrib_list, configs, config_size, num_config); } MOBILEGL_EGL_API EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareCtx, const EGLint* attrib_list) { - MGLOG_D("[MobileGL] eglCreateContext(dpy=%p, config=%p, shareCtx=%p, attrib_list=%p)", dpy, config, shareCtx, - attrib_list); + MGLOG_D("eglCreateContext(dpy=%p, config=%p, shareCtx=%p, attrib_list=%p)", dpy, config, shareCtx, attrib_list); #ifdef TRACY_ENABLE tracy::StartupProfiler(); #endif @@ -34,27 +32,27 @@ MOBILEGL_EGL_API EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, E } MOBILEGL_EGL_API EGLBoolean eglInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) { - MGLOG_D("[MobileGL] eglInitialize(dpy=%p, major=%p, minor=%p)", dpy, major, minor); + MGLOG_D("eglInitialize(dpy=%p, major=%p, minor=%p)", dpy, major, minor); return MobileGL::MG_Impl::EGLImpl::Initialize(dpy, major, minor); } MOBILEGL_EGL_API EGLDisplay eglGetDisplay(NativeDisplayType display) { - MGLOG_D("[MobileGL] eglGetDisplay(display=%p)", display); + MGLOG_D("eglGetDisplay(display=%p)", display); return MobileGL::MG_Impl::EGLImpl::GetDisplay(display); } MOBILEGL_EGL_API EGLint eglGetError() { - MGLOG_D("[MobileGL] eglGetError()"); + MGLOG_D("eglGetError()"); return MobileGL::MG_Impl::EGLImpl::GetError(); } MOBILEGL_EGL_API EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { - MGLOG_D("[MobileGL] eglMakeCurrent(dpy=%p, draw=%p, read=%p, ctx=%p)", dpy, draw, read, ctx); + MGLOG_D("eglMakeCurrent(dpy=%p, draw=%p, read=%p, ctx=%p)", dpy, draw, read, ctx); return MobileGL::MG_Impl::EGLImpl::MakeCurrent(dpy, draw, read, ctx); } MOBILEGL_EGL_API EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { - MGLOG_D("[MobileGL] eglDestroyContext(dpy=%p, ctx=%p)", dpy, ctx); + MGLOG_D("eglDestroyContext(dpy=%p, ctx=%p)", dpy, ctx); #ifdef TRACY_ENABLE tracy::ShutdownProfiler(); #endif @@ -62,58 +60,57 @@ MOBILEGL_EGL_API EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { } MOBILEGL_EGL_API EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { - MGLOG_D("[MobileGL] eglDestroySurface(dpy=%p, surface=%p)", dpy, surface); + MGLOG_D("eglDestroySurface(dpy=%p, surface=%p)", dpy, surface); return MobileGL::MG_Impl::EGLImpl::DestroySurface(dpy, surface); } MOBILEGL_EGL_API EGLBoolean eglTerminate(EGLDisplay dpy) { - MGLOG_D("[MobileGL] eglTerminate(dpy=%p)", dpy); + MGLOG_D("eglTerminate(dpy=%p)", dpy); return MobileGL::MG_Impl::EGLImpl::Terminate(dpy); } MOBILEGL_EGL_API EGLBoolean eglReleaseThread(void) { - MGLOG_D("[MobileGL] eglReleaseThread()"); + MGLOG_D("eglReleaseThread()"); return MobileGL::MG_Impl::EGLImpl::ReleaseThread(); } MOBILEGL_EGL_API EGLContext eglGetCurrentContext(void) { - MGLOG_D("[MobileGL] eglGetCurrentContext()"); + MGLOG_D("eglGetCurrentContext()"); return MobileGL::MG_Impl::EGLImpl::GetCurrentContext(); } MOBILEGL_EGL_API EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value) { - MGLOG_D("[MobileGL] eglGetConfigAttrib(dpy=%p, config=%p, attribute=%d, value=%p)", dpy, config, attribute, value); + MGLOG_D("eglGetConfigAttrib(dpy=%p, config=%p, attribute=%d, value=%p)", dpy, config, attribute, value); return MobileGL::MG_Impl::EGLImpl::GetConfigAttrib(dpy, config, attribute, value); } MOBILEGL_EGL_API EGLBoolean eglBindAPI(EGLenum api) { - MGLOG_D("[MobileGL] eglBindAPI(api=%u)", api); + MGLOG_D("eglBindAPI(api=%u)", api); return MobileGL::MG_Impl::EGLImpl::BindAPI(api); } MOBILEGL_EGL_API EGLSurface eglGetCurrentSurface(EGLint readdraw) { - MGLOG_D("[MobileGL] eglGetCurrentSurface(readdraw=%d)", readdraw); + MGLOG_D("eglGetCurrentSurface(readdraw=%d)", readdraw); return MobileGL::MG_Impl::EGLImpl::GetCurrentSurface(readdraw); } MOBILEGL_EGL_API EGLBoolean eglQuerySurface(EGLDisplay display, EGLSurface surface, EGLint attribute, EGLint* value) { - MGLOG_D("[MobileGL] eglQuerySurface(display=%p, surface=%p, attribute=%d, value=%p)", display, surface, attribute, - value); + MGLOG_D("eglQuerySurface(display=%p, surface=%p, attribute=%d, value=%p)", display, surface, attribute, value); return MobileGL::MG_Impl::EGLImpl::QuerySurface(display, surface, attribute, value); } MOBILEGL_EGL_API char const* eglQueryString(EGLDisplay display, EGLint name) { - MGLOG_D("[MobileGL] eglQueryString(display=%p, name=%d)", display, name); + MGLOG_D("eglQueryString(display=%p, name=%d)", display, name); return MobileGL::MG_Impl::EGLImpl::QueryString(display, name); } MOBILEGL_EGL_API EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) { - MGLOG_D("[MobileGL] eglSwapInterval(dpy=%p, interval=%d)", dpy, interval); + MGLOG_D("eglSwapInterval(dpy=%p, interval=%d)", dpy, interval); return MobileGL::MG_Impl::EGLImpl::SwapInterval(dpy, interval); } MOBILEGL_EGL_API EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) { - MGLOG_D("[MobileGL] eglSwapBuffers(dpy=%p, draw=%p)", dpy, draw); + MGLOG_D("eglSwapBuffers(dpy=%p, draw=%p)", dpy, draw); #ifdef TRACY_ENABLE FrameMark; #endif @@ -121,140 +118,138 @@ MOBILEGL_EGL_API EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) { } MOBILEGL_EGL_API EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list) { - MGLOG_D("[MobileGL] eglCreatePbufferSurface(dpy=%p, config=%p, attrib_list=%p)", dpy, config, attrib_list); + MGLOG_D("eglCreatePbufferSurface(dpy=%p, config=%p, attrib_list=%p)", dpy, config, attrib_list); return MobileGL::MG_Impl::EGLImpl::CreatePbufferSurface(dpy, config, attrib_list); } MOBILEGL_EGL_API __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char* name) { - MGLOG_D("[MobileGL] eglGetProcAddress(name=%s)", name ? name : "null"); + MGLOG_D("eglGetProcAddress(name=%s)", name ? name : "null"); return MobileGL::MG_Impl::EGLImpl::GetProcAddress(name); } MOBILEGL_EGL_API EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - MGLOG_D("[MobileGL] eglBindTexImage(dpy=%p, surface=%p, buffer=%d)", dpy, surface, buffer); + MGLOG_D("eglBindTexImage(dpy=%p, surface=%p, buffer=%d)", dpy, surface, buffer); return MobileGL::MG_Impl::EGLImpl::BindTexImage(dpy, surface, buffer); } MOBILEGL_EGL_API EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - MGLOG_D("[MobileGL] eglReleaseTexImage(dpy=%p, surface=%p, buffer=%d)", dpy, surface, buffer); + MGLOG_D("eglReleaseTexImage(dpy=%p, surface=%p, buffer=%d)", dpy, surface, buffer); return MobileGL::MG_Impl::EGLImpl::ReleaseTexImage(dpy, surface, buffer); } MOBILEGL_EGL_API EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { - MGLOG_D("[MobileGL] eglCopyBuffers(dpy=%p, surface=%p, target=%p)", dpy, surface, target); + MGLOG_D("eglCopyBuffers(dpy=%p, surface=%p, target=%p)", dpy, surface, target); return MobileGL::MG_Impl::EGLImpl::CopyBuffers(dpy, surface, target); } MOBILEGL_EGL_API EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint* attrib_list) { - MGLOG_D("[MobileGL] eglCreatePbufferFromClientBuffer(dpy=%p, buftype=%u, buffer=%p, config=%p, attrib_list=%p)", - dpy, buftype, buffer, config, attrib_list); + MGLOG_D("eglCreatePbufferFromClientBuffer(dpy=%p, buftype=%u, buffer=%p, config=%p, attrib_list=%p)", dpy, buftype, + buffer, config, attrib_list); return MobileGL::MG_Impl::EGLImpl::CreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list); } MOBILEGL_EGL_API EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* attrib_list) { - MGLOG_D("[MobileGL] eglCreatePixmapSurface(dpy=%p, config=%p, pixmap=%p, attrib_list=%p)", dpy, config, pixmap, - attrib_list); + MGLOG_D("eglCreatePixmapSurface(dpy=%p, config=%p, pixmap=%p, attrib_list=%p)", dpy, config, pixmap, attrib_list); return MobileGL::MG_Impl::EGLImpl::CreatePixmapSurface(dpy, config, pixmap, attrib_list); } MOBILEGL_EGL_API EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config) { - MGLOG_D("[MobileGL] eglGetConfigs(dpy=%p, configs=%p, config_size=%d, num_config=%p)", dpy, configs, config_size, - num_config); + MGLOG_D("eglGetConfigs(dpy=%p, configs=%p, config_size=%d, num_config=%p)", dpy, configs, config_size, num_config); return MobileGL::MG_Impl::EGLImpl::GetConfigs(dpy, configs, config_size, num_config); } MOBILEGL_EGL_API EGLDisplay eglGetCurrentDisplay(void) { - MGLOG_D("[MobileGL] eglGetCurrentDisplay()"); + MGLOG_D("eglGetCurrentDisplay()"); return MobileGL::MG_Impl::EGLImpl::GetCurrentDisplay(); } MOBILEGL_EGL_API EGLenum eglQueryAPI(void) { - MGLOG_D("[MobileGL] eglQueryAPI()"); + MGLOG_D("eglQueryAPI()"); return MobileGL::MG_Impl::EGLImpl::QueryAPI(); } MOBILEGL_EGL_API EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value) { - MGLOG_D("[MobileGL] eglQueryContext(dpy=%p, ctx=%p, attribute=%d, value=%p)", dpy, ctx, attribute, value); + MGLOG_D("eglQueryContext(dpy=%p, ctx=%p, attribute=%d, value=%p)", dpy, ctx, attribute, value); return MobileGL::MG_Impl::EGLImpl::QueryContext(dpy, ctx, attribute, value); } MOBILEGL_EGL_API EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) { - MGLOG_D("[MobileGL] eglSurfaceAttrib(dpy=%p, surface=%p, attribute=%d, value=%d)", dpy, surface, attribute, value); + MGLOG_D("eglSurfaceAttrib(dpy=%p, surface=%p, attribute=%d, value=%d)", dpy, surface, attribute, value); return MobileGL::MG_Impl::EGLImpl::SurfaceAttrib(dpy, surface, attribute, value); } MOBILEGL_EGL_API EGLBoolean eglWaitClient(void) { - MGLOG_D("[MobileGL] eglWaitClient()"); + MGLOG_D("eglWaitClient()"); return MobileGL::MG_Impl::EGLImpl::WaitClient(); } MOBILEGL_EGL_API EGLBoolean eglWaitGL(void) { - MGLOG_D("[MobileGL] eglWaitGL()"); + MGLOG_D("eglWaitGL()"); return MobileGL::MG_Impl::EGLImpl::WaitGL(); } MOBILEGL_EGL_API EGLBoolean eglWaitNative(EGLint engine) { - MGLOG_D("[MobileGL] eglWaitNative(engine=%d)", engine); + MGLOG_D("eglWaitNative(engine=%d)", engine); return MobileGL::MG_Impl::EGLImpl::WaitNative(engine); } MOBILEGL_EGL_API EGLSync eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib* attrib_list) { - MGLOG_D("[MobileGL] eglCreateSync(dpy=%p, type=%u, attrib_list=%p)", dpy, type, attrib_list); + MGLOG_D("eglCreateSync(dpy=%p, type=%u, attrib_list=%p)", dpy, type, attrib_list); return MobileGL::MG_Impl::EGLImpl::CreateSync(dpy, type, attrib_list); } MOBILEGL_EGL_API EGLBoolean eglDestroySync(EGLDisplay dpy, EGLSync sync) { - MGLOG_D("[MobileGL] eglDestroySync(dpy=%p, sync=%p)", dpy, sync); + MGLOG_D("eglDestroySync(dpy=%p, sync=%p)", dpy, sync); return MobileGL::MG_Impl::EGLImpl::DestroySync(dpy, sync); } MOBILEGL_EGL_API EGLint eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) { - MGLOG_D("[MobileGL] eglClientWaitSync(dpy=%p, sync=%p, flags=%d, timeout=%llu)", dpy, sync, flags, + MGLOG_D("eglClientWaitSync(dpy=%p, sync=%p, flags=%d, timeout=%llu)", dpy, sync, flags, static_cast(timeout)); return MobileGL::MG_Impl::EGLImpl::ClientWaitSync(dpy, sync, flags, timeout); } MOBILEGL_EGL_API EGLBoolean eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib* value) { - MGLOG_D("[MobileGL] eglGetSyncAttrib(dpy=%p, sync=%p, attribute=%d, value=%p)", dpy, sync, attribute, value); + MGLOG_D("eglGetSyncAttrib(dpy=%p, sync=%p, attribute=%d, value=%p)", dpy, sync, attribute, value); return MobileGL::MG_Impl::EGLImpl::GetSyncAttrib(dpy, sync, attribute, value); } MOBILEGL_EGL_API EGLImage eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib* attrib_list) { - MGLOG_D("[MobileGL] eglCreateImage(dpy=%p, ctx=%p, target=%u, buffer=%p, attrib_list=%p)", dpy, ctx, target, buffer, + MGLOG_D("eglCreateImage(dpy=%p, ctx=%p, target=%u, buffer=%p, attrib_list=%p)", dpy, ctx, target, buffer, attrib_list); return MobileGL::MG_Impl::EGLImpl::CreateImage(dpy, ctx, target, buffer, attrib_list); } MOBILEGL_EGL_API EGLBoolean eglDestroyImage(EGLDisplay dpy, EGLImage image) { - MGLOG_D("[MobileGL] eglDestroyImage(dpy=%p, image=%p)", dpy, image); + MGLOG_D("eglDestroyImage(dpy=%p, image=%p)", dpy, image); return MobileGL::MG_Impl::EGLImpl::DestroyImage(dpy, image); } MOBILEGL_EGL_API EGLDisplay eglGetPlatformDisplay(EGLenum platform, void* native_display, const EGLAttrib* attrib_list) { - MGLOG_D("[MobileGL] eglGetPlatformDisplay(platform=%u, native_display=%p, attrib_list=%p)", platform, - native_display, attrib_list); + MGLOG_D("eglGetPlatformDisplay(platform=%u, native_display=%p, attrib_list=%p)", platform, native_display, + attrib_list); return MobileGL::MG_Impl::EGLImpl::GetPlatformDisplay(platform, native_display, attrib_list); } MOBILEGL_EGL_API EGLSurface eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void* native_window, const EGLAttrib* attrib_list) { - MGLOG_D("[MobileGL] eglCreatePlatformWindowSurface(dpy=%p, config=%p, native_window=%p, attrib_list=%p)", dpy, - config, native_window, attrib_list); + MGLOG_D("eglCreatePlatformWindowSurface(dpy=%p, config=%p, native_window=%p, attrib_list=%p)", dpy, config, + native_window, attrib_list); return MobileGL::MG_Impl::EGLImpl::CreatePlatformWindowSurface(dpy, config, native_window, attrib_list); } MOBILEGL_EGL_API EGLSurface eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void* native_pixmap, const EGLAttrib* attrib_list) { - MGLOG_D("[MobileGL] eglCreatePlatformPixmapSurface(dpy=%p, config=%p, native_pixmap=%p, attrib_list=%p)", dpy, - config, native_pixmap, attrib_list); + MGLOG_D("eglCreatePlatformPixmapSurface(dpy=%p, config=%p, native_pixmap=%p, attrib_list=%p)", dpy, config, + native_pixmap, attrib_list); return MobileGL::MG_Impl::EGLImpl::CreatePlatformPixmapSurface(dpy, config, native_pixmap, attrib_list); } MOBILEGL_EGL_API EGLBoolean eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) { - MGLOG_D("[MobileGL] eglWaitSync(dpy=%p, sync=%p, flags=%d)", dpy, sync, flags); + MGLOG_D("eglWaitSync(dpy=%p, sync=%p, flags=%d)", dpy, sync, flags); return MobileGL::MG_Impl::EGLImpl::WaitSync(dpy, sync, flags); } From 60f06d1b8d29a2916a9b426cfcec417f413db4fe Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Fri, 20 Feb 2026 15:26:46 +0800 Subject: [PATCH 12/12] [Improvement] (MG_Backend): Separate Initialize and InitCapabilities. --- MobileGL/MG_Backend/BackendObject.h | 2 +- .../DirectGLES/BackendObject_DirectGLES.cpp | 9 +- .../DirectGLES/BackendObject_DirectGLES.h | 2 + MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp | 7 ++ .../MG_Util/BackendLoaders/OpenGL/Loader.cpp | 106 +----------------- .../MG_Util/BackendLoaders/OpenGL/Loader.h | 3 +- 6 files changed, 20 insertions(+), 109 deletions(-) diff --git a/MobileGL/MG_Backend/BackendObject.h b/MobileGL/MG_Backend/BackendObject.h index 6833afe0..727bb67f 100644 --- a/MobileGL/MG_Backend/BackendObject.h +++ b/MobileGL/MG_Backend/BackendObject.h @@ -10,7 +10,6 @@ #include namespace MobileGL { - enum class BackendType { DirectGLES, BackendTypeCount, @@ -91,6 +90,7 @@ namespace MobileGL { virtual ~BackendObject() = default; virtual void Initialize() = 0; + virtual void InitCapabilities() = 0; virtual void InitWindowSurface() = 0; void SetWindowHandle(const WindowHandle& handle); diff --git a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp index 3f45da86..81a63e40 100644 --- a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp @@ -38,8 +38,15 @@ namespace MobileGL::MG_Backend::DirectGLES { DirectGLES::SetEGLFuncsTable(m_EGLFunctions); DirectGLES::SetGLESFuncsTable(m_GLESFunctions); + } - if (!MG_Util::BackendLoader::FillInGLESCapabilities(m_GLESCapabilities, m_GLESFunctions, m_EGLFunctions)) { + void BackendObject_DirectGLES::InitCapabilities() { + if (!m_initialized) { + MGLOG_E("DirectGLES backend not initialized"); + return; + } + + if (!MG_Util::BackendLoader::FillInGLESCapabilities(m_GLESCapabilities, m_GLESFunctions)) { MGLOG_E("Failed to fill in GLES capabilities for DirectGLES backend"); return; } diff --git a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.h b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.h index e539a271..d85b9623 100644 --- a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.h +++ b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.h @@ -15,7 +15,9 @@ namespace MobileGL::MG_Backend::DirectGLES { class BackendObject_DirectGLES : public BackendObject { public: ~BackendObject_DirectGLES() override; + void Initialize() override; + void InitCapabilities() override; void InitWindowSurface() override; const RendererInfo& GetRendererInfo() const override; diff --git a/MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp b/MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp index 973205e7..f5122970 100644 --- a/MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp +++ b/MobileGL/MG_Impl/EGLImpl/EGLImpl.cpp @@ -59,6 +59,13 @@ namespace MobileGL::MG_Impl::EGLImpl { } EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { + MGLOG_D("EGLImpl::CreateWindowSurface called with window=%p", window); + const auto& activeBackendObject = MG_Backend::pActiveBackendObject; + if (!activeBackendObject) { + MGLOG_E("activeBackendObject not initialized!"); + return EGL_FALSE; + } + activeBackendObject->InitCapabilities(); return EGL_TRUE; } diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp index 7c8b7863..dad8a1cd 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp @@ -496,114 +496,11 @@ namespace MobileGL::MG_Util::BackendLoader { return true; } - static EGLDisplay eglDisplay = EGL_NO_DISPLAY; - static EGLSurface eglSurface = EGL_NO_SURFACE; - static EGLContext eglContext = EGL_NO_CONTEXT; - inline void DestroyTempEGLCtx(const MG_External::EGLFunctionsTable& eglFuncs) { - if (eglSurface != EGL_NO_SURFACE) { - eglFuncs.eglDestroySurface(eglDisplay, eglSurface); - eglSurface = EGL_NO_SURFACE; - } - if (eglContext != EGL_NO_CONTEXT) { - eglFuncs.eglDestroyContext(eglDisplay, eglContext); - eglContext = EGL_NO_CONTEXT; - } - if (eglDisplay != EGL_NO_DISPLAY) { - eglFuncs.eglTerminate(eglDisplay); - eglDisplay = EGL_NO_DISPLAY; - } - } - inline Bool InitTmpEGLContext(const MG_External::EGLFunctionsTable& eglFuncs) { - EGLint configAttribs[] = {EGL_RED_SIZE, - 8, - EGL_GREEN_SIZE, - 8, - EGL_BLUE_SIZE, - 8, - EGL_ALPHA_SIZE, - 8, - EGL_SURFACE_TYPE, - EGL_PBUFFER_BIT, - EGL_RENDERABLE_TYPE, - EGL_OPENGL_ES2_BIT, - EGL_NONE}; - - EGLint ctxAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; - - EGLint pbAttribs[] = {EGL_WIDTH, 32, EGL_HEIGHT, 32, EGL_NONE}; - - EGLConfig pbufConfig; - EGLint configsFound = 0; - - eglDisplay = eglFuncs.eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (eglDisplay == EGL_NO_DISPLAY) { - DestroyTempEGLCtx(eglFuncs); - return false; - } - - if (eglFuncs.eglInitialize(eglDisplay, nullptr, nullptr) != EGL_TRUE) { - DestroyTempEGLCtx(eglFuncs); - return false; - } - - if (eglFuncs.eglBindAPI(EGL_OPENGL_ES_API) != EGL_TRUE) { - DestroyTempEGLCtx(eglFuncs); - return false; - } - - if (eglFuncs.eglChooseConfig(eglDisplay, configAttribs, &pbufConfig, 1, &configsFound) != EGL_TRUE) { - DestroyTempEGLCtx(eglFuncs); - return false; - } - - if (configsFound == 0) { - configAttribs[6] = 0; - if (eglFuncs.eglChooseConfig(eglDisplay, configAttribs, &pbufConfig, 1, &configsFound) != EGL_TRUE) { - DestroyTempEGLCtx(eglFuncs); - return false; - } - if (!configsFound) { - DestroyTempEGLCtx(eglFuncs); - return false; - } - } - - eglContext = eglFuncs.eglCreateContext(eglDisplay, pbufConfig, EGL_NO_CONTEXT, ctxAttribs); - if (eglContext == EGL_NO_CONTEXT) { - DestroyTempEGLCtx(eglFuncs); - return false; - } - - eglSurface = eglFuncs.eglCreatePbufferSurface(eglDisplay, pbufConfig, pbAttribs); - if (eglSurface == EGL_NO_SURFACE) { - DestroyTempEGLCtx(eglFuncs); - return false; - } - - if (eglFuncs.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE) { - DestroyTempEGLCtx(eglFuncs); - return false; - } - return true; - } - - Bool FillInGLESCapabilities(MG_External::GLESCapabilities& caps, const MG_External::GLESFunctionsTable& glesFuncs, - const MG_External::EGLFunctionsTable& eglFuncs) { + Bool FillInGLESCapabilities(MG_External::GLESCapabilities& caps, const MG_External::GLESFunctionsTable& glesFuncs) { if (!glesFuncs.glGetString || !glesFuncs.glGetIntegerv) { MGLOG_E("Required GLES functions are not loaded, cannot query capabilities"); return false; } - if (!eglFuncs.eglGetDisplay || !eglFuncs.eglInitialize || !eglFuncs.eglChooseConfig || - !eglFuncs.eglCreateContext || !eglFuncs.eglCreatePbufferSurface || !eglFuncs.eglMakeCurrent) { - MGLOG_E("Required EGL functions are not loaded, cannot create temporary EGL context"); - return false; - } - - Bool eglCtxCreated = InitTmpEGLContext(eglFuncs); - if (!eglCtxCreated) { - MGLOG_E("Failed to create temporary EGL context, cannot query GLES capabilities"); - return false; - } auto* vendorName = glesFuncs.glGetString(GL_VENDOR); MGLOG_I("GL_VENDOR: %s", vendorName); @@ -637,7 +534,6 @@ namespace MobileGL::MG_Util::BackendLoader { glesFuncs.glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &caps.UniformBufferOffsetAlignment); MGLOG_I(" GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: %d", caps.UniformBufferOffsetAlignment); - DestroyTempEGLCtx(eglFuncs); return true; } } // namespace MobileGL::MG_Util::BackendLoader diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h index 8b6441b4..17b0f884 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h @@ -1020,8 +1020,7 @@ namespace MobileGL { MG_External::EGL::eglGetProcAddress_PTR procAddress); Bool AcquireEGLFunctions(MG_External::EGLFunctionsTable& funcs); Bool FillInGLESCapabilities(MG_External::GLESCapabilities& caps, - const MG_External::GLESFunctionsTable& glesFuncs, - const MG_External::EGLFunctionsTable& eglFuncs); + const MG_External::GLESFunctionsTable& glesFuncs); } // namespace MG_Util::BackendLoader } // namespace MobileGL #undef MOBILEGL_EXTERNAL_GLES