Skip to content

Commit

Permalink
[impeller] Implement an OpenGL ES 2.0 backend. (flutter#33084)
Browse files Browse the repository at this point in the history
  • Loading branch information
chinmaygarde authored May 4, 2022
1 parent a406112 commit 99d3ec0
Show file tree
Hide file tree
Showing 123 changed files with 3,924 additions and 723 deletions.
10 changes: 6 additions & 4 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,13 @@ group("unittests") {
public_deps += [ "//flutter/shell/platform/fuchsia:tests" ]
}

if (is_mac || is_linux) {
public_deps += [ "//flutter/impeller:impeller_unittests" ]
}

if (is_mac) {
public_deps += [
"//flutter/impeller:impeller_unittests",
"//flutter/shell/platform/darwin:flutter_channels_unittests",
]
public_deps +=
[ "//flutter/shell/platform/darwin:flutter_channels_unittests" ]
}

if (!is_win && !is_fuchsia) {
Expand Down
22 changes: 21 additions & 1 deletion ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -611,28 +611,46 @@ FILE: ../../../flutter/impeller/renderer/allocator.cc
FILE: ../../../flutter/impeller/renderer/allocator.h
FILE: ../../../flutter/impeller/renderer/backend/gles/allocator_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/allocator_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/buffer_bindings_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/buffer_bindings_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/command_buffer_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/command_buffer_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/context_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/context_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/device_buffer_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/device_buffer_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/formats_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/formats_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/gl_description.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/gl_description.h
FILE: ../../../flutter/impeller/renderer/backend/gles/gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/gles_handle.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/gles_handle.h
FILE: ../../../flutter/impeller/renderer/backend/gles/gles_test.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/gles_test.h
FILE: ../../../flutter/impeller/renderer/backend/gles/gles_unittests.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/pipeline_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/pipeline_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/pipeline_library_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/pipeline_library_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/proc_table_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/proc_table_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/reactor_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/reactor_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/render_pass_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/render_pass_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/sampler_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/sampler_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/sampler_library_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/sampler_library_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/shader_function_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/shader_function_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/shader_library_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/shader_library_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/surface_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/surface_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/texture_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/vertex_descriptor_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/texture_gles.h
FILE: ../../../flutter/impeller/renderer/backend/metal/allocator_mtl.h
FILE: ../../../flutter/impeller/renderer/backend/metal/allocator_mtl.mm
FILE: ../../../flutter/impeller/renderer/backend/metal/command_buffer_mtl.h
Expand Down Expand Up @@ -708,6 +726,8 @@ FILE: ../../../flutter/impeller/renderer/sampler_library.cc
FILE: ../../../flutter/impeller/renderer/sampler_library.h
FILE: ../../../flutter/impeller/renderer/shader_function.cc
FILE: ../../../flutter/impeller/renderer/shader_function.h
FILE: ../../../flutter/impeller/renderer/shader_key.cc
FILE: ../../../flutter/impeller/renderer/shader_key.h
FILE: ../../../flutter/impeller/renderer/shader_library.cc
FILE: ../../../flutter/impeller/renderer/shader_library.h
FILE: ../../../flutter/impeller/renderer/shader_types.cc
Expand Down
10 changes: 10 additions & 0 deletions impeller/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ config("impeller_public_config") {
defines += [ "IMPELLER_SUPPORTS_RENDERING=1" ]
}

if (impeller_enable_metal) {
defines += [ "IMPELLER_ENABLE_METAL=1" ]
}

if (impeller_enable_opengles) {
defines += [ "IMPELLER_ENABLE_OPENGLES=1" ]
}

if (is_win) {
defines += [
"_USE_MATH_DEFINES",
Expand All @@ -42,6 +50,7 @@ group("impeller") {
"entity",
"image",
"renderer",
"renderer/backend",
"typographer",
]
}
Expand All @@ -68,6 +77,7 @@ executable("impeller_unittests") {
"image:image_unittests",
"playground",
"renderer:renderer_unittests",
"renderer/backend:backend_unittests",
"typographer:typographer_unittests",
]
}
Expand Down
2 changes: 1 addition & 1 deletion impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ TEST_P(AiksTest, CanvasCanPushPopCTM) {
TEST_P(AiksTest, CanRenderColoredRect) {
Canvas canvas;
Paint paint;
paint.color = Color::Red();
paint.color = Color::Blue();
canvas.DrawPath(PathBuilder{}
.AddRect(Rect::MakeXYWH(100.0, 100.0, 100.0, 100.0))
.TakePath(),
Expand Down
20 changes: 20 additions & 0 deletions impeller/base/allocation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,24 @@ bool Allocation::Reserve(size_t reserved) {
return true;
}

std::shared_ptr<fml::Mapping> CreateMappingWithCopy(const uint8_t* contents,
size_t length) {
if (contents == nullptr) {
return nullptr;
}

auto allocation = std::make_shared<Allocation>();
if (!allocation->Truncate(length)) {
return nullptr;
}

std::memmove(allocation->GetBuffer(), contents, length);

return std::make_shared<fml::NonOwnedMapping>(
reinterpret_cast<const uint8_t*>(allocation->GetBuffer()), //
allocation->GetLength(), //
[allocation](auto, auto) {} //
);
}

} // namespace impeller
4 changes: 4 additions & 0 deletions impeller/base/allocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <memory>

#include "flutter/fml/macros.h"
#include "flutter/fml/mapping.h"

namespace impeller {

Expand Down Expand Up @@ -39,4 +40,7 @@ class Allocation {
FML_DISALLOW_COPY_AND_ASSIGN(Allocation);
};

std::shared_ptr<fml::Mapping> CreateMappingWithCopy(const uint8_t* contents,
size_t length);

} // namespace impeller
6 changes: 6 additions & 0 deletions impeller/base/backend_cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ class BackendCast {
static const Sub& Cast(const Base& base) {
return reinterpret_cast<const Sub&>(base);
}

static Sub* Cast(Base* base) { return reinterpret_cast<Sub*>(base); }

static const Sub* Cast(const Base* base) {
return reinterpret_cast<const Sub*>(base);
}
};

} // namespace impeller
20 changes: 20 additions & 0 deletions impeller/blobcat/blob_library.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ BlobLibrary::BlobLibrary(std::shared_ptr<fml::Mapping> mapping)
is_valid_ = true;
}

BlobLibrary::BlobLibrary(BlobLibrary&&) = default;

BlobLibrary::~BlobLibrary() = default;

bool BlobLibrary::IsValid() const {
Expand All @@ -91,4 +93,22 @@ std::shared_ptr<fml::Mapping> BlobLibrary::GetMapping(Blob::ShaderType type,
return found == blobs_.end() ? nullptr : found->second;
}

size_t BlobLibrary::IterateAllBlobs(
std::function<bool(Blob::ShaderType type,
const std::string& name,
const std::shared_ptr<fml::Mapping>& mapping)> callback)
const {
if (!IsValid() || !callback) {
return 0u;
}
size_t count = 0u;
for (const auto& blob : blobs_) {
count++;
if (!callback(blob.first.type, blob.first.name, blob.second)) {
break;
}
}
return count;
}

} // namespace impeller
7 changes: 7 additions & 0 deletions impeller/blobcat/blob_library.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class BlobLibrary {
public:
BlobLibrary(std::shared_ptr<fml::Mapping> mapping);

BlobLibrary(BlobLibrary&&);

~BlobLibrary();

bool IsValid() const;
Expand All @@ -28,6 +30,11 @@ class BlobLibrary {
std::shared_ptr<fml::Mapping> GetMapping(Blob::ShaderType type,
std::string name) const;

size_t IterateAllBlobs(
std::function<bool(Blob::ShaderType type,
const std::string& name,
const std::shared_ptr<fml::Mapping>& mapping)>) const;

private:
struct BlobKey {
Blob::ShaderType type = Blob::ShaderType::kFragment;
Expand Down
51 changes: 40 additions & 11 deletions impeller/compiler/code_gen_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,19 @@ constexpr std::string_view kReflectionHeaderTemplate =
#pragma once
// Note: The nogncheck decorations are only to make GN not mad at the template
// this file is generated from. There are no GN rule violations in the generated
// file itself.
#include "impeller/renderer/buffer_view.h" // nogncheck
#include "impeller/renderer/command.h" // nogncheck
#include "impeller/renderer/sampler.h" // nogncheck
#include "impeller/renderer/shader_types.h" // nogncheck
#include "impeller/renderer/texture.h" // nogncheck
{# Note: The nogncheck decorations are only to make GN not mad at the template#}
{# this file is generated from. There are no GN rule violations in the generated#}
{# file itself and the no-check declarations will be stripped in generated files.#}
#include "impeller/renderer/buffer_view.h" {# // nogncheck #}
#include "impeller/renderer/command.h" {# // nogncheck #}
#include "impeller/renderer/sampler.h" {# // nogncheck #}
#include "impeller/renderer/shader_types.h" {# // nogncheck #}
#include "impeller/renderer/texture.h" {# // nogncheck #}
namespace impeller {
Expand All @@ -31,12 +36,14 @@ struct {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader {
static constexpr std::string_view kLabel = "{{camel_case(shader_name)}}";
static constexpr std::string_view kEntrypointName = "{{entrypoint}}";
static constexpr ShaderStage kShaderStage = {{to_shader_stage(shader_stage)}};
// The generator used to prepare these bindings. Metal generators may be used
// by GLES backends but GLES generators are unsuitable for the metal backend.
static constexpr std::string_view kGeneratorName = "{{get_generator_name()}}";
{% if length(struct_definitions) > 0 %}
// ===========================================================================
// Struct Definitions ========================================================
// ===========================================================================
{% for def in struct_definitions %}
struct {{def.name}} {
{% for member in def.members %}
{{member.type}} {{member.name}}; // (offset {{member.offset}}, size {{member.byte_length}})
Expand All @@ -51,10 +58,11 @@ struct {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader {
// ===========================================================================
{% for buffer in buffers %}
static constexpr auto kResource{{camel_case(buffer.name)}} = ShaderUniformSlot<{{buffer.name}}> { // {{buffer.name}}
static constexpr auto kResource{{camel_case(buffer.name)}} = ShaderUniformSlot { // {{buffer.name}}
"{{buffer.name}}", // name
{{buffer.ext_res_0}}u, // binding
};
static ShaderMetadata kMetadata{{camel_case(buffer.name)}};
{% endfor %}
{% endif %}
Expand Down Expand Up @@ -94,6 +102,7 @@ struct {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader {
{{sampled_image.ext_res_0}}u, // texture
{{sampled_image.ext_res_1}}u, // sampler
};
static ShaderMetadata kMetadata{{camel_case(sampled_image.name)}};
{% endfor %}
{% endif %}
// ===========================================================================
Expand Down Expand Up @@ -130,7 +139,7 @@ struct {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader {
{% endfor %}) {
return {{ proto.args.0.argument_name }}.BindResource({% for arg in proto.args %}
{% if loop.is_first %}
{{to_shader_stage(shader_stage)}}, kResource{{ proto.name }}, {% else %}
{{to_shader_stage(shader_stage)}}, kResource{{ proto.name }}, kMetadata{{ proto.name }}, {% else %}
std::move({{ arg.argument_name }}){% if not loop.is_last %}, {% endif %}
{% endif %}
{% endfor %});
Expand Down Expand Up @@ -164,6 +173,26 @@ static_assert(offsetof(Shader::{{def.name}}, {{member.name}}) == {{member.offset
{% endfor %}
{% endfor %}
{% for buffer in buffers %}
ShaderMetadata Shader::kMetadata{{camel_case(buffer.name)}} = {
"{{buffer.name}}", // name
std::vector<ShaderStructMemberMetadata> {
{% for member in buffer.type.members %}
ShaderStructMemberMetadata {
{{ member.base_type }}, // type
"{{ member.name }}", // name
{{ member.offset }}, // offset
{{ member.size }}, // size
},
{% endfor %}
} // members
};
{% endfor %}
{% for sampled_image in sampled_images %}
ShaderMetadata Shader::kMetadata{{camel_case(sampled_image.name)}};
{% endfor %}
} // namespace impeller
)~~";

Expand Down
26 changes: 24 additions & 2 deletions impeller/compiler/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,33 @@ static CompilerBackend CreateGLSLCompiler(const spirv_cross::ParsedIR& ir,
auto gl_compiler = std::make_shared<spirv_cross::CompilerGLSL>(ir);
spirv_cross::CompilerGLSL::Options sl_options;
sl_options.force_zero_initialized_variables = true;
sl_options.vertex.fixup_clipspace = true;
if (source_options.target_platform == TargetPlatform::kOpenGLES) {
sl_options.version = 100;
sl_options.es = true;
} else {
sl_options.version = 120;
sl_options.es = false;
}
gl_compiler->set_common_options(sl_options);
return gl_compiler;
}

static bool EntryPointMustBeNamedMain(TargetPlatform platform) {
switch (platform) {
case TargetPlatform::kUnknown:
FML_UNREACHABLE();
case TargetPlatform::kMetalDesktop:
case TargetPlatform::kMetalIOS:
return false;
case TargetPlatform::kFlutterSPIRV:
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
return true;
}
FML_UNREACHABLE();
}

static CompilerBackend CreateCompiler(const spirv_cross::ParsedIR& ir,
const SourceOptions& source_options) {
CompilerBackend compiler;
Expand All @@ -62,8 +81,11 @@ static CompilerBackend CreateCompiler(const spirv_cross::ParsedIR& ir,
return {};
}
auto* backend = compiler.GetCompiler();
backend->rename_entry_point("main", source_options.entry_point_name,
ToExecutionModel(source_options.type));
if (!EntryPointMustBeNamedMain(source_options.target_platform)) {
backend->rename_entry_point("main", source_options.entry_point_name,
ToExecutionModel(source_options.type));
}

return compiler;
}

Expand Down
Loading

0 comments on commit 99d3ec0

Please sign in to comment.