18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci
168bf80f4bSopenharmony_ci#ifndef GLES_DEVICE_GLES_H
178bf80f4bSopenharmony_ci#define GLES_DEVICE_GLES_H
188bf80f4bSopenharmony_ci
198bf80f4bSopenharmony_ci#include <cstddef>
208bf80f4bSopenharmony_ci#include <cstdint>
218bf80f4bSopenharmony_ci#include <mutex>
228bf80f4bSopenharmony_ci
238bf80f4bSopenharmony_ci#include <base/containers/string_view.h>
248bf80f4bSopenharmony_ci#include <base/containers/unique_ptr.h>
258bf80f4bSopenharmony_ci#include <base/containers/vector.h>
268bf80f4bSopenharmony_ci#include <base/math/vector.h>
278bf80f4bSopenharmony_ci#include <base/namespace.h>
288bf80f4bSopenharmony_ci#include <render/device/pipeline_state_desc.h>
298bf80f4bSopenharmony_ci#include <render/gles/intf_device_gles.h>
308bf80f4bSopenharmony_ci#include <render/namespace.h>
318bf80f4bSopenharmony_ci#include <render/resource_handle.h>
328bf80f4bSopenharmony_ci
338bf80f4bSopenharmony_ci#include "device/device.h"
348bf80f4bSopenharmony_ci#include "gles/swapchain_gles.h"
358bf80f4bSopenharmony_ci
368bf80f4bSopenharmony_ci#if RENDER_HAS_GLES_BACKEND
378bf80f4bSopenharmony_ci#include "egl_state.h"
388bf80f4bSopenharmony_ci#endif
398bf80f4bSopenharmony_ci#if RENDER_HAS_GL_BACKEND
408bf80f4bSopenharmony_ci#include "wgl_state.h"
418bf80f4bSopenharmony_ci#endif
428bf80f4bSopenharmony_ci
438bf80f4bSopenharmony_ciRENDER_BEGIN_NAMESPACE()
448bf80f4bSopenharmony_ciclass ComputePipelineStateObject;
458bf80f4bSopenharmony_ciclass GpuBuffer;
468bf80f4bSopenharmony_ciclass GpuComputeProgram;
478bf80f4bSopenharmony_ciclass GpuImage;
488bf80f4bSopenharmony_ciclass GpuResourceManager;
498bf80f4bSopenharmony_ciclass GpuSemaphore;
508bf80f4bSopenharmony_ciclass GpuSampler;
518bf80f4bSopenharmony_ciclass GpuShaderProgram;
528bf80f4bSopenharmony_ciclass GraphicsPipelineStateObject;
538bf80f4bSopenharmony_ciclass LowLevelDeviceGLES;
548bf80f4bSopenharmony_ciclass NodeContextDescriptorSetManager;
558bf80f4bSopenharmony_ciclass NodeContextPoolManager;
568bf80f4bSopenharmony_ciclass RenderBackend;
578bf80f4bSopenharmony_ciclass RenderFrameSync;
588bf80f4bSopenharmony_ciclass PlatformGpuMemoryAllocator;
598bf80f4bSopenharmony_ciclass ShaderManager;
608bf80f4bSopenharmony_ciclass Swapchain;
618bf80f4bSopenharmony_ciclass SwapchainGLES;
628bf80f4bSopenharmony_ci
638bf80f4bSopenharmony_cistruct BackendSpecificImageDesc;
648bf80f4bSopenharmony_cistruct GpuAccelerationStructureDesc;
658bf80f4bSopenharmony_cistruct GpuBufferDesc;
668bf80f4bSopenharmony_cistruct GpuComputeProgramCreateData;
678bf80f4bSopenharmony_cistruct GpuImageDesc;
688bf80f4bSopenharmony_cistruct GpuImagePlatformData;
698bf80f4bSopenharmony_cistruct GpuSamplerDesc;
708bf80f4bSopenharmony_cistruct GpuShaderProgramCreateData;
718bf80f4bSopenharmony_cistruct SwapchainCreateInfo;
728bf80f4bSopenharmony_cistruct PipelineLayout;
738bf80f4bSopenharmony_ci
748bf80f4bSopenharmony_ciclass DeviceGLES final : public Device {
758bf80f4bSopenharmony_cipublic:
768bf80f4bSopenharmony_ci    // NOTE: normalized flag
778bf80f4bSopenharmony_ci    struct ImageFormat {
788bf80f4bSopenharmony_ci        BASE_NS::Format coreFormat;
798bf80f4bSopenharmony_ci        uint32_t format;
808bf80f4bSopenharmony_ci        uint32_t internalFormat;
818bf80f4bSopenharmony_ci        uint32_t dataType;
828bf80f4bSopenharmony_ci        uint32_t bytesperpixel;
838bf80f4bSopenharmony_ci        struct {
848bf80f4bSopenharmony_ci            bool compressed;
858bf80f4bSopenharmony_ci            uint8_t blockW;
868bf80f4bSopenharmony_ci            uint8_t blockH;
878bf80f4bSopenharmony_ci            uint32_t bytesperblock;
888bf80f4bSopenharmony_ci        } compression;
898bf80f4bSopenharmony_ci        BASE_NS::Math::UVec4 swizzle;
908bf80f4bSopenharmony_ci    };
918bf80f4bSopenharmony_ci
928bf80f4bSopenharmony_ci    DeviceGLES(RenderContext& renderContext, DeviceCreateInfo const& createInfo);
938bf80f4bSopenharmony_ci    ~DeviceGLES() override;
948bf80f4bSopenharmony_ci
958bf80f4bSopenharmony_ci    // From IDevice
968bf80f4bSopenharmony_ci    DeviceBackendType GetBackendType() const override;
978bf80f4bSopenharmony_ci    const DevicePlatformData& GetPlatformData() const override;
988bf80f4bSopenharmony_ci    AccelerationStructureBuildSizes GetAccelerationStructureBuildSizes(
998bf80f4bSopenharmony_ci        const AccelerationStructureBuildGeometryInfo& geometry,
1008bf80f4bSopenharmony_ci        BASE_NS::array_view<const AccelerationStructureGeometryTrianglesInfo> triangles,
1018bf80f4bSopenharmony_ci        BASE_NS::array_view<const AccelerationStructureGeometryAabbsInfo> aabbs,
1028bf80f4bSopenharmony_ci        BASE_NS::array_view<const AccelerationStructureGeometryInstancesInfo> instances) const override;
1038bf80f4bSopenharmony_ci    FormatProperties GetFormatProperties(BASE_NS::Format format) const override;
1048bf80f4bSopenharmony_ci    ILowLevelDevice& GetLowLevelDevice() const override;
1058bf80f4bSopenharmony_ci    // NOTE: can be called from API
1068bf80f4bSopenharmony_ci    void WaitForIdle() override;
1078bf80f4bSopenharmony_ci
1088bf80f4bSopenharmony_ci    PlatformGpuMemoryAllocator* GetPlatformGpuMemoryAllocator() override;
1098bf80f4bSopenharmony_ci
1108bf80f4bSopenharmony_ci    // (re-)create swapchain
1118bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<Swapchain> CreateDeviceSwapchain(const SwapchainCreateInfo& swapchainCreateInfo) override;
1128bf80f4bSopenharmony_ci    void DestroyDeviceSwapchain() override;
1138bf80f4bSopenharmony_ci
1148bf80f4bSopenharmony_ci    bool IsActive() const;
1158bf80f4bSopenharmony_ci    void Activate() override;
1168bf80f4bSopenharmony_ci    void Deactivate() override;
1178bf80f4bSopenharmony_ci
1188bf80f4bSopenharmony_ci    bool AllowThreadedProcessing() const override;
1198bf80f4bSopenharmony_ci
1208bf80f4bSopenharmony_ci    GpuQueue GetValidGpuQueue(const GpuQueue& gpuQueue) const override;
1218bf80f4bSopenharmony_ci    uint32_t GetGpuQueueCount() const override;
1228bf80f4bSopenharmony_ci
1238bf80f4bSopenharmony_ci    void InitializePipelineCache(BASE_NS::array_view<const uint8_t> initialData) override;
1248bf80f4bSopenharmony_ci    BASE_NS::vector<uint8_t> GetPipelineCache() const override;
1258bf80f4bSopenharmony_ci
1268bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<GpuBuffer> CreateGpuBuffer(const GpuBufferDesc& desc) override;
1278bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<GpuBuffer> CreateGpuBuffer(const GpuAccelerationStructureDesc& desc) override;
1288bf80f4bSopenharmony_ci
1298bf80f4bSopenharmony_ci    // Create gpu image resources
1308bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<GpuImage> CreateGpuImage(const GpuImageDesc& desc) override;
1318bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<GpuImage> CreateGpuImageView(
1328bf80f4bSopenharmony_ci        const GpuImageDesc& desc, const GpuImagePlatformData& platformData) override;
1338bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<GpuImage> CreateGpuImageView(
1348bf80f4bSopenharmony_ci        const GpuImageDesc& desc, const BackendSpecificImageDesc& platformData) override;
1358bf80f4bSopenharmony_ci    BASE_NS::vector<BASE_NS::unique_ptr<GpuImage>> CreateGpuImageViews(const Swapchain& platformSwapchain) override;
1368bf80f4bSopenharmony_ci
1378bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<GpuSampler> CreateGpuSampler(const GpuSamplerDesc& desc) override;
1388bf80f4bSopenharmony_ci
1398bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<RenderFrameSync> CreateRenderFrameSync() override;
1408bf80f4bSopenharmony_ci
1418bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<RenderBackend> CreateRenderBackend(
1428bf80f4bSopenharmony_ci        GpuResourceManager& gpuResourceMgr, const CORE_NS::IParallelTaskQueue::Ptr& queue) override;
1438bf80f4bSopenharmony_ci
1448bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<ShaderModule> CreateShaderModule(const ShaderModuleCreateInfo& data) override;
1458bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<ShaderModule> CreateComputeShaderModule(const ShaderModuleCreateInfo& data) override;
1468bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<GpuShaderProgram> CreateGpuShaderProgram(const GpuShaderProgramCreateData& data) override;
1478bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<GpuComputeProgram> CreateGpuComputeProgram(const GpuComputeProgramCreateData& data) override;
1488bf80f4bSopenharmony_ci
1498bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<NodeContextDescriptorSetManager> CreateNodeContextDescriptorSetManager() override;
1508bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<NodeContextPoolManager> CreateNodeContextPoolManager(
1518bf80f4bSopenharmony_ci        class GpuResourceManager& gpuResourceMgr, const GpuQueue& gpuQueue) override;
1528bf80f4bSopenharmony_ci
1538bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<GraphicsPipelineStateObject> CreateGraphicsPipelineStateObject(
1548bf80f4bSopenharmony_ci        const GpuShaderProgram& gpuProgram, const GraphicsState& graphicsState, const PipelineLayout& pipelineLayout,
1558bf80f4bSopenharmony_ci        const VertexInputDeclarationView& vertexInputDeclaration,
1568bf80f4bSopenharmony_ci        const ShaderSpecializationConstantDataView& specializationConstants,
1578bf80f4bSopenharmony_ci        const BASE_NS::array_view<const DynamicStateEnum> dynamicStates, const RenderPassDesc& renderPassDesc,
1588bf80f4bSopenharmony_ci        const BASE_NS::array_view<const RenderPassSubpassDesc>& renderPassSubpassDescs, const uint32_t subpassIndex,
1598bf80f4bSopenharmony_ci        const LowLevelRenderPassData* renderPassData, const LowLevelPipelineLayoutData* pipelineLayoutData) override;
1608bf80f4bSopenharmony_ci
1618bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<ComputePipelineStateObject> CreateComputePipelineStateObject(
1628bf80f4bSopenharmony_ci        const GpuComputeProgram& gpuProgram, const PipelineLayout& pipelineLayout,
1638bf80f4bSopenharmony_ci        const ShaderSpecializationConstantDataView& specializationConstants,
1648bf80f4bSopenharmony_ci        const LowLevelPipelineLayoutData* pipelineLayoutData) override;
1658bf80f4bSopenharmony_ci
1668bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<GpuSemaphore> CreateGpuSemaphore() override;
1678bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<GpuSemaphore> CreateGpuSemaphoreView(const uint64_t handle) override;
1688bf80f4bSopenharmony_ci
1698bf80f4bSopenharmony_ci    void SetBackendConfig(const BackendConfig& config) override;
1708bf80f4bSopenharmony_ci
1718bf80f4bSopenharmony_ci    // Internal apis, only usable by other parts of GLES backend.
1728bf80f4bSopenharmony_ci    bool HasExtension(BASE_NS::string_view extension) const;
1738bf80f4bSopenharmony_ci    void Activate(RenderHandle swapchain);
1748bf80f4bSopenharmony_ci#if RENDER_HAS_GL_BACKEND
1758bf80f4bSopenharmony_ci    const WGLHelpers::WGLState& GetEglState();
1768bf80f4bSopenharmony_ci#endif
1778bf80f4bSopenharmony_ci#if RENDER_HAS_GLES_BACKEND
1788bf80f4bSopenharmony_ci    const EGLHelpers::EGLState& GetEglState();
1798bf80f4bSopenharmony_ci    bool IsDepthResolveSupported() const;
1808bf80f4bSopenharmony_ci#endif
1818bf80f4bSopenharmony_ci
1828bf80f4bSopenharmony_ci    uint32_t CacheProgram(
1838bf80f4bSopenharmony_ci        BASE_NS::string_view vertSource, BASE_NS::string_view fragSource, BASE_NS::string_view compSource);
1848bf80f4bSopenharmony_ci    void ReleaseProgram(uint32_t program);
1858bf80f4bSopenharmony_ci
1868bf80f4bSopenharmony_ci    void UseProgram(uint32_t program);
1878bf80f4bSopenharmony_ci    void BindBuffer(uint32_t target, uint32_t buffer);
1888bf80f4bSopenharmony_ci    void BindBufferRange(uint32_t target, uint32_t binding, uint32_t buffer, uint64_t offset, uint64_t size);
1898bf80f4bSopenharmony_ci    void BindSampler(uint32_t textureUnit, uint32_t sampler);
1908bf80f4bSopenharmony_ci    void BindTexture(uint32_t textureUnit, uint32_t target, uint32_t texture); // target = GL_TEXTURE_2D et al.
1918bf80f4bSopenharmony_ci    void BindImageTexture(uint32_t unit, uint32_t texture, uint32_t level, bool layered, uint32_t layer,
1928bf80f4bSopenharmony_ci        uint32_t access, uint32_t format);
1938bf80f4bSopenharmony_ci    void BindFrameBuffer(uint32_t fbo);
1948bf80f4bSopenharmony_ci    void BindReadFrameBuffer(uint32_t fbo);
1958bf80f4bSopenharmony_ci    void BindWriteFrameBuffer(uint32_t fbo);
1968bf80f4bSopenharmony_ci    void BindVertexArray(uint32_t vao);
1978bf80f4bSopenharmony_ci
1988bf80f4bSopenharmony_ci    void BindVertexBuffer(uint32_t slot, uint32_t buffer, intptr_t offset, intptr_t stride);
1998bf80f4bSopenharmony_ci    void VertexBindingDivisor(uint32_t slot, uint32_t divisor);
2008bf80f4bSopenharmony_ci    void BindElementBuffer(uint32_t buffer);
2018bf80f4bSopenharmony_ci
2028bf80f4bSopenharmony_ci    uint32_t BoundReadFrameBuffer() const;
2038bf80f4bSopenharmony_ci    uint32_t BoundWriteFrameBuffer() const;
2048bf80f4bSopenharmony_ci
2058bf80f4bSopenharmony_ci    uint32_t BoundProgram() const;
2068bf80f4bSopenharmony_ci    uint32_t BoundBuffer(uint32_t target) const;
2078bf80f4bSopenharmony_ci    uint32_t BoundBuffer(uint32_t target, uint32_t binding) const;
2088bf80f4bSopenharmony_ci    uint32_t BoundSampler(uint32_t textureUnit) const;
2098bf80f4bSopenharmony_ci    uint32_t BoundTexture(uint32_t textureUnit, uint32_t target) const;
2108bf80f4bSopenharmony_ci    uint32_t BoundVertexArray() const;
2118bf80f4bSopenharmony_ci
2128bf80f4bSopenharmony_ci    // Creation functions for objects.
2138bf80f4bSopenharmony_ci    uint32_t CreateVertexArray();
2148bf80f4bSopenharmony_ci    // Deletion functions for objects.
2158bf80f4bSopenharmony_ci    void DeleteTexture(uint32_t texture);
2168bf80f4bSopenharmony_ci    void DeleteBuffer(uint32_t buffer);
2178bf80f4bSopenharmony_ci    void DeleteSampler(uint32_t sampler);
2188bf80f4bSopenharmony_ci    void DeleteVertexArray(uint32_t vao);
2198bf80f4bSopenharmony_ci    void DeleteFrameBuffer(uint32_t fbo);
2208bf80f4bSopenharmony_ci
2218bf80f4bSopenharmony_ci    void SetActiveTextureUnit(uint32_t textureUnit); // hide this.
2228bf80f4bSopenharmony_ci    // swizzles for textures
2238bf80f4bSopenharmony_ci    void TexSwizzle(uint32_t image, uint32_t target, const BASE_NS::Math::UVec4& swizzle);
2248bf80f4bSopenharmony_ci    // texture upload / storage
2258bf80f4bSopenharmony_ci    void TexStorage2D(
2268bf80f4bSopenharmony_ci        uint32_t image, uint32_t target, uint32_t levels, uint32_t internalformat, const BASE_NS::Math::UVec2& extent);
2278bf80f4bSopenharmony_ci    void TexStorage3D(
2288bf80f4bSopenharmony_ci        uint32_t image, uint32_t target, uint32_t levels, uint32_t internalformat, const BASE_NS::Math::UVec3& extent);
2298bf80f4bSopenharmony_ci    void TexStorage2DMultisample(uint32_t image, uint32_t target, uint32_t samples, uint32_t internalformat,
2308bf80f4bSopenharmony_ci        const BASE_NS::Math::UVec2& extent, bool fixedsamplelocations);
2318bf80f4bSopenharmony_ci
2328bf80f4bSopenharmony_ci    void TexSubImage2D(uint32_t image, uint32_t target, uint32_t level, const BASE_NS::Math::UVec2& offset,
2338bf80f4bSopenharmony_ci        const BASE_NS::Math::UVec2& extent, uint32_t format, uint32_t type, const void* pixels);
2348bf80f4bSopenharmony_ci    void TexSubImage3D(uint32_t image, uint32_t target, uint32_t level, const BASE_NS::Math::UVec3& offset,
2358bf80f4bSopenharmony_ci        const BASE_NS::Math::UVec3& extent, uint32_t format, uint32_t type, const void* pixels);
2368bf80f4bSopenharmony_ci    void CompressedTexSubImage2D(uint32_t image, uint32_t target, uint32_t level, const BASE_NS::Math::UVec2& offset,
2378bf80f4bSopenharmony_ci        const BASE_NS::Math::UVec2& extent, uint32_t format, uint32_t imageSize, const void* data);
2388bf80f4bSopenharmony_ci    void CompressedTexSubImage3D(uint32_t image, uint32_t target, uint32_t level, const BASE_NS::Math::UVec3& offset,
2398bf80f4bSopenharmony_ci        const BASE_NS::Math::UVec3& extent, uint32_t format, uint32_t imageSize, const void* data);
2408bf80f4bSopenharmony_ci
2418bf80f4bSopenharmony_ci    const ImageFormat& GetGlImageFormat(BASE_NS::Format format) const;
2428bf80f4bSopenharmony_ci
2438bf80f4bSopenharmony_ci    void SwapBuffers(const SwapchainGLES&);
2448bf80f4bSopenharmony_ci
2458bf80f4bSopenharmony_ciprivate:
2468bf80f4bSopenharmony_ci    enum BufferBindId : uint32_t {
2478bf80f4bSopenharmony_ci        UNIFORM_BUFFER_BIND = 0,
2488bf80f4bSopenharmony_ci        SHADER_STORAGE_BUFFER_BIND,
2498bf80f4bSopenharmony_ci#ifdef HANDLE_UNSUPPORTED_ENUMS
2508bf80f4bSopenharmony_ci        ATOMIC_COUNTER_BUFFER_BIND,
2518bf80f4bSopenharmony_ci        TRANSFORM_FEEDBACK_BUFFER_BIND,
2528bf80f4bSopenharmony_ci#endif
2538bf80f4bSopenharmony_ci        MAX_BUFFER_BIND_ID
2548bf80f4bSopenharmony_ci    };
2558bf80f4bSopenharmony_ci
2568bf80f4bSopenharmony_ci    enum BufferTargetId : uint32_t {
2578bf80f4bSopenharmony_ci        PIXEL_UNPACK_BUFFER = 0,
2588bf80f4bSopenharmony_ci        PIXEL_PACK_BUFFER,
2598bf80f4bSopenharmony_ci        COPY_READ_BUFFER,
2608bf80f4bSopenharmony_ci        COPY_WRITE_BUFFER,
2618bf80f4bSopenharmony_ci        UNIFORM_BUFFER,
2628bf80f4bSopenharmony_ci        SHADER_STORAGE_BUFFER,
2638bf80f4bSopenharmony_ci        DISPATCH_INDIRECT_BUFFER,
2648bf80f4bSopenharmony_ci        DRAW_INDIRECT_BUFFER,
2658bf80f4bSopenharmony_ci#ifdef HANDLE_UNSUPPORTED_ENUMS
2668bf80f4bSopenharmony_ci        ATOMIC_COUNTER_BUFFER,
2678bf80f4bSopenharmony_ci        QUERY_BUFFER,
2688bf80f4bSopenharmony_ci        TRANSFORM_FEEDBACK_BUFFER,
2698bf80f4bSopenharmony_ci        ARRAY_BUFFER,
2708bf80f4bSopenharmony_ci        ELEMENT_ARRAY_BUFFER, // stored in VAO state...
2718bf80f4bSopenharmony_ci        TEXTURE_BUFFER,
2728bf80f4bSopenharmony_ci#endif
2738bf80f4bSopenharmony_ci        MAX_BUFFER_TARGET_ID
2748bf80f4bSopenharmony_ci    };
2758bf80f4bSopenharmony_ci
2768bf80f4bSopenharmony_ci    enum TextureTargetId : uint32_t {
2778bf80f4bSopenharmony_ci        TEXTURE_2D = 0,
2788bf80f4bSopenharmony_ci        TEXTURE_CUBE_MAP = 1,
2798bf80f4bSopenharmony_ci#if RENDER_HAS_GLES_BACKEND
2808bf80f4bSopenharmony_ci        TEXTURE_EXTERNAL_OES = 2,
2818bf80f4bSopenharmony_ci#endif
2828bf80f4bSopenharmony_ci        TEXTURE_2D_MULTISAMPLE = 3,
2838bf80f4bSopenharmony_ci        TEXTURE_2D_ARRAY = 4,
2848bf80f4bSopenharmony_ci        TEXTURE_3D = 5,
2858bf80f4bSopenharmony_ci        MAX_TEXTURE_TARGET_ID
2868bf80f4bSopenharmony_ci    };
2878bf80f4bSopenharmony_ci
2888bf80f4bSopenharmony_ci    static constexpr uint32_t READ_ONLY { 0x88B8 }; /* GL_READ_ONLY */
2898bf80f4bSopenharmony_ci    static constexpr uint32_t R32UI { 0x8236 };     /* GL_R32UI */
2908bf80f4bSopenharmony_ci    static constexpr uint32_t MAX_TEXTURE_UNITS { 16 };
2918bf80f4bSopenharmony_ci    static constexpr uint32_t MAX_SAMPLERS { 16 };
2928bf80f4bSopenharmony_ci    static constexpr uint32_t MAX_BOUND_IMAGE { 16 };
2938bf80f4bSopenharmony_ci    static constexpr uint32_t MAX_BINDING_VALUE { 16 };
2948bf80f4bSopenharmony_ci
2958bf80f4bSopenharmony_ci    // Cleanup cache state when deleting objects.
2968bf80f4bSopenharmony_ci    void UnBindTexture(uint32_t texture);
2978bf80f4bSopenharmony_ci    void UnBindBuffer(uint32_t buffer);
2988bf80f4bSopenharmony_ci    void UnBindBufferFromVertexArray(uint32_t buffer);
2998bf80f4bSopenharmony_ci    void UnBindSampler(uint32_t sampler);
3008bf80f4bSopenharmony_ci    void UnBindVertexArray(uint32_t vao);
3018bf80f4bSopenharmony_ci    void UnBindFrameBuffer(uint32_t fbo);
3028bf80f4bSopenharmony_ci
3038bf80f4bSopenharmony_ci    BASE_NS::vector<BASE_NS::string_view> extensions_;
3048bf80f4bSopenharmony_ci    BASE_NS::vector<ImageFormat> supportedFormats_;
3058bf80f4bSopenharmony_ci
3068bf80f4bSopenharmony_ci    enum { VERTEX_CACHE = 0, FRAGMENT_CACHE = 1, COMPUTE_CACHE = 2, MAX_CACHES };
3078bf80f4bSopenharmony_ci    struct ShaderCache {
3088bf80f4bSopenharmony_ci        size_t hit { 0 };
3098bf80f4bSopenharmony_ci        size_t miss { 0 };
3108bf80f4bSopenharmony_ci        struct Entry {
3118bf80f4bSopenharmony_ci            uint32_t shader { 0 };
3128bf80f4bSopenharmony_ci            uint64_t hash { 0 }; // hash of generated GLSL
3138bf80f4bSopenharmony_ci            uint32_t refCount { 0 };
3148bf80f4bSopenharmony_ci        };
3158bf80f4bSopenharmony_ci        BASE_NS::vector<Entry> cache;
3168bf80f4bSopenharmony_ci    };
3178bf80f4bSopenharmony_ci    ShaderCache caches[MAX_CACHES];
3188bf80f4bSopenharmony_ci
3198bf80f4bSopenharmony_ci    const ShaderCache::Entry& CacheShader(int type, BASE_NS::string_view source);
3208bf80f4bSopenharmony_ci    void ReleaseShader(uint32_t type, uint32_t shader);
3218bf80f4bSopenharmony_ci
3228bf80f4bSopenharmony_ci    struct ProgramCache {
3238bf80f4bSopenharmony_ci        uint32_t program { 0 };
3248bf80f4bSopenharmony_ci        uint32_t vertShader { 0 };
3258bf80f4bSopenharmony_ci        uint32_t fragShader { 0 };
3268bf80f4bSopenharmony_ci        uint32_t compShader { 0 };
3278bf80f4bSopenharmony_ci        uint64_t hashVert { 0 };
3288bf80f4bSopenharmony_ci        uint64_t hashFrag { 0 };
3298bf80f4bSopenharmony_ci        uint64_t hashComp { 0 };
3308bf80f4bSopenharmony_ci        uint32_t refCount { 0 };
3318bf80f4bSopenharmony_ci    };
3328bf80f4bSopenharmony_ci    BASE_NS::vector<ProgramCache> programs_;
3338bf80f4bSopenharmony_ci    size_t pCacheHit_ { 0 };
3348bf80f4bSopenharmony_ci    size_t pCacheMiss_ { 0 };
3358bf80f4bSopenharmony_ci
3368bf80f4bSopenharmony_ci#if RENDER_HAS_GL_BACKEND
3378bf80f4bSopenharmony_ci#if _WIN32
3388bf80f4bSopenharmony_ci    const DeviceBackendType backendType_ = DeviceBackendType::OPENGL;
3398bf80f4bSopenharmony_ci    WGLHelpers::WGLState eglState_;
3408bf80f4bSopenharmony_ci#else
3418bf80f4bSopenharmony_ci#error Core::DeviceBackendType::OPENGL not implemented for this platform yet.
3428bf80f4bSopenharmony_ci#endif
3438bf80f4bSopenharmony_ci#endif
3448bf80f4bSopenharmony_ci#if RENDER_HAS_GLES_BACKEND
3458bf80f4bSopenharmony_ci    const DeviceBackendType backendType_ = DeviceBackendType::OPENGLES;
3468bf80f4bSopenharmony_ci    EGLHelpers::EGLState eglState_;
3478bf80f4bSopenharmony_ci    BackendConfigGLES backendConfig_ { {}, false };
3488bf80f4bSopenharmony_ci#endif
3498bf80f4bSopenharmony_ci    mutable std::mutex activeMutex_;
3508bf80f4bSopenharmony_ci    uint32_t isActive_ { 0 };
3518bf80f4bSopenharmony_ci    bool isRenderbackendRunning_ { false };
3528bf80f4bSopenharmony_ci    BASE_NS::unique_ptr<LowLevelDeviceGLES> lowLevelDevice_;
3538bf80f4bSopenharmony_ci    // GL State cache..
3548bf80f4bSopenharmony_ci    // cache.
3558bf80f4bSopenharmony_ci    uint32_t activeTextureUnit_ = { 0 };
3568bf80f4bSopenharmony_ci    uint32_t boundSampler_[MAX_SAMPLERS] = { 0 };
3578bf80f4bSopenharmony_ci
3588bf80f4bSopenharmony_ci    struct {
3598bf80f4bSopenharmony_ci        bool bound { false };
3608bf80f4bSopenharmony_ci        uint32_t texture { 0 };
3618bf80f4bSopenharmony_ci        uint32_t level { 0 };
3628bf80f4bSopenharmony_ci        bool layered { false };
3638bf80f4bSopenharmony_ci        uint32_t layer { 0 };
3648bf80f4bSopenharmony_ci        uint32_t access { READ_ONLY };
3658bf80f4bSopenharmony_ci        uint32_t format { R32UI };
3668bf80f4bSopenharmony_ci    } boundImage_[MAX_BOUND_IMAGE] = { {} };
3678bf80f4bSopenharmony_ci
3688bf80f4bSopenharmony_ci    uint32_t boundTexture_[MAX_TEXTURE_UNITS][MAX_TEXTURE_TARGET_ID] = { { 0 } }; // [textureunit][target type]
3698bf80f4bSopenharmony_ci
3708bf80f4bSopenharmony_ci    struct BufferCache {
3718bf80f4bSopenharmony_ci        bool cached { false };
3728bf80f4bSopenharmony_ci        uint32_t buffer { 0 };
3738bf80f4bSopenharmony_ci        uint64_t offset { 0 };
3748bf80f4bSopenharmony_ci        uint64_t size { 0 };
3758bf80f4bSopenharmony_ci    };
3768bf80f4bSopenharmony_ci    // Cache for GL_ATOMIC_COUNTER_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER, GL_UNIFORM_BUFFER, or GL_SHADER_STORAGE_BUFFER
3778bf80f4bSopenharmony_ci    // bindings.
3788bf80f4bSopenharmony_ci    BufferCache boundBuffers_[MAX_BUFFER_BIND_ID][MAX_BINDING_VALUE] = { {} };
3798bf80f4bSopenharmony_ci
3808bf80f4bSopenharmony_ci    // bufferBound_ caches GL_PIXEL_UNPACK_BUFFER / GL_COPY_READ_BUFFER / GL_COPY_WRITE_BUFFER (and other generic
3818bf80f4bSopenharmony_ci    // bindings)
3828bf80f4bSopenharmony_ci    struct {
3838bf80f4bSopenharmony_ci        bool bound { false };
3848bf80f4bSopenharmony_ci        uint32_t buffer { 0 };
3858bf80f4bSopenharmony_ci    } bufferBound_[MAX_BUFFER_TARGET_ID];
3868bf80f4bSopenharmony_ci    uint32_t boundReadFbo_ { 0 };
3878bf80f4bSopenharmony_ci    uint32_t boundWriteFbo_ { 0 };
3888bf80f4bSopenharmony_ci    uint32_t boundVao_ { 0 };
3898bf80f4bSopenharmony_ci    uint32_t boundProgram_ { 0 };
3908bf80f4bSopenharmony_ci    struct VAOState {
3918bf80f4bSopenharmony_ci        uint32_t vao { 0 }; // GL name for object.
3928bf80f4bSopenharmony_ci        struct {
3938bf80f4bSopenharmony_ci            bool bound { false };
3948bf80f4bSopenharmony_ci            uint32_t buffer { 0 };
3958bf80f4bSopenharmony_ci        } elementBuffer;
3968bf80f4bSopenharmony_ci        struct {
3978bf80f4bSopenharmony_ci            bool bound { false };
3988bf80f4bSopenharmony_ci            uint32_t buffer { 0 };
3998bf80f4bSopenharmony_ci            intptr_t offset { 0 };
4008bf80f4bSopenharmony_ci            intptr_t stride { 0 };
4018bf80f4bSopenharmony_ci            uint32_t divisor { 0 };
4028bf80f4bSopenharmony_ci        } vertexBufferBinds[PipelineStateConstants::MAX_VERTEX_BUFFER_COUNT];
4038bf80f4bSopenharmony_ci    };
4048bf80f4bSopenharmony_ci    BASE_NS::vector<VAOState> vaoStates_;
4058bf80f4bSopenharmony_ci    size_t vaoStatesInUse_ = 0;
4068bf80f4bSopenharmony_ci
4078bf80f4bSopenharmony_ci    // glid -> internal id
4088bf80f4bSopenharmony_ci    static BufferBindId IndexedTargetToTargetId(uint32_t target);
4098bf80f4bSopenharmony_ci    static uint32_t TargetToBinding(uint32_t target);
4108bf80f4bSopenharmony_ci    static BufferTargetId GenericTargetToTargetId(uint32_t target);
4118bf80f4bSopenharmony_ci    static TextureTargetId TextureTargetToTargetId(uint32_t target);
4128bf80f4bSopenharmony_ci
4138bf80f4bSopenharmony_ci    // internal id -> glid
4148bf80f4bSopenharmony_ci    static uint32_t GenericTargetIdToTarget(BufferTargetId target);
4158bf80f4bSopenharmony_ci    static uint32_t IndexedTargetIdToTarget(BufferBindId target);
4168bf80f4bSopenharmony_ci    static uint32_t TextureTargetIdToTarget(TextureTargetId target);
4178bf80f4bSopenharmony_ci};
4188bf80f4bSopenharmony_ci
4198bf80f4bSopenharmony_ci// Wrapper for low level device access
4208bf80f4bSopenharmony_ciclass LowLevelDeviceGLES final : public ILowLevelDeviceGLES {
4218bf80f4bSopenharmony_cipublic:
4228bf80f4bSopenharmony_ci    explicit LowLevelDeviceGLES(DeviceGLES& deviceGLES);
4238bf80f4bSopenharmony_ci    ~LowLevelDeviceGLES() = default;
4248bf80f4bSopenharmony_ci
4258bf80f4bSopenharmony_ci    DeviceBackendType GetBackendType() const override;
4268bf80f4bSopenharmony_ci
4278bf80f4bSopenharmony_ci#if RENDER_HAS_EXPERIMENTAL
4288bf80f4bSopenharmony_ci    void Activate() override;
4298bf80f4bSopenharmony_ci    void Deactivate() override;
4308bf80f4bSopenharmony_ci    void SwapBuffers() override;
4318bf80f4bSopenharmony_ci#endif
4328bf80f4bSopenharmony_ci
4338bf80f4bSopenharmony_ciprivate:
4348bf80f4bSopenharmony_ci    DeviceGLES& deviceGLES_;
4358bf80f4bSopenharmony_ci    GpuResourceManager& gpuResourceMgr_;
4368bf80f4bSopenharmony_ci};
4378bf80f4bSopenharmony_ci
4388bf80f4bSopenharmony_ci#if (RENDER_HAS_GL_BACKEND)
4398bf80f4bSopenharmony_ciBASE_NS::unique_ptr<Device> CreateDeviceGL(RenderContext& renderContext, DeviceCreateInfo const& createInfo);
4408bf80f4bSopenharmony_ci#endif
4418bf80f4bSopenharmony_ci#if (RENDER_HAS_GLES_BACKEND)
4428bf80f4bSopenharmony_ciBASE_NS::unique_ptr<Device> CreateDeviceGLES(RenderContext& renderContext, DeviceCreateInfo const& createInfo);
4438bf80f4bSopenharmony_ci#endif
4448bf80f4bSopenharmony_ciRENDER_END_NAMESPACE()
4458bf80f4bSopenharmony_ci
4468bf80f4bSopenharmony_ci#endif // GLES_DEVICE_GLES_H
447