This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
[Impeller] Add support for multi-rendering-backend fat shader archives. #47278
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// 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 "impeller/shader_archive/multi_arch_shader_archive.h" | ||
|
||
#include "impeller/shader_archive/multi_arch_shader_archive_flatbuffers.h" | ||
|
||
namespace impeller { | ||
|
||
constexpr ArchiveRenderingBackend ToArchiveRenderingBackend( | ||
fb::RenderingBackend backend) { | ||
switch (backend) { | ||
case fb::RenderingBackend::kOpenGLES: | ||
return ArchiveRenderingBackend::kOpenGLES; | ||
case fb::RenderingBackend::kVulkan: | ||
return ArchiveRenderingBackend::kVulkan; | ||
case fb::RenderingBackend::kMetal: | ||
return ArchiveRenderingBackend::kMetal; | ||
} | ||
FML_UNREACHABLE(); | ||
} | ||
|
||
std::shared_ptr<ShaderArchive> MultiArchShaderArchive::CreateArchiveFromMapping( | ||
const std::shared_ptr<const fml::Mapping>& mapping, | ||
ArchiveRenderingBackend backend) { | ||
{ | ||
auto multi_archive = std::make_shared<MultiArchShaderArchive>(mapping); | ||
if (multi_archive->IsValid()) { | ||
return multi_archive->GetShaderArchive(backend); | ||
} | ||
} | ||
{ | ||
auto single_archive = | ||
std::shared_ptr<ShaderArchive>(new ShaderArchive(mapping)); | ||
if (single_archive->IsValid()) { | ||
return single_archive; | ||
} | ||
} | ||
return nullptr; | ||
} | ||
|
||
MultiArchShaderArchive::MultiArchShaderArchive( | ||
const std::shared_ptr<const fml::Mapping>& mapping) { | ||
if (!mapping) { | ||
return; | ||
} | ||
|
||
if (!fb::MultiArchShaderArchiveBufferHasIdentifier(mapping->GetMapping())) { | ||
return; | ||
} | ||
|
||
const auto* multi_arch = fb::GetMultiArchShaderArchive(mapping->GetMapping()); | ||
|
||
if (!multi_arch) { | ||
return; | ||
} | ||
|
||
if (auto archives = multi_arch->items()) { | ||
for (auto i = archives->begin(), end = archives->end(); i != end; i++) { | ||
// This implementation is unable to handle multiple archives for the same | ||
// backend. | ||
backend_mappings_[ToArchiveRenderingBackend(i->rendering_backend())] = | ||
std::make_shared<fml::NonOwnedMapping>(i->mapping()->Data(), | ||
i->mapping()->size(), | ||
[mapping](auto, auto) { | ||
// Just hold the mapping. | ||
}); | ||
} | ||
} | ||
|
||
is_valid_ = true; | ||
} | ||
|
||
MultiArchShaderArchive::~MultiArchShaderArchive() = default; | ||
|
||
bool MultiArchShaderArchive::IsValid() const { | ||
return is_valid_; | ||
} | ||
|
||
std::shared_ptr<const fml::Mapping> MultiArchShaderArchive::GetArchive( | ||
ArchiveRenderingBackend backend) const { | ||
auto found = backend_mappings_.find(backend); | ||
if (found == backend_mappings_.end()) { | ||
return nullptr; | ||
} | ||
return found->second; | ||
} | ||
|
||
std::shared_ptr<ShaderArchive> MultiArchShaderArchive::GetShaderArchive( | ||
ArchiveRenderingBackend backend) const { | ||
auto archive = GetArchive(backend); | ||
if (!archive) { | ||
return nullptr; | ||
} | ||
auto shader_archive = | ||
std::shared_ptr<ShaderArchive>(new ShaderArchive(std::move(archive))); | ||
if (!shader_archive->IsValid()) { | ||
return nullptr; | ||
} | ||
return shader_archive; | ||
} | ||
|
||
} // namespace impeller |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// 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. | ||
|
||
namespace impeller.fb; | ||
|
||
enum RenderingBackend:byte { | ||
kOpenGLES, | ||
kVulkan, | ||
kMetal, | ||
} | ||
|
||
table ShaderArchiveBlob { | ||
rendering_backend: RenderingBackend; | ||
mapping: [ubyte]; | ||
} | ||
|
||
table MultiArchShaderArchive { | ||
// We could have just as easily used the existing `ShaderArchive` table here. | ||
// However, those tables aren't used by Metal. | ||
items: [ShaderArchiveBlob]; | ||
} | ||
|
||
root_type MultiArchShaderArchive; | ||
file_identifier "MARC"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// 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. | ||
|
||
#pragma once | ||
|
||
#include <map> | ||
#include <memory> | ||
|
||
#include "flutter/fml/macros.h" | ||
#include "flutter/fml/mapping.h" | ||
#include "impeller/shader_archive/shader_archive.h" | ||
#include "impeller/shader_archive/shader_archive_types.h" | ||
|
||
namespace impeller { | ||
|
||
class MultiArchShaderArchive { | ||
public: | ||
static std::shared_ptr<ShaderArchive> CreateArchiveFromMapping( | ||
const std::shared_ptr<const fml::Mapping>& mapping, | ||
ArchiveRenderingBackend backend); | ||
|
||
explicit MultiArchShaderArchive( | ||
const std::shared_ptr<const fml::Mapping>& mapping); | ||
|
||
~MultiArchShaderArchive(); | ||
|
||
std::shared_ptr<const fml::Mapping> GetArchive( | ||
ArchiveRenderingBackend backend) const; | ||
|
||
std::shared_ptr<ShaderArchive> GetShaderArchive( | ||
ArchiveRenderingBackend backend) const; | ||
|
||
bool IsValid() const; | ||
|
||
private: | ||
std::map<ArchiveRenderingBackend, std::shared_ptr<const fml::Mapping>> | ||
backend_mappings_; | ||
bool is_valid_ = false; | ||
|
||
FML_DISALLOW_COPY_AND_ASSIGN(MultiArchShaderArchive); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we still doing this in new code? Or should the new style be used? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Patched #47307 |
||
}; | ||
|
||
} // namespace impeller |
64 changes: 64 additions & 0 deletions
64
impeller/shader_archive/multi_arch_shader_archive_writer.cc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// 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 "impeller/shader_archive/multi_arch_shader_archive_writer.h" | ||
|
||
#include "impeller/base/validation.h" | ||
#include "impeller/shader_archive/multi_arch_shader_archive_flatbuffers.h" | ||
|
||
namespace impeller { | ||
|
||
MultiArchShaderArchiveWriter::MultiArchShaderArchiveWriter() = default; | ||
|
||
MultiArchShaderArchiveWriter::~MultiArchShaderArchiveWriter() = default; | ||
|
||
bool MultiArchShaderArchiveWriter::RegisterShaderArchive( | ||
ArchiveRenderingBackend backend, | ||
std::shared_ptr<const fml::Mapping> mapping) { | ||
if (!mapping || mapping->GetMapping() == nullptr) { | ||
return false; | ||
} | ||
if (archives_.find(backend) != archives_.end()) { | ||
VALIDATION_LOG << "Multi-archive already has a shader library registered " | ||
"for that backend."; | ||
return false; | ||
} | ||
archives_[backend] = std::move(mapping); | ||
return true; | ||
} | ||
|
||
constexpr fb::RenderingBackend ToRenderingBackend( | ||
ArchiveRenderingBackend backend) { | ||
switch (backend) { | ||
case ArchiveRenderingBackend::kMetal: | ||
return fb::RenderingBackend::kMetal; | ||
case ArchiveRenderingBackend::kVulkan: | ||
return fb::RenderingBackend::kVulkan; | ||
case ArchiveRenderingBackend::kOpenGLES: | ||
return fb::RenderingBackend::kOpenGLES; | ||
} | ||
FML_UNREACHABLE(); | ||
} | ||
|
||
std::shared_ptr<fml::Mapping> MultiArchShaderArchiveWriter::CreateMapping() | ||
const { | ||
fb::MultiArchShaderArchiveT multi_archive; | ||
for (const auto& archive : archives_) { | ||
auto archive_blob = std::make_unique<fb::ShaderArchiveBlobT>(); | ||
archive_blob->rendering_backend = ToRenderingBackend(archive.first); | ||
archive_blob->mapping = { | ||
archive.second->GetMapping(), | ||
archive.second->GetMapping() + archive.second->GetSize()}; | ||
multi_archive.items.emplace_back(std::move(archive_blob)); | ||
} | ||
auto builder = std::make_shared<flatbuffers::FlatBufferBuilder>(); | ||
builder->Finish( | ||
fb::MultiArchShaderArchive::Pack(*builder.get(), &multi_archive), | ||
fb::MultiArchShaderArchiveIdentifier()); | ||
return std::make_shared<fml::NonOwnedMapping>(builder->GetBufferPointer(), | ||
builder->GetSize(), | ||
[builder](auto, auto) {}); | ||
} | ||
|
||
} // namespace impeller |
34 changes: 34 additions & 0 deletions
34
impeller/shader_archive/multi_arch_shader_archive_writer.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// 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. | ||
|
||
#pragma once | ||
|
||
#include <map> | ||
|
||
#include "flutter/fml/macros.h" | ||
#include "flutter/fml/mapping.h" | ||
#include "impeller/shader_archive/shader_archive_types.h" | ||
|
||
namespace impeller { | ||
|
||
class MultiArchShaderArchiveWriter { | ||
public: | ||
MultiArchShaderArchiveWriter(); | ||
|
||
~MultiArchShaderArchiveWriter(); | ||
|
||
[[nodiscard]] bool RegisterShaderArchive( | ||
ArchiveRenderingBackend backend, | ||
std::shared_ptr<const fml::Mapping> mapping); | ||
|
||
std::shared_ptr<fml::Mapping> CreateMapping() const; | ||
|
||
private: | ||
std::map<ArchiveRenderingBackend, std::shared_ptr<const fml::Mapping>> | ||
archives_; | ||
|
||
FML_DISALLOW_COPY_AND_ASSIGN(MultiArchShaderArchiveWriter); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto question. |
||
}; | ||
|
||
} // namespace impeller |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we include more information here? Right now there are some implicit version constraints in these formats more or less. We could make this explicitly kOpenGLESv100 or add additional version metadata.
You could imagine in the future that we might support targeting higher GLSL versions for desktop or webgl, and the engine will need to know the right version information to consume it. I'm not sure if we'd ever ship multiple GLSL versions of the same shader in the same file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of this is internal implementation detail. So I suspect we can tinker on this all we want.
In the future, we could even concatenate multiple shader libraries for the same backend instead of loading on of each.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sgtm