diff --git a/impeller/renderer/backend/gles/BUILD.gn b/impeller/renderer/backend/gles/BUILD.gn index 39b112fcb9295..2877f2c72a684 100644 --- a/impeller/renderer/backend/gles/BUILD.gn +++ b/impeller/renderer/backend/gles/BUILD.gn @@ -14,6 +14,7 @@ config("gles_config") { impeller_component("gles_unittests") { testonly = true sources = [ + "test/capabilities_unittests.cc", "test/mock_gles.cc", "test/mock_gles.h", "test/mock_gles_unittests.cc", diff --git a/impeller/renderer/backend/gles/capabilities_gles.cc b/impeller/renderer/backend/gles/capabilities_gles.cc index fff4e5889808e..e639b1428bf86 100644 --- a/impeller/renderer/backend/gles/capabilities_gles.cc +++ b/impeller/renderer/backend/gles/capabilities_gles.cc @@ -103,4 +103,60 @@ size_t CapabilitiesGLES::GetMaxTextureUnits(ShaderStage stage) const { FML_UNREACHABLE(); } +bool CapabilitiesGLES::SupportsOffscreenMSAA() const { + return false; +} + +bool CapabilitiesGLES::SupportsSSBO() const { + return false; +} + +bool CapabilitiesGLES::SupportsBufferToTextureBlits() const { + return false; +} + +bool CapabilitiesGLES::SupportsTextureToTextureBlits() const { + return false; +} + +bool CapabilitiesGLES::SupportsFramebufferFetch() const { + return false; +} + +bool CapabilitiesGLES::SupportsCompute() const { + return false; +} + +bool CapabilitiesGLES::SupportsComputeSubgroups() const { + return false; +} + +bool CapabilitiesGLES::SupportsReadFromOnscreenTexture() const { + return false; +} + +bool CapabilitiesGLES::SupportsReadFromResolve() const { + return false; +} + +bool CapabilitiesGLES::SupportsDecalSamplerAddressMode() const { + return false; +} + +bool CapabilitiesGLES::SupportsDeviceTransientTextures() const { + return false; +} + +PixelFormat CapabilitiesGLES::GetDefaultColorFormat() const { + return PixelFormat::kR8G8B8A8UNormInt; +} + +PixelFormat CapabilitiesGLES::GetDefaultStencilFormat() const { + return PixelFormat::kS8UInt; +} + +PixelFormat CapabilitiesGLES::GetDefaultDepthStencilFormat() const { + return PixelFormat::kD24UnormS8Uint; +} + } // namespace impeller diff --git a/impeller/renderer/backend/gles/capabilities_gles.h b/impeller/renderer/backend/gles/capabilities_gles.h index edcfb99892c9c..b6ba0850c7b67 100644 --- a/impeller/renderer/backend/gles/capabilities_gles.h +++ b/impeller/renderer/backend/gles/capabilities_gles.h @@ -6,16 +6,31 @@ #include -#include "flutter/fml/macros.h" +#include "impeller/base/backend_cast.h" #include "impeller/core/shader_types.h" #include "impeller/geometry/size.h" +#include "impeller/renderer/capabilities.h" namespace impeller { class ProcTableGLES; -struct CapabilitiesGLES { - CapabilitiesGLES(const ProcTableGLES& gl); +//------------------------------------------------------------------------------ +/// @brief The Vulkan layers and extensions wrangler. +/// +class CapabilitiesGLES final + : public Capabilities, + public BackendCast { + public: + explicit CapabilitiesGLES(const ProcTableGLES& gl); + + CapabilitiesGLES(const CapabilitiesGLES&) = delete; + + CapabilitiesGLES(CapabilitiesGLES&&) = delete; + + CapabilitiesGLES& operator=(const CapabilitiesGLES&) = delete; + + CapabilitiesGLES& operator=(CapabilitiesGLES&&) = delete; // Must be at least 8. size_t max_combined_texture_image_units = 8; @@ -57,6 +72,48 @@ struct CapabilitiesGLES { size_t num_shader_binary_formats = 0; size_t GetMaxTextureUnits(ShaderStage stage) const; + + // |Capabilities| + bool SupportsOffscreenMSAA() const override; + + // |Capabilities| + bool SupportsSSBO() const override; + + // |Capabilities| + bool SupportsBufferToTextureBlits() const override; + + // |Capabilities| + bool SupportsTextureToTextureBlits() const override; + + // |Capabilities| + bool SupportsFramebufferFetch() const override; + + // |Capabilities| + bool SupportsCompute() const override; + + // |Capabilities| + bool SupportsComputeSubgroups() const override; + + // |Capabilities| + bool SupportsReadFromOnscreenTexture() const override; + + // |Capabilities| + bool SupportsReadFromResolve() const override; + + // |Capabilities| + bool SupportsDecalSamplerAddressMode() const override; + + // |Capabilities| + bool SupportsDeviceTransientTextures() const override; + + // |Capabilities| + PixelFormat GetDefaultColorFormat() const override; + + // |Capabilities| + PixelFormat GetDefaultStencilFormat() const override; + + // |Capabilities| + PixelFormat GetDefaultDepthStencilFormat() const override; }; } // namespace impeller diff --git a/impeller/renderer/backend/gles/context_gles.cc b/impeller/renderer/backend/gles/context_gles.cc index df65f5a1e09e0..8d98d41144133 100644 --- a/impeller/renderer/backend/gles/context_gles.cc +++ b/impeller/renderer/backend/gles/context_gles.cc @@ -6,6 +6,7 @@ #include "impeller/base/config.h" #include "impeller/base/validation.h" +#include "impeller/renderer/backend/gles/command_buffer_gles.h" namespace impeller { @@ -58,27 +59,7 @@ ContextGLES::ContextGLES(std::unique_ptr gl, std::shared_ptr(new SamplerLibraryGLES()); } - // Create the device capabilities. - { - device_capabilities_ = - CapabilitiesBuilder() - .SetSupportsOffscreenMSAA(false) - .SetSupportsSSBO(false) - .SetSupportsBufferToTextureBlits(false) - .SetSupportsTextureToTextureBlits(false) - .SetSupportsFramebufferFetch(false) - .SetDefaultColorFormat(PixelFormat::kR8G8B8A8UNormInt) - .SetDefaultStencilFormat(PixelFormat::kS8UInt) - .SetDefaultDepthStencilFormat(PixelFormat::kD24UnormS8Uint) - .SetSupportsCompute(false) - .SetSupportsComputeSubgroups(false) - .SetSupportsReadFromResolve(false) - .SetSupportsReadFromOnscreenTexture(false) - .SetSupportsDecalSamplerAddressMode(false) - .SetSupportsDeviceTransientTextures(false) - .Build(); - } - + device_capabilities_ = reactor_->GetProcTable().GetCapabilities(); is_valid_ = true; } diff --git a/impeller/renderer/backend/gles/context_gles.h b/impeller/renderer/backend/gles/context_gles.h index 92054cb413bee..56da6c55a8092 100644 --- a/impeller/renderer/backend/gles/context_gles.h +++ b/impeller/renderer/backend/gles/context_gles.h @@ -7,7 +7,7 @@ #include "flutter/fml/macros.h" #include "impeller/base/backend_cast.h" #include "impeller/renderer/backend/gles/allocator_gles.h" -#include "impeller/renderer/backend/gles/command_buffer_gles.h" +#include "impeller/renderer/backend/gles/capabilities_gles.h" #include "impeller/renderer/backend/gles/pipeline_library_gles.h" #include "impeller/renderer/backend/gles/reactor_gles.h" #include "impeller/renderer/backend/gles/sampler_library_gles.h" @@ -44,6 +44,9 @@ class ContextGLES final : public Context, std::shared_ptr pipeline_library_; std::shared_ptr sampler_library_; std::shared_ptr resource_allocator_; + // Note: This is stored separately from the ProcTableGLES CapabilitiesGLES + // in order to satisfy the Context::GetCapabilities signature which returns + // a reference. std::shared_ptr device_capabilities_; bool is_valid_ = false; diff --git a/impeller/renderer/backend/gles/proc_table_gles.cc b/impeller/renderer/backend/gles/proc_table_gles.cc index 1a13757354725..7bfbf4dce3f10 100644 --- a/impeller/renderer/backend/gles/proc_table_gles.cc +++ b/impeller/renderer/backend/gles/proc_table_gles.cc @@ -9,6 +9,8 @@ #include "impeller/base/allocation.h" #include "impeller/base/comparable.h" #include "impeller/base/validation.h" +#include "impeller/renderer/backend/gles/capabilities_gles.h" +#include "impeller/renderer/capabilities.h" namespace impeller { @@ -125,7 +127,7 @@ ProcTableGLES::ProcTableGLES(Resolver resolver) { DiscardFramebufferEXT.Reset(); } - capabilities_ = std::make_unique(*this); + capabilities_ = std::make_shared(*this); is_valid_ = true; } @@ -148,8 +150,9 @@ const DescriptionGLES* ProcTableGLES::GetDescription() const { return description_.get(); } -const CapabilitiesGLES* ProcTableGLES::GetCapabilities() const { - return capabilities_.get(); +const std::shared_ptr& ProcTableGLES::GetCapabilities() + const { + return capabilities_; } static const char* FramebufferStatusToString(GLenum status) { diff --git a/impeller/renderer/backend/gles/proc_table_gles.h b/impeller/renderer/backend/gles/proc_table_gles.h index 831c909e7a6e6..22945e6283850 100644 --- a/impeller/renderer/backend/gles/proc_table_gles.h +++ b/impeller/renderer/backend/gles/proc_table_gles.h @@ -229,7 +229,7 @@ class ProcTableGLES { const DescriptionGLES* GetDescription() const; - const CapabilitiesGLES* GetCapabilities() const; + const std::shared_ptr& GetCapabilities() const; std::string DescribeCurrentFramebuffer() const; @@ -248,7 +248,7 @@ class ProcTableGLES { private: bool is_valid_ = false; std::unique_ptr description_; - std::unique_ptr capabilities_; + std::shared_ptr capabilities_; GLint debug_label_max_length_ = 0; FML_DISALLOW_COPY_AND_ASSIGN(ProcTableGLES); diff --git a/impeller/renderer/backend/gles/test/capabilities_unittests.cc b/impeller/renderer/backend/gles/test/capabilities_unittests.cc new file mode 100644 index 0000000000000..0bbc1b93e9775 --- /dev/null +++ b/impeller/renderer/backend/gles/test/capabilities_unittests.cc @@ -0,0 +1,38 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/testing/testing.h" // IWYU pragma: keep +#include "gtest/gtest.h" +#include "impeller/renderer/backend/gles/proc_table_gles.h" +#include "impeller/renderer/backend/gles/test/mock_gles.h" + +namespace impeller { +namespace testing { + +TEST(CapabilitiesGLES, CanInitializeWithDefaults) { + auto mock_gles = MockGLES::Init(); + + auto capabilities = mock_gles->GetProcTable().GetCapabilities(); + + EXPECT_FALSE(capabilities->SupportsOffscreenMSAA()); + EXPECT_FALSE(capabilities->SupportsSSBO()); + EXPECT_FALSE(capabilities->SupportsBufferToTextureBlits()); + EXPECT_FALSE(capabilities->SupportsTextureToTextureBlits()); + EXPECT_FALSE(capabilities->SupportsFramebufferFetch()); + EXPECT_FALSE(capabilities->SupportsCompute()); + EXPECT_FALSE(capabilities->SupportsComputeSubgroups()); + EXPECT_FALSE(capabilities->SupportsReadFromOnscreenTexture()); + EXPECT_FALSE(capabilities->SupportsReadFromResolve()); + EXPECT_FALSE(capabilities->SupportsDecalSamplerAddressMode()); + EXPECT_FALSE(capabilities->SupportsDeviceTransientTextures()); + + EXPECT_EQ(capabilities->GetDefaultColorFormat(), + PixelFormat::kR8G8B8A8UNormInt); + EXPECT_EQ(capabilities->GetDefaultStencilFormat(), PixelFormat::kS8UInt); + EXPECT_EQ(capabilities->GetDefaultDepthStencilFormat(), + PixelFormat::kD24UnormS8Uint); +} + +} // namespace testing +} // namespace impeller