mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Reduces the compile size of Pipelines and ContentContext (#167671)
This reduces the size of ContentContext by introducing generic superclass versions of `RenderPipelineHandle` and `Variants` which allows the compiler to put most of the .text in the superclasses. testing: no new functionality, refactor ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
parent
2ca6284ce3
commit
bee65f3a4f
@ -28,6 +28,56 @@ namespace impeller {
|
||||
|
||||
namespace {
|
||||
|
||||
/// A generic version of `Variants` which mostly exists to reduce code size.
|
||||
class GenericVariants {
|
||||
public:
|
||||
void Set(const ContentContextOptions& options,
|
||||
std::unique_ptr<GenericRenderPipelineHandle> pipeline) {
|
||||
uint64_t p_key = options.ToKey();
|
||||
for (const auto& [key, pipeline] : pipelines_) {
|
||||
if (key == p_key) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
pipelines_.push_back(std::make_pair(p_key, std::move(pipeline)));
|
||||
}
|
||||
|
||||
void SetDefault(const ContentContextOptions& options,
|
||||
std::unique_ptr<GenericRenderPipelineHandle> pipeline) {
|
||||
default_options_ = options;
|
||||
if (pipeline) {
|
||||
Set(options, std::move(pipeline));
|
||||
}
|
||||
}
|
||||
|
||||
GenericRenderPipelineHandle* Get(const ContentContextOptions& options) const {
|
||||
uint64_t p_key = options.ToKey();
|
||||
for (const auto& [key, pipeline] : pipelines_) {
|
||||
if (key == p_key) {
|
||||
return pipeline.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SetDefaultDescriptor(std::optional<PipelineDescriptor> desc) {
|
||||
desc_ = std::move(desc);
|
||||
}
|
||||
|
||||
size_t GetPipelineCount() const { return pipelines_.size(); }
|
||||
|
||||
bool IsDefault(const ContentContextOptions& opts) {
|
||||
return default_options_.has_value() &&
|
||||
opts.ToKey() == default_options_.value().ToKey();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::optional<PipelineDescriptor> desc_;
|
||||
std::optional<ContentContextOptions> default_options_;
|
||||
std::vector<std::pair<uint64_t, std::unique_ptr<GenericRenderPipelineHandle>>>
|
||||
pipelines_;
|
||||
};
|
||||
|
||||
/// Holds multiple Pipelines associated with the same PipelineHandle types.
|
||||
///
|
||||
/// For example, it may have multiple
|
||||
@ -42,7 +92,7 @@ namespace {
|
||||
/// - impeller::RenderPipelineHandle<> - The type of objects this typically
|
||||
/// contains.
|
||||
template <class PipelineHandleT>
|
||||
class Variants {
|
||||
class Variants : public GenericVariants {
|
||||
static_assert(
|
||||
ShaderStageCompatibilityChecker<
|
||||
typename PipelineHandleT::VertexShader,
|
||||
@ -55,32 +105,20 @@ class Variants {
|
||||
|
||||
void Set(const ContentContextOptions& options,
|
||||
std::unique_ptr<PipelineHandleT> pipeline) {
|
||||
uint64_t p_key = options.ToKey();
|
||||
for (const auto& [key, pipeline] : pipelines_) {
|
||||
if (key == p_key) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
pipelines_.push_back(std::make_pair(p_key, std::move(pipeline)));
|
||||
GenericVariants::Set(options, std::move(pipeline));
|
||||
}
|
||||
|
||||
void SetDefault(const ContentContextOptions& options,
|
||||
std::unique_ptr<PipelineHandleT> pipeline) {
|
||||
default_options_ = options;
|
||||
if (pipeline) {
|
||||
Set(options, std::move(pipeline));
|
||||
}
|
||||
}
|
||||
|
||||
void SetDefaultDescriptor(std::optional<PipelineDescriptor> desc) {
|
||||
desc_ = std::move(desc);
|
||||
GenericVariants::SetDefault(options, std::move(pipeline));
|
||||
}
|
||||
|
||||
void CreateDefault(const Context& context,
|
||||
const ContentContextOptions& options,
|
||||
const std::vector<Scalar>& constants = {}) {
|
||||
auto desc = PipelineHandleT::Builder::MakeDefaultPipelineDescriptor(
|
||||
context, constants);
|
||||
std::optional<PipelineDescriptor> desc =
|
||||
PipelineHandleT::Builder::MakeDefaultPipelineDescriptor(context,
|
||||
constants);
|
||||
if (!desc.has_value()) {
|
||||
VALIDATION_LOG << "Failed to create default pipeline.";
|
||||
return;
|
||||
@ -96,18 +134,7 @@ class Variants {
|
||||
}
|
||||
|
||||
PipelineHandleT* Get(const ContentContextOptions& options) const {
|
||||
uint64_t p_key = options.ToKey();
|
||||
for (const auto& [key, pipeline] : pipelines_) {
|
||||
if (key == p_key) {
|
||||
return pipeline.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool IsDefault(const ContentContextOptions& opts) {
|
||||
return default_options_.has_value() &&
|
||||
opts.ToKey() == default_options_.value().ToKey();
|
||||
return static_cast<PipelineHandleT*>(GenericVariants::Get(options));
|
||||
}
|
||||
|
||||
PipelineHandleT* GetDefault(const Context& context) {
|
||||
@ -123,13 +150,7 @@ class Variants {
|
||||
return Get(default_options_.value());
|
||||
}
|
||||
|
||||
size_t GetPipelineCount() const { return pipelines_.size(); }
|
||||
|
||||
private:
|
||||
std::optional<PipelineDescriptor> desc_;
|
||||
std::optional<ContentContextOptions> default_options_;
|
||||
std::vector<std::pair<uint64_t, std::unique_ptr<PipelineHandleT>>> pipelines_;
|
||||
|
||||
Variants(const Variants&) = delete;
|
||||
|
||||
Variants& operator=(const Variants&) = delete;
|
||||
|
||||
@ -107,34 +107,24 @@ PipelineFuture<ComputePipelineDescriptor> CreatePipelineFuture(
|
||||
const Context& context,
|
||||
std::optional<ComputePipelineDescriptor> desc);
|
||||
|
||||
/// Holds a reference to a Pipeline used for rendering while also maintaining
|
||||
/// the vertex shader and fragment shader types at compile-time.
|
||||
/// Holds a reference to a Pipeline used for rendering.
|
||||
///
|
||||
/// See also:
|
||||
/// - impeller::ContentContext::Variants - the typical container for
|
||||
/// RenderPipelineHandles.
|
||||
template <class VertexShader_, class FragmentShader_>
|
||||
class RenderPipelineHandle {
|
||||
/// @see RenderPipelineHandle the templated subclass that stores compile-time
|
||||
/// shader information.
|
||||
class GenericRenderPipelineHandle {
|
||||
public:
|
||||
using VertexShader = VertexShader_;
|
||||
using FragmentShader = FragmentShader_;
|
||||
using Builder = PipelineBuilder<VertexShader, FragmentShader>;
|
||||
explicit GenericRenderPipelineHandle(const Context& context,
|
||||
std::optional<PipelineDescriptor> desc,
|
||||
bool async = true)
|
||||
: GenericRenderPipelineHandle(
|
||||
CreatePipelineFuture(context, std::move(desc), /*async=*/async)) {}
|
||||
|
||||
explicit RenderPipelineHandle(const Context& context, bool async = true)
|
||||
: RenderPipelineHandle(CreatePipelineFuture(
|
||||
context,
|
||||
Builder::MakeDefaultPipelineDescriptor(context),
|
||||
async)) {}
|
||||
|
||||
explicit RenderPipelineHandle(const Context& context,
|
||||
std::optional<PipelineDescriptor> desc,
|
||||
bool async = true)
|
||||
: RenderPipelineHandle(
|
||||
CreatePipelineFuture(context, desc, /*async=*/async)) {}
|
||||
|
||||
explicit RenderPipelineHandle(PipelineFuture<PipelineDescriptor> future)
|
||||
explicit GenericRenderPipelineHandle(
|
||||
PipelineFuture<PipelineDescriptor> future)
|
||||
: pipeline_future_(std::move(future)) {}
|
||||
|
||||
virtual ~GenericRenderPipelineHandle() = default;
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>> WaitAndGet() {
|
||||
if (did_wait_) {
|
||||
return pipeline_;
|
||||
@ -155,6 +145,40 @@ class RenderPipelineHandle {
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline_;
|
||||
bool did_wait_ = false;
|
||||
|
||||
GenericRenderPipelineHandle(const GenericRenderPipelineHandle&) = delete;
|
||||
|
||||
GenericRenderPipelineHandle& operator=(const GenericRenderPipelineHandle&) =
|
||||
delete;
|
||||
};
|
||||
|
||||
/// Holds a reference to a Pipeline used for rendering while also maintaining
|
||||
/// the vertex shader and fragment shader types at compile-time.
|
||||
///
|
||||
/// See also:
|
||||
/// - impeller::ContentContext::Variants - the typical container for
|
||||
/// RenderPipelineHandles.
|
||||
template <class VertexShader_, class FragmentShader_>
|
||||
class RenderPipelineHandle : public GenericRenderPipelineHandle {
|
||||
public:
|
||||
using VertexShader = VertexShader_;
|
||||
using FragmentShader = FragmentShader_;
|
||||
using Builder = PipelineBuilder<VertexShader, FragmentShader>;
|
||||
|
||||
explicit RenderPipelineHandle(const Context& context, bool async = true)
|
||||
: GenericRenderPipelineHandle(CreatePipelineFuture(
|
||||
context,
|
||||
Builder::MakeDefaultPipelineDescriptor(context),
|
||||
async)) {}
|
||||
|
||||
explicit RenderPipelineHandle(const Context& context,
|
||||
std::optional<PipelineDescriptor> desc,
|
||||
bool async = true)
|
||||
: GenericRenderPipelineHandle(context, desc, async) {}
|
||||
|
||||
explicit RenderPipelineHandle(PipelineFuture<PipelineDescriptor> future)
|
||||
: GenericRenderPipelineHandle(std::move(future)) {}
|
||||
|
||||
private:
|
||||
RenderPipelineHandle(const RenderPipelineHandle&) = delete;
|
||||
|
||||
RenderPipelineHandle& operator=(const RenderPipelineHandle&) = delete;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user