Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions impeller/aiks/aiks_blur_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ TEST_P(AiksTest, GaussianBlurWithoutDecalSupport) {
FLT_FORWARD(mock_capabilities, old_capabilities, SupportsCompute);
FLT_FORWARD(mock_capabilities, old_capabilities,
SupportsTextureToTextureBlits);
FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultGlyphAtlasFormat);
ASSERT_TRUE(SetCapabilities(mock_capabilities).ok());

auto texture = std::make_shared<Image>(CreateTextureForFixture("boston.jpg"));
Expand Down
6 changes: 5 additions & 1 deletion impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,11 @@ ContentContext::ContentContext(
options_trianglestrip);
srgb_to_linear_filter_pipelines_.CreateDefault(*context_,
options_trianglestrip);
glyph_atlas_pipelines_.CreateDefault(*context_, options);
glyph_atlas_pipelines_.CreateDefault(
*context_, options,
{static_cast<Scalar>(
GetContext()->GetCapabilities()->GetDefaultGlyphAtlasFormat() ==
PixelFormat::kA8UNormInt)});
glyph_atlas_color_pipelines_.CreateDefault(*context_, options);
geometry_color_pipelines_.CreateDefault(*context_, options);
yuv_to_rgb_filter_pipelines_.CreateDefault(*context_, options_trianglestrip);
Expand Down
8 changes: 7 additions & 1 deletion impeller/entity/shaders/glyph_atlas.frag
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ precision mediump float;

uniform f16sampler2D glyph_atlas_sampler;

layout(constant_id = 0) const float use_alpha_color_channel = 1.0;

in highp vec2 v_uv;

IMPELLER_MAYBE_FLAT in f16vec4 v_text_color;
Expand All @@ -16,5 +18,9 @@ out f16vec4 frag_color;

void main() {
f16vec4 value = texture(glyph_atlas_sampler, v_uv);
frag_color = value.aaaa * v_text_color;
if (use_alpha_color_channel == 1.0) {
frag_color = value.aaaa * v_text_color;
} else {
frag_color = value.rrrr * v_text_color;
}
}
11 changes: 11 additions & 0 deletions impeller/renderer/backend/gles/capabilities_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "impeller/renderer/backend/gles/capabilities_gles.h"

#include "impeller/core/formats.h"
#include "impeller/renderer/backend/gles/proc_table_gles.h"

namespace impeller {
Expand Down Expand Up @@ -102,6 +103,12 @@ CapabilitiesGLES::CapabilitiesGLES(const ProcTableGLES& gl) {
num_shader_binary_formats = value;
}

if (desc->IsES()) {
default_glyph_atlas_format_ = PixelFormat::kA8UNormInt;
} else {
default_glyph_atlas_format_ = PixelFormat::kR8UNormInt;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jason-simmons I think this shoudl be enough to get desktop GL working.

}

supports_framebuffer_fetch_ = desc->HasExtension(kFramebufferFetchExt);

if (desc->HasExtension(kTextureBorderClampExt) ||
Expand Down Expand Up @@ -194,4 +201,8 @@ bool CapabilitiesGLES::IsANGLE() const {
return is_angle_;
}

PixelFormat CapabilitiesGLES::GetDefaultGlyphAtlasFormat() const {
return default_glyph_atlas_format_;
}

} // namespace impeller
5 changes: 5 additions & 0 deletions impeller/renderer/backend/gles/capabilities_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <cstddef>

#include "impeller/base/backend_cast.h"
#include "impeller/core/formats.h"
#include "impeller/core/shader_types.h"
#include "impeller/geometry/size.h"
#include "impeller/renderer/capabilities.h"
Expand Down Expand Up @@ -118,12 +119,16 @@ class CapabilitiesGLES final
// |Capabilities|
PixelFormat GetDefaultDepthStencilFormat() const override;

// |Capabilities|
PixelFormat GetDefaultGlyphAtlasFormat() const override;

private:
bool supports_framebuffer_fetch_ = false;
bool supports_decal_sampler_address_mode_ = false;
bool supports_offscreen_msaa_ = false;
bool supports_implicit_msaa_ = false;
bool is_angle_ = false;
PixelFormat default_glyph_atlas_format_ = PixelFormat::kUnknown;
};

} // namespace impeller
Expand Down
6 changes: 5 additions & 1 deletion impeller/renderer/backend/gles/texture_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ struct TexImage2DData {
external_format = GL_ALPHA;
type = GL_UNSIGNED_BYTE;
break;
case PixelFormat::kR8UNormInt:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GL_RED is ES 3.0 and above only. A8 was chosen based on the ES 2.0 floors cap.

I agree that we should NOT depend on swizzles however. We observed some pretty dire performance cliffs with swizzles on older drivers. Though, to perform a swizzle via GL_TEXTURE_SWIZZLE_ requires ES 3.0 too. So we can't do it on ES 2.0 (and we shouldn't).

