diff --git a/impeller/renderer/backend/gles/proc_table_gles.cc b/impeller/renderer/backend/gles/proc_table_gles.cc index 3e9d7d70e7b43..ee4af806d244e 100644 --- a/impeller/renderer/backend/gles/proc_table_gles.cc +++ b/impeller/renderer/backend/gles/proc_table_gles.cc @@ -140,6 +140,10 @@ ProcTableGLES::ProcTableGLES( // NOLINT(google-readability-function-size) capabilities_ = std::make_shared(*this); + // This this will force glUseProgram to only be used on one thread in debug + // builds to identify threading violations in the engine. + UseProgram.enforce_one_thread = true; + is_valid_ = true; } diff --git a/impeller/renderer/backend/gles/proc_table_gles.h b/impeller/renderer/backend/gles/proc_table_gles.h index eadcb4f333057..5cbe7db89c6b6 100644 --- a/impeller/renderer/backend/gles/proc_table_gles.h +++ b/impeller/renderer/backend/gles/proc_table_gles.h @@ -6,7 +6,9 @@ #define FLUTTER_IMPELLER_RENDERER_BACKEND_GLES_PROC_TABLE_GLES_H_ #include +#include #include +#include #include "flutter/fml/logging.h" #include "flutter/fml/mapping.h" @@ -99,6 +101,14 @@ struct GLProc { /// bool log_calls = false; + //---------------------------------------------------------------------------- + /// Whether the OpenGL call asserts it is only used from / one thread in + /// IMPELLER_DEBUG builds. + /// + /// This is used to block drawing calls from happening anywhere but the raster + /// thread. + bool enforce_one_thread = false; + //---------------------------------------------------------------------------- /// @brief Call the GL function with the appropriate parameters. Lookup /// the documentation for the GL function being called to @@ -118,6 +128,16 @@ struct GLProc { FML_LOG(IMPORTANT) << name << BuildGLArguments(std::forward(args)...); } + if (enforce_one_thread) { + static std::thread::id allowed_thread; + static std::once_flag flag; + std::call_once(flag, + []() { allowed_thread = std::this_thread::get_id(); }); + FML_CHECK(std::this_thread::get_id() == allowed_thread) + << "This symbol is expected to be called from one thread, the raster " + "thread. As of this addition, the design of the engine should be " + "using non-raster threads only for uploading images."; + } #endif // defined(IMPELLER_DEBUG) && !defined(NDEBUG) return function(std::forward(args)...); }