diff --git a/fml/lightweight_string.h b/fml/lightweight_string.h new file mode 100644 index 0000000000000..b497d3e18f61e --- /dev/null +++ b/fml/lightweight_string.h @@ -0,0 +1,84 @@ +// 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. + +#ifndef FLUTTER_FML_LIGHTWEIGHT_STRING_H_ +#define FLUTTER_FML_LIGHTWEIGHT_STRING_H_ + +#include +#include +#include + +#include "flutter/fml/logging.h" +#include "flutter/fml/macros.h" + +namespace fml { + +/// An 16 byte string that does not copy string literals. +class LightweightString { + public: + LightweightString() { + str_.c = nullptr; + is_owned_ = false; + } + + LightweightString(const LightweightString& str) { + if (str.is_owned_) { + str_.c = strdup(str.str_.cc); + is_owned_ = true; + } else { + str_.cc = str.str_.cc; + is_owned_ = false; + } + } + + template + constexpr LightweightString(const char (&s)[N]) { + str_.cc = s; + is_owned_ = false; + } + + LightweightString(const std::string& str) { + str_.c = strdup(str.c_str()); + is_owned_ = true; + } + + ~LightweightString() { + if (is_owned_) { + free(str_.c); + } + } + + const char* c_str() const { return str_.cc; } + + bool empty() const { return str_.cc == nullptr; } + + LightweightString& operator=(const LightweightString& str) { + if (is_owned_) { + free(str_.c); + } + if (str.is_owned_) { + str_.c = strdup(str.str_.cc); + is_owned_ = true; + } else { + str_.cc = str.str_.cc; + is_owned_ = false; + } + return *this; + } + + private: + typedef union { + char* c; + const char* cc; + } StrPtr; + + StrPtr str_; + uint8_t is_owned_; +}; + +static_assert(sizeof(LightweightString) < sizeof(std::string)); + +} // namespace fml + +#endif // FLUTTER_FML_LIGHTWEIGHT_STRING_H_ diff --git a/impeller/entity/contents/texture_contents.cc b/impeller/entity/contents/texture_contents.cc index 1dbc8a5a2b50b..3c416f71d0d7b 100644 --- a/impeller/entity/contents/texture_contents.cc +++ b/impeller/entity/contents/texture_contents.cc @@ -138,9 +138,10 @@ bool TextureContents::Render(const ContentContext& renderer, frame_info.alpha = GetOpacity(); Command cmd; - cmd.label = "Texture Fill"; - if (!label_.empty()) { - cmd.label += ": " + label_; + if (label_.empty()) { + cmd.label = "Texture Fill"; + } else { + cmd.label = "Texture Fill: " + label_; } auto pipeline_options = OptionsFromPassAndEntity(pass, entity); diff --git a/impeller/entity/contents/tiled_texture_contents.cc b/impeller/entity/contents/tiled_texture_contents.cc index 8ef9b6d78cb99..30675aaaae04c 100644 --- a/impeller/entity/contents/tiled_texture_contents.cc +++ b/impeller/entity/contents/tiled_texture_contents.cc @@ -139,7 +139,11 @@ bool TiledTextureContents::Render(const ContentContext& renderer, frame_info.alpha = GetOpacityFactor(); Command cmd; - cmd.label = uses_emulated_tile_mode ? "TiledTextureFill" : "TextureFill"; + if (uses_emulated_tile_mode) { + cmd.label = "TiledTextureFill"; + } else { + cmd.label = "TextureFill"; + } cmd.stencil_reference = entity.GetStencilDepth(); auto options = OptionsFromPassAndEntity(pass, entity); diff --git a/impeller/renderer/backend/gles/render_pass_gles.cc b/impeller/renderer/backend/gles/render_pass_gles.cc index 2cdadb4fc3cd7..aedaf619dd717 100644 --- a/impeller/renderer/backend/gles/render_pass_gles.cc +++ b/impeller/renderer/backend/gles/render_pass_gles.cc @@ -247,7 +247,7 @@ struct RenderPassData { fml::ScopedCleanupClosure pop_cmd_debug_marker( [&gl]() { gl.PopDebugGroup(); }); if (!command.label.empty()) { - gl.PushDebugGroup(command.label); + gl.PushDebugGroup(command.label.c_str()); } else { pop_cmd_debug_marker.Release(); } diff --git a/impeller/renderer/command.h b/impeller/renderer/command.h index e44633f2365b7..de23bca60adff 100644 --- a/impeller/renderer/command.h +++ b/impeller/renderer/command.h @@ -9,6 +9,7 @@ #include #include +#include "flutter/fml/lightweight_string.h" #include "flutter/fml/logging.h" #include "flutter/fml/macros.h" #include "impeller/core/buffer_view.h" @@ -119,7 +120,7 @@ struct Command : public ResourceBinder { //---------------------------------------------------------------------------- /// The debugging label to use for the command. /// - std::string label; + fml::LightweightString label; //---------------------------------------------------------------------------- /// The reference value to use in stenciling operations. Stencil configuration /// is part of pipeline setup and can be read from the pipelines descriptor. @@ -205,4 +206,12 @@ struct Command : public ResourceBinder { const BufferView& view); }; +// Many Commands are allocated per frame so care should be taken when increasing +// their size. +#if defined(__SIZEOF_POINTER__) +#if __SIZEOF_POINTER__ == 8 +static_assert(sizeof(Command) == 432); +#endif +#endif + } // namespace impeller