Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Impeller] Add debug ToString methods to render targets. #41221

Merged
merged 1 commit into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 8 additions & 0 deletions impeller/base/base_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

#include "flutter/testing/testing.h"
#include "impeller/base/strings.h"
#include "impeller/base/thread.h"

namespace impeller {
Expand Down Expand Up @@ -68,5 +69,12 @@ TEST(ThreadTest, CanCreateRWMutexLock) {
// f.mtx.UnlockReader(); <--- Static analysis error.
}

TEST(StringsTest, CanSPrintF) {
ASSERT_EQ(SPrintF("%sx%d", "Hello", 12), "Hellox12");
ASSERT_EQ(SPrintF(""), "");
ASSERT_EQ(SPrintF("Hello"), "Hello");
ASSERT_EQ(SPrintF("%sx%.2f", "Hello", 12.122222), "Hellox12.12");
}

} // namespace testing
} // namespace impeller
15 changes: 12 additions & 3 deletions impeller/base/strings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,21 @@ namespace impeller {

IMPELLER_PRINTF_FORMAT(1, 2)
std::string SPrintF(const char* format, ...) {
std::string ret_val;
va_list list;
va_list list2;
va_start(list, format);
char buffer[64] = {0};
::vsnprintf(buffer, sizeof(buffer), format, list);
va_copy(list2, list);
if (auto string_length = ::vsnprintf(nullptr, 0, format, list);
string_length >= 0) {
auto buffer = reinterpret_cast<char*>(::malloc(string_length + 1));
::vsnprintf(buffer, string_length + 1, format, list2);
ret_val = std::string{buffer, static_cast<size_t>(string_length)};
::free(buffer);
}
va_end(list2);
va_end(list);
return buffer;
return ret_val;
Comment on lines 12 to +27
Copy link
Member

Choose a reason for hiding this comment

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

I'll take your word for this.

Copy link
Member Author

Choose a reason for hiding this comment

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

Are you talking about the dubious var name?

}

bool HasPrefix(const std::string& string, const std::string& prefix) {
Expand Down
40 changes: 40 additions & 0 deletions impeller/core/formats.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,44 @@ std::string TextureUsageMaskToString(TextureUsageMask mask) {
return stream.str();
}

std::string AttachmentToString(const Attachment& attachment) {
std::stringstream stream;
if (attachment.texture) {
stream << "Texture=("
<< TextureDescriptorToString(
attachment.texture->GetTextureDescriptor())
<< "),";
}
if (attachment.resolve_texture) {
stream << "ResolveTexture=("
<< TextureDescriptorToString(
attachment.resolve_texture->GetTextureDescriptor())
<< "),";
}
stream << "LoadAction=" << LoadActionToString(attachment.load_action) << ",";
stream << "StoreAction=" << StoreActionToString(attachment.store_action);
return stream.str();
}

std::string ColorAttachmentToString(const ColorAttachment& color) {
std::stringstream stream;
stream << AttachmentToString(color) << ",";
stream << "ClearColor=(" << ColorToString(color.clear_color) << ")";
return stream.str();
}

std::string DepthAttachmentToString(const DepthAttachment& depth) {
std::stringstream stream;
stream << AttachmentToString(depth) << ",";
stream << "ClearDepth=" << SPrintF("%.2f", depth.clear_depth);
return stream.str();
}

std::string StencilAttachmentToString(const StencilAttachment& stencil) {
std::stringstream stream;
stream << AttachmentToString(stencil) << ",";
stream << "ClearStencil=" << stencil.clear_stencil;
return stream.str();
}

} // namespace impeller
68 changes: 68 additions & 0 deletions impeller/core/formats.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,42 @@ enum class PixelFormat {
kD32FloatS8UInt,
};

constexpr const char* PixelFormatToString(PixelFormat format) {
switch (format) {
case PixelFormat::kUnknown:
return "Unknown";
case PixelFormat::kA8UNormInt:
return "A8UNormInt";
case PixelFormat::kR8UNormInt:
return "R8UNormInt";
case PixelFormat::kR8G8UNormInt:
return "R8G8UNormInt";
case PixelFormat::kR8G8B8A8UNormInt:
return "R8G8B8A8UNormInt";
case PixelFormat::kR8G8B8A8UNormIntSRGB:
return "R8G8B8A8UNormIntSRGB";
case PixelFormat::kB8G8R8A8UNormInt:
return "B8G8R8A8UNormInt";
case PixelFormat::kB8G8R8A8UNormIntSRGB:
return "B8G8R8A8UNormIntSRGB";
case PixelFormat::kR32G32B32A32Float:
return "R32G32B32A32Float";
case PixelFormat::kR16G16B16A16Float:
return "R16G16B16A16Float";
case PixelFormat::kB10G10R10XR:
return "B10G10R10XR";
case PixelFormat::kB10G10R10XRSRGB:
return "B10G10R10XRSRGB";
case PixelFormat::kB10G10R10A10XR:
return "B10G10R10A10XR";
case PixelFormat::kS8UInt:
return "S8UInt";
case PixelFormat::kD32FloatS8UInt:
return "D32FloatS8UInt";
}
FML_UNREACHABLE();
}

enum class BlendFactor {
kZero,
kOne,
Expand Down Expand Up @@ -147,6 +183,30 @@ enum class StoreAction {
kStoreAndMultisampleResolve,
};

constexpr const char* LoadActionToString(LoadAction action) {
switch (action) {
case LoadAction::kDontCare:
return "DontCare";
case LoadAction::kLoad:
return "Load";
case LoadAction::kClear:
return "Clear";
}
}

constexpr const char* StoreActionToString(StoreAction action) {
switch (action) {
case StoreAction::kDontCare:
return "DontCare";
case StoreAction::kStore:
return "Store";
case StoreAction::kMultisampleResolve:
return "MultisampleResolve";
case StoreAction::kStoreAndMultisampleResolve:
return "StoreAndMultisampleResolve";
}
}

constexpr bool CanClearAttachment(LoadAction action) {
switch (action) {
case LoadAction::kLoad:
Expand Down Expand Up @@ -530,6 +590,14 @@ struct StencilAttachment : public Attachment {
uint32_t clear_stencil = 0;
};

std::string AttachmentToString(const Attachment& attachment);

std::string ColorAttachmentToString(const ColorAttachment& color);

std::string DepthAttachmentToString(const DepthAttachment& depth);

std::string StencilAttachmentToString(const StencilAttachment& stencil);

} // namespace impeller

namespace std {
Expand Down
14 changes: 13 additions & 1 deletion impeller/core/texture_descriptor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,20 @@

#include "impeller/core/texture_descriptor.h"

#include <sstream>

namespace impeller {

//
std::string TextureDescriptorToString(const TextureDescriptor& desc) {
std::stringstream stream;
stream << "StorageMode=" << StorageModeToString(desc.storage_mode) << ",";
stream << "Type=" << TextureTypeToString(desc.type) << ",";
stream << "Format=" << PixelFormatToString(desc.format) << ",";
stream << "Size=" << desc.size << ",";
stream << "MipCount=" << desc.mip_count << ",";
stream << "SampleCount=" << static_cast<size_t>(desc.sample_count) << ",";
stream << "Compression=" << CompressionTypeToString(desc.compression_type);
return stream.str();
}

} // namespace impeller
13 changes: 13 additions & 0 deletions impeller/core/texture_descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ enum class CompressionType {
kLossless,
kLossy,
};

constexpr const char* CompressionTypeToString(CompressionType type) {
switch (type) {
case CompressionType::kLossless:
return "Lossless";
case CompressionType::kLossy:
return "Lossy";
}
FML_UNREACHABLE();
}

//------------------------------------------------------------------------------
/// @brief A lightweight object that describes the attributes of a texture
/// that can then used an allocator to create that texture.
Expand Down Expand Up @@ -63,4 +74,6 @@ struct TextureDescriptor {
}
};

std::string TextureDescriptorToString(const TextureDescriptor& desc);

} // namespace impeller
5 changes: 4 additions & 1 deletion impeller/geometry/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ impeller_component("geometry") {
"vector.h",
]

deps = [ "//flutter/fml" ]
deps = [
"../base",
"//flutter/fml",
]
}

impeller_component("geometry_asserts") {
Expand Down
10 changes: 10 additions & 0 deletions impeller/geometry/color.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <cmath>
#include <sstream>

#include "impeller/base/strings.h"
#include "impeller/geometry/constants.h"
#include "impeller/geometry/scalar.h"
#include "impeller/geometry/vector.h"
Expand Down Expand Up @@ -360,4 +361,13 @@ Color Color::BlendColor(const Color& src,
}
}

std::string ColorToString(const Color& color) {
return SPrintF("R=%.1f,G=%.1f,B=%.1f,A=%.1f", //
color.red, //
color.green, //
color.blue, //
color.alpha //
);
}

} // namespace impeller
2 changes: 2 additions & 0 deletions impeller/geometry/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,8 @@ struct Color {
constexpr bool IsOpaque() const { return alpha == 1.0f; }
};