I suggest having a kGrayBitmap that maps to the backend native format and have an ifdef in the shader to pick the right format directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack, will do some more digging on that. I thought I observed Skia consistently using red bitmaps but that might just be on newer devices.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏽 go/es2-reference and go/es3-reference might come in handy. I also have Dash docsets for the different versions so checking up flag compatibility is easier. If you use Dash though.

internal_format = GL_RED;
external_format = GL_RED;
type = GL_UNSIGNED_BYTE;
break;
case PixelFormat::kR8G8B8A8UNormInt:
case PixelFormat::kB8G8R8A8UNormInt:
case PixelFormat::kR8G8B8A8UNormIntSRGB:
Expand Down Expand Up @@ -161,7 +166,6 @@ struct TexImage2DData {
break;
case PixelFormat::kUnknown:
case PixelFormat::kD32FloatS8UInt:
case PixelFormat::kR8UNormInt:
case PixelFormat::kR8G8UNormInt:
case PixelFormat::kB10G10R10XRSRGB:
case PixelFormat::kB10G10R10XR:
Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/backend/metal/context_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ static bool DeviceSupportsComputeSubgroups(id<MTLDevice> device) {
.SetSupportsComputeSubgroups(DeviceSupportsComputeSubgroups(device))
.SetSupportsReadFromResolve(true)
.SetSupportsDeviceTransientTextures(true)
.SetDefaultGlyphAtlasFormat(PixelFormat::kA8UNormInt)
.Build();
}

Expand Down
4 changes: 4 additions & 0 deletions impeller/renderer/backend/vulkan/capabilities_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -484,4 +484,8 @@ bool CapabilitiesVK::HasOptionalDeviceExtension(
optional_device_extensions_.end();
}

PixelFormat CapabilitiesVK::GetDefaultGlyphAtlasFormat() const {
return PixelFormat::kR8UNormInt;
}

} // namespace impeller
3 changes: 3 additions & 0 deletions impeller/renderer/backend/vulkan/capabilities_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ class CapabilitiesVK final : public Capabilities,
// |Capabilities|
PixelFormat GetDefaultDepthStencilFormat() const override;

// |Capabilities|
PixelFormat GetDefaultGlyphAtlasFormat() const override;

private:
bool validations_enabled_ = false;
std::map<std::string, std::set<std::string>> exts_;
Expand Down
9 changes: 0 additions & 9 deletions impeller/renderer/backend/vulkan/debug_report_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,6 @@ DebugReportVK::Result DebugReportVK::OnDebugCallback(
return Result::kContinue;
}

// This is a real error but we can't fix it due to our headers being too
// old. More more details see:
// https://vulkan.lunarg.com/doc/view/1.3.224.1/mac/1.3-extensions/vkspec.html#VUID-VkImageViewCreateInfo-imageViewFormatSwizzle-04465
// This validation error currently only trips on macOS due to the use of
// texture swizzles.
if (data->messageIdNumber == static_cast<int32_t>(0x82ae5050)) {
return Result::kContinue;
}

std::vector<std::pair<std::string, std::string>> items;

items.emplace_back("Severity", vk::to_string(severity));
Expand Down
20 changes: 18 additions & 2 deletions impeller/renderer/capabilities.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

#include "impeller/renderer/capabilities.h"
#include "impeller/core/formats.h"

namespace impeller {

Expand Down Expand Up @@ -74,10 +75,16 @@ class StandardCapabilities final : public Capabilities {
return default_depth_stencil_format_;
}

// |Capabilities|
bool SupportsDeviceTransientTextures() const override {
return supports_device_transient_textures_;
}

// |Capabilities|
PixelFormat GetDefaultGlyphAtlasFormat() const override {
return default_glyph_atlas_format_;
}

private:
StandardCapabilities(bool supports_offscreen_msaa,
bool supports_ssbo,
Expand All @@ -91,7 +98,8 @@ class StandardCapabilities final : public Capabilities {
bool supports_device_transient_textures,
PixelFormat default_color_format,
PixelFormat default_stencil_format,
PixelFormat default_depth_stencil_format)
PixelFormat default_depth_stencil_format,
PixelFormat default_glyph_atlas_format)
: supports_offscreen_msaa_(supports_offscreen_msaa),
supports_ssbo_(supports_ssbo),
supports_buffer_to_texture_blits_(supports_buffer_to_texture_blits),
Expand Down Expand Up @@ -122,6 +130,7 @@ class StandardCapabilities final : public Capabilities {
PixelFormat default_color_format_ = PixelFormat::kUnknown;
PixelFormat default_stencil_format_ = PixelFormat::kUnknown;
PixelFormat default_depth_stencil_format_ = PixelFormat::kUnknown;
PixelFormat default_glyph_atlas_format_ = PixelFormat::kUnknown;

StandardCapabilities(const StandardCapabilities&) = delete;

Expand Down Expand Up @@ -207,6 +216,12 @@ CapabilitiesBuilder& CapabilitiesBuilder::SetSupportsDeviceTransientTextures(
return *this;
}

CapabilitiesBuilder& CapabilitiesBuilder::SetDefaultGlyphAtlasFormat(
PixelFormat value) {
default_glyph_atlas_format_ = value;
return *this;
}

std::unique_ptr<Capabilities> CapabilitiesBuilder::Build() {
return std::unique_ptr<StandardCapabilities>(new StandardCapabilities( //
supports_offscreen_msaa_, //
Expand All @@ -221,7 +236,8 @@ std::unique_ptr<Capabilities> CapabilitiesBuilder::Build() {
supports_device_transient_textures_, //
default_color_format_.value_or(PixelFormat::kUnknown), //
default_stencil_format_.value_or(PixelFormat::kUnknown), //
default_depth_stencil_format_.value_or(PixelFormat::kUnknown) //
default_depth_stencil_format_.value_or(PixelFormat::kUnknown), //
default_glyph_atlas_format_.value_or(PixelFormat::kUnknown) //
));
}

Expand Down
9 changes: 9 additions & 0 deletions impeller/renderer/capabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ class Capabilities {
/// format was found.
virtual PixelFormat GetDefaultDepthStencilFormat() const = 0;

/// @brief Returns the default pixel format for the alpha bitmap glyph atlas.
///
/// Some backends may use Red channel while others use grey. This
/// should not have any impact
virtual PixelFormat GetDefaultGlyphAtlasFormat() const = 0;

protected:
Capabilities();

Expand Down Expand Up @@ -145,6 +151,8 @@ class CapabilitiesBuilder {

CapabilitiesBuilder& SetSupportsDeviceTransientTextures(bool value);

CapabilitiesBuilder& SetDefaultGlyphAtlasFormat(PixelFormat value);

std::unique_ptr<Capabilities> Build();

private:
Expand All @@ -161,6 +169,7 @@ class CapabilitiesBuilder {
std::optional<PixelFormat> default_color_format_ = std::nullopt;
std::optional<PixelFormat> default_stencil_format_ = std::nullopt;
std::optional<PixelFormat> default_depth_stencil_format_ = std::nullopt;
std::optional<PixelFormat> default_glyph_atlas_format_ = std::nullopt;

CapabilitiesBuilder(const CapabilitiesBuilder&) = delete;

Expand Down
21 changes: 15 additions & 6 deletions impeller/renderer/capabilities_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,31 +31,40 @@ CAPABILITY_TEST(SupportsDeviceTransientTextures, false);

TEST(CapabilitiesTest, DefaultColorFormat) {
auto defaults = CapabilitiesBuilder().Build();
ASSERT_EQ(defaults->GetDefaultColorFormat(), PixelFormat::kUnknown);
EXPECT_EQ(defaults->GetDefaultColorFormat(), PixelFormat::kUnknown);
auto mutated = CapabilitiesBuilder()
.SetDefaultColorFormat(PixelFormat::kB10G10R10A10XR)
.Build();
ASSERT_EQ(mutated->GetDefaultColorFormat(), PixelFormat::kB10G10R10A10XR);
EXPECT_EQ(mutated->GetDefaultColorFormat(), PixelFormat::kB10G10R10A10XR);
}

TEST(CapabilitiesTest, DefaultStencilFormat) {
auto defaults = CapabilitiesBuilder().Build();
ASSERT_EQ(defaults->GetDefaultStencilFormat(), PixelFormat::kUnknown);
EXPECT_EQ(defaults->GetDefaultStencilFormat(), PixelFormat::kUnknown);
auto mutated = CapabilitiesBuilder()
.SetDefaultStencilFormat(PixelFormat::kS8UInt)
.Build();
ASSERT_EQ(mutated->GetDefaultStencilFormat(), PixelFormat::kS8UInt);
EXPECT_EQ(mutated->GetDefaultStencilFormat(), PixelFormat::kS8UInt);
}

TEST(CapabilitiesTest, DefaultDepthStencilFormat) {
auto defaults = CapabilitiesBuilder().Build();
ASSERT_EQ(defaults->GetDefaultDepthStencilFormat(), PixelFormat::kUnknown);
EXPECT_EQ(defaults->GetDefaultDepthStencilFormat(), PixelFormat::kUnknown);
auto mutated = CapabilitiesBuilder()
.SetDefaultDepthStencilFormat(PixelFormat::kD32FloatS8UInt)
.Build();
ASSERT_EQ(mutated->GetDefaultDepthStencilFormat(),
EXPECT_EQ(mutated->GetDefaultDepthStencilFormat(),
PixelFormat::kD32FloatS8UInt);
}

TEST(CapabilitiesTest, DefaultGlyphAtlasFormat) {
auto defaults = CapabilitiesBuilder().Build();
EXPECT_EQ(defaults->GetDefaultGlyphAtlasFormat(), PixelFormat::kUnknown);
auto mutated = CapabilitiesBuilder()
.SetDefaultGlyphAtlasFormat(PixelFormat::kA8UNormInt)
.Build();
EXPECT_EQ(mutated->GetDefaultGlyphAtlasFormat(), PixelFormat::kA8UNormInt);
}

} // namespace testing
} // namespace impeller
1 change: 1 addition & 0 deletions impeller/renderer/testing/mocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ class MockCapabilities : public Capabilities {
MOCK_METHOD(PixelFormat, GetDefaultColorFormat, (), (const, override));
MOCK_METHOD(PixelFormat, GetDefaultStencilFormat, (), (const, override));
MOCK_METHOD(PixelFormat, GetDefaultDepthStencilFormat, (), (const, override));
MOCK_METHOD(PixelFormat, GetDefaultGlyphAtlasFormat, (), (const, override));
};

class MockCommandQueue : public CommandQueue {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "impeller/typographer/backends/skia/typeface_skia.h"
#include "impeller/typographer/rectangle_packer.h"
#include "impeller/typographer/typographer_context.h"
#include "include/core/SkColor.h"
#include "include/core/SkSize.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkFont.h"
Expand Down Expand Up @@ -220,7 +222,9 @@ static std::shared_ptr<SkBitmap> CreateAtlasBitmap(const GlyphAtlas& atlas,

switch (atlas.GetType()) {
case GlyphAtlas::Type::kAlphaBitmap:
image_info = SkImageInfo::MakeA8(atlas_size.width, atlas_size.height);
image_info =
SkImageInfo::MakeA8(SkISize{static_cast<int32_t>(atlas_size.width),
static_cast<int32_t>(atlas_size.height)});
break;
case GlyphAtlas::Type::kColorBitmap:
image_info =
Expand Down Expand Up @@ -466,7 +470,7 @@ std::shared_ptr<GlyphAtlas> TypographerContextSkia::CreateGlyphAtlas(
PixelFormat format;
switch (type) {
case GlyphAtlas::Type::kAlphaBitmap:
format = PixelFormat::kA8UNormInt;
format = context.GetCapabilities()->GetDefaultGlyphAtlasFormat();
break;
case GlyphAtlas::Type::kColorBitmap:
format = PixelFormat::kR8G8B8A8UNormInt;
Expand Down
7 changes: 4 additions & 3 deletions impeller/typographer/backends/stb/typographer_context_stb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -516,11 +516,12 @@ std::shared_ptr<GlyphAtlas> TypographerContextSTB::CreateGlyphAtlas(
PixelFormat format;
switch (type) {
case GlyphAtlas::Type::kAlphaBitmap:
format = PixelFormat::kA8UNormInt;
format = context.GetCapabilities()->GetDefaultGlyphAtlasFormat();
break;
case GlyphAtlas::Type::kColorBitmap:
format = DISABLE_COLOR_FONT_SUPPORT ? PixelFormat::kA8UNormInt
: PixelFormat::kR8G8B8A8UNormInt;
format = DISABLE_COLOR_FONT_SUPPORT
? context.GetCapabilities()->GetDefaultGlyphAtlasFormat()
: PixelFormat::kR8G8B8A8UNormInt;
break;
}
auto texture = UploadGlyphTextureAtlas(context.GetResourceAllocator(), bitmap,
Expand Down
5 changes: 3 additions & 2 deletions impeller/typographer/glyph_atlas.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <optional>
#include <unordered_map>

#include "flutter/fml/macros.h"
#include "impeller/core/texture.h"
#include "impeller/geometry/rect.h"
#include "impeller/renderer/pipeline.h"
Expand All @@ -33,8 +32,10 @@ class GlyphAtlas {
enum class Type {
//--------------------------------------------------------------------------
/// The glyphs are reprsented at their requested size using only an 8-bit
/// alpha channel.
/// color channel.
///
/// This might be backed by a grey or red single channel texture, depending
/// on the backend capabilities.
kAlphaBitmap,

//--------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion impeller/typographer/typographer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ TEST_P(TypographerTest, LazyAtlasTracksColor) {

lazy_atlas.AddTextFrame(*frame, 1.0f);

// Creates different atlases for color and alpha bitmap.
// Creates different atlases for color and red bitmap.
auto color_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
*GetContext(), GlyphAtlas::Type::kColorBitmap);

Expand Down