Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
10410a2
Add io task runner to pipeline library gles.
xiaowei-guan Mar 13, 2026
6650c7a
Implement pipeline compile queue for gles
xiaowei-guan Mar 13, 2026
4c3a105
Fix build error
xiaowei-guan Mar 16, 2026
6539904
Add pipeline_compile_queue_vulkan.h
xiaowei-guan Mar 16, 2026
b7f9f28
Update GetPipeline method when sync == true
xiaowei-guan Mar 16, 2026
59c6773
Make link program after schedule frame on IO thread
xiaowei-guan Mar 27, 2026
fc6e3a6
Fix codereview issues
xiaowei-guan Apr 29, 2026
15f3251
Execute the compile job one by one; do not push all the tasks into th…
xiaowei-guan May 14, 2026
5434e6f
When executing an OpenGL job, you must wait for the previous job to f…
xiaowei-guan May 15, 2026
fa3cdc2
Remove empty line
xiaowei-guan May 15, 2026
751c330
Add a robust mutex-based synchronization pattern
xiaowei-guan May 21, 2026
6a1d9c7
Fix code review issues
xiaowei-guan May 21, 2026
2a8d812
Fix code review issues
xiaowei-guan May 21, 2026
4465367
Fix code review issues
xiaowei-guan May 22, 2026
c026698
Add check when creating PipelineCompileQueueGLES
xiaowei-guan May 25, 2026
fa86d60
Fix format issue
xiaowei-guan May 25, 2026
64d533d
Add UT test
xiaowei-guan May 29, 2026
dcf6915
Fix unit test issue
xiaowei-guan Jun 1, 2026
312d9d6
Add android part
xiaowei-guan Jun 1, 2026
20fd5fa
io task runner maybe null when call ContextGLES::Create
xiaowei-guan Jun 3, 2026
cd35071
Remove not used comments
xiaowei-guan Jun 4, 2026
226b234
Make PipelineCompileQueueVulkan PipelineCompileQueueGles constructor
xiaowei-guan Jun 4, 2026
54ddd8f
Fix build error
xiaowei-guan Jun 12, 2026
3f0cf4e
Remove redundant code
xiaowei-guan Jun 12, 2026
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 engine/src/flutter/impeller/renderer/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ template("renderer_unittests_component") {
"blit_pass_unittests.cc",
"capabilities_unittests.cc",
"device_buffer_unittests.cc",
"pipeline_compile_queue_unittests.cc",
"pipeline_descriptor_unittests.cc",
"pipeline_library_unittests.cc",
"pool_unittests.cc",
Expand Down
4 changes: 4 additions & 0 deletions engine/src/flutter/impeller/renderer/backend/gles/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ impeller_component("gles_unittests") {
"test/mock_gles.cc",
"test/mock_gles.h",
"test/mock_gles_unittests.cc",
"test/pipeline_compile_queue_gles_unittests.cc",
"test/pipeline_library_gles_unittests.cc",
"test/proc_table_gles_unittests.cc",
"test/reactor_unittests.cc",
Expand All @@ -34,6 +35,7 @@ impeller_component("gles_unittests") {
]
deps = [
":gles",
"//flutter/fml",
"//flutter/impeller/playground:playground_test",
"//flutter/testing:testing_lib",
]
Expand Down Expand Up @@ -68,6 +70,8 @@ impeller_component("gles") {
"gpu_tracer_gles.h",
"handle_gles.cc",
"handle_gles.h",
"pipeline_compile_queue_gles.cc",
"pipeline_compile_queue_gles.h",
"pipeline_gles.cc",
"pipeline_gles.h",
"pipeline_library_gles.cc",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,19 @@ std::shared_ptr<ContextGLES> ContextGLES::Create(
const Flags& flags,
std::unique_ptr<ProcTableGLES> gl,
const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries,
bool enable_gpu_tracing) {
return std::shared_ptr<ContextGLES>(new ContextGLES(
flags, std::move(gl), shader_libraries, enable_gpu_tracing));
bool enable_gpu_tracing,
fml::RefPtr<fml::TaskRunner> io_task_runner) {
return std::shared_ptr<ContextGLES>(
new ContextGLES(flags, std::move(gl), shader_libraries,
enable_gpu_tracing, std::move(io_task_runner)));
}

ContextGLES::ContextGLES(
const Flags& flags,
std::unique_ptr<ProcTableGLES> gl,
const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries_mappings,
bool enable_gpu_tracing)
bool enable_gpu_tracing,
fml::RefPtr<fml::TaskRunner> io_task_runner)
: Context(flags) {
reactor_ = std::make_shared<ReactorGLES>(std::move(gl));
if (!reactor_->IsValid()) {
Expand All @@ -52,8 +55,8 @@ ContextGLES::ContextGLES(

// Create the pipeline library.
{
pipeline_library_ =
std::shared_ptr<PipelineLibraryGLES>(new PipelineLibraryGLES(reactor_));
pipeline_library_ = std::shared_ptr<PipelineLibraryGLES>(
new PipelineLibraryGLES(reactor_, std::move(io_task_runner)));
}

// Create allocators.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ class ContextGLES final : public Context,
const Flags& flags,
std::unique_ptr<ProcTableGLES> gl,
const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries,
bool enable_gpu_tracing);
bool enable_gpu_tracing,
fml::RefPtr<fml::TaskRunner> io_task_runner = nullptr);

// |Context|
~ContextGLES() override;
Expand Down Expand Up @@ -64,7 +65,8 @@ class ContextGLES final : public Context,
const Flags& flags,
std::unique_ptr<ProcTableGLES> gl,
const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries,
bool enable_gpu_tracing);
bool enable_gpu_tracing,
fml::RefPtr<fml::TaskRunner> io_task_runner = nullptr);

// |Context|
std::string DescribeGpuModel() const override;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// 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.

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

#include "flutter/fml/logging.h"
#include "flutter/fml/trace_event.h"
#include "impeller/base/validation.h"

namespace impeller {

std::shared_ptr<PipelineCompileQueueGLES> PipelineCompileQueueGLES::Create(
fml::RefPtr<fml::TaskRunner> worker_task_runner) {
if (!worker_task_runner) {
return nullptr;
}
return std::shared_ptr<PipelineCompileQueueGLES>(
new PipelineCompileQueueGLES(std::move(worker_task_runner)));
}

PipelineCompileQueueGLES::PipelineCompileQueueGLES(
fml::RefPtr<fml::TaskRunner> worker_task_runner)
: worker_task_runner_(std::move(worker_task_runner)) {}

PipelineCompileQueueGLES::~PipelineCompileQueueGLES() = default;

void PipelineCompileQueueGLES::OnJobAdded() {
Lock lock(processing_mutex_);
if (!is_processing_) {
is_processing_ = true;
DrainPendingJobs();
}
}
Comment thread
xiaowei-guan marked this conversation as resolved.

void PipelineCompileQueueGLES::PostJob(const fml::closure& job) {
if (!job) {
return;
}

worker_task_runner_->PostTask(job);
}

void PipelineCompileQueueGLES::DrainPendingJobs() {
PostJob([weak_queue = weak_from_this()]() {
if (auto queue = std::static_pointer_cast<PipelineCompileQueueGLES>(
weak_queue.lock())) {
queue->DoOneJob();
{
Lock lock(queue->processing_mutex_);
if (!queue->HasPendingJobs()) {
queue->is_processing_ = false;
return;
}
}
queue->DrainPendingJobs();
}
});
}

} // namespace impeller
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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_IMPELLER_RENDERER_BACKEND_GLES_PIPELINE_COMPILE_QUEUE_GLES_H_
#define FLUTTER_IMPELLER_RENDERER_BACKEND_GLES_PIPELINE_COMPILE_QUEUE_GLES_H_

#include "flutter/fml/closure.h"
#include "flutter/fml/task_runner.h"
#include "impeller/base/thread.h"
#include "impeller/renderer/pipeline_compile_queue.h"

namespace impeller {

class PipelineCompileQueueGLES : public PipelineCompileQueue {
public:
static std::shared_ptr<PipelineCompileQueueGLES> Create(
fml::RefPtr<fml::TaskRunner> worker_task_runner);

~PipelineCompileQueueGLES() override;

PipelineCompileQueueGLES(const PipelineCompileQueueGLES&) = delete;

PipelineCompileQueueGLES& operator=(const PipelineCompileQueueGLES&) = delete;

void PostJob(const fml::closure& job) override;

void OnJobAdded() override;

private:
explicit PipelineCompileQueueGLES(
fml::RefPtr<fml::TaskRunner> worker_task_runner);
void DrainPendingJobs();

fml::RefPtr<fml::TaskRunner> worker_task_runner_;
Mutex processing_mutex_;
bool is_processing_ IPLR_GUARDED_BY(processing_mutex_) = false;
};

} // namespace impeller

#endif // FLUTTER_IMPELLER_RENDERER_BACKEND_GLES_PIPELINE_COMPILE_QUEUE_GLES_H_
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@

namespace impeller {

PipelineLibraryGLES::PipelineLibraryGLES(std::shared_ptr<ReactorGLES> reactor)
: reactor_(std::move(reactor)) {}
PipelineLibraryGLES::PipelineLibraryGLES(
std::shared_ptr<ReactorGLES> reactor,
fml::RefPtr<fml::TaskRunner> io_task_runner)
: reactor_(std::move(reactor)),
compile_queue_(
PipelineCompileQueueGLES::Create(std::move(io_task_runner))) {}

static std::string GetShaderInfoLog(const ProcTableGLES& gl, GLuint shader) {
GLint log_length = 0;
Expand Down Expand Up @@ -296,17 +300,34 @@ PipelineFuture<PipelineDescriptor> PipelineLibraryGLES::GetPipeline(
PipelineFuture<PipelineDescriptor>{descriptor, promise->get_future()};
pipelines_[descriptor] = pipeline_future;

const auto result = reactor_->AddOperation([promise, //
weak_this = weak_from_this(), //
descriptor, //
vert_function, //
frag_function, //
threadsafe //
](const ReactorGLES& reactor) {
promise->set_value(CreatePipeline(weak_this, descriptor, vert_function,
frag_function, threadsafe));
});
FML_CHECK(result);
auto weak_this = weak_from_this();
auto reactor = reactor_;
auto generation_task = [promise, weak_this, descriptor, vert_function,
frag_function, threadsafe, reactor]() {
auto thiz = weak_this.lock();
if (!thiz) {
promise->set_value(nullptr);
return;
}
const auto result = reactor->AddOperation([promise, //
weak_this, //
descriptor, //
vert_function, //
frag_function, //
threadsafe //
](const ReactorGLES& reactor) {
promise->set_value(CreatePipeline(weak_this, descriptor, vert_function,
frag_function, threadsafe));
});
FML_CHECK(result);
};

if (async && compile_queue_) {
compile_queue_->PostJobForDescriptor(descriptor,
std::move(generation_task));
} else {
generation_task();
}
Comment thread
xiaowei-guan marked this conversation as resolved.

return pipeline_future;
}
Expand Down Expand Up @@ -373,4 +394,8 @@ void PipelineLibraryGLES::SetProgramForKey(
programs_[key] = std::move(program);
}

PipelineCompileQueue* PipelineLibraryGLES::GetPipelineCompileQueue() const {
return compile_queue_.get();
}

} // namespace impeller
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
#include <vector>

#include "flutter/fml/hash_combine.h"
#include "flutter/fml/task_runner.h"
#include "impeller/base/thread.h"
#include "impeller/renderer/backend/gles/pipeline_compile_queue_gles.h"
#include "impeller/renderer/backend/gles/reactor_gles.h"
#include "impeller/renderer/backend/gles/unique_handle_gles.h"
#include "impeller/renderer/pipeline_library.h"
Expand Down Expand Up @@ -91,8 +93,10 @@ class PipelineLibraryGLES final
PipelineMap pipelines_;
Mutex programs_mutex_;
ProgramMap programs_ IPLR_GUARDED_BY(programs_mutex_);
std::shared_ptr<PipelineCompileQueueGLES> compile_queue_;

explicit PipelineLibraryGLES(std::shared_ptr<ReactorGLES> reactor);
explicit PipelineLibraryGLES(std::shared_ptr<ReactorGLES> reactor,
fml::RefPtr<fml::TaskRunner> io_task_runner);

// |PipelineLibrary|
bool IsValid() const override;
Expand Down Expand Up @@ -127,6 +131,8 @@ class PipelineLibraryGLES final

void SetProgramForKey(const ProgramKey& key,
std::shared_ptr<UniqueHandleGLES> program);
// |PipelineLibrary|
PipelineCompileQueue* GetPipelineCompileQueue() const override;
};

} // namespace impeller
Expand Down
Loading
Loading