std::string ColorToString(const Color& color);

/**
* Represents a color by its constituent hue, saturation, brightness and alpha
*/
Expand Down
32 changes: 30 additions & 2 deletions impeller/renderer/render_target.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "impeller/renderer/render_target.h"

#include <sstream>

#include "impeller/base/strings.h"
#include "impeller/base/validation.h"
#include "impeller/core/allocator.h"
Expand Down Expand Up @@ -59,21 +61,27 @@ bool RenderTarget::IsValid() const {

if (texture_type != attachment.texture->GetTextureDescriptor().type) {
passes_type_validation = false;
VALIDATION_LOG << "Render target has incompatible texture types: "
<< TextureTypeToString(texture_type.value()) << " != "
<< TextureTypeToString(
attachment.texture->GetTextureDescriptor().type)
<< " on target " << ToString();
return false;
}

if (sample_count !=
attachment.texture->GetTextureDescriptor().sample_count) {
passes_type_validation = false;
VALIDATION_LOG << "Render target (" << ToString()
<< ") has incompatible sample counts.";

return false;
}

return true;
};
IterateAllAttachments(iterator);
if (!passes_type_validation) {
VALIDATION_LOG << "Render target texture types are not of the same type "
"and sample count.";
return false;
}
}
Expand Down Expand Up @@ -370,4 +378,24 @@ size_t RenderTarget::GetTotalAttachmentCount() const {
return count;
}

std::string RenderTarget::ToString() const {
std::stringstream stream;

for (const auto& [index, color] : colors_) {
stream << SPrintF("Color[%zu]=(%s)", index,
ColorAttachmentToString(color).c_str());
}
if (depth_) {
stream << ",";
stream << SPrintF("Depth=(%s)",
DepthAttachmentToString(depth_.value()).c_str());
}
if (stencil_) {
stream << ",";
stream << SPrintF("Stencil=(%s)",
StencilAttachmentToString(stencil_.value()).c_str());
}
return stream.str();
}

} // namespace impeller
2 changes: 2 additions & 0 deletions impeller/renderer/render_target.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ class RenderTarget final {
void IterateAllAttachments(
const std::function<bool(const Attachment& attachment)>& iterator) const;

std::string ToString() const;

private:
std::map<size_t, ColorAttachment> colors_;
std::optional<DepthAttachment> depth_;
Expand Down