9 #include "flutter/fml/mapping.h"
10 #include "flutter/testing/testing.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
16 #include "impeller/renderer/backend/gles/test/mock_gles.h"
27 using ::testing::NiceMock;
29 class ToggleWorker final :
public ReactorGLES::Worker {
31 explicit ToggleWorker(
bool allowed) : allowed_(allowed) {}
33 bool CanReactorReactOnCurrentThreadNow(
34 const ReactorGLES&
reactor)
const override {
35 return allowed_.load();
38 void SetAllowed(
bool allowed) { allowed_.store(allowed); }
41 std::atomic<bool> allowed_;
44 std::shared_ptr<ContextGLES> CreateFakeGLESContext() {
45 auto gl = std::make_unique<ProcTableGLES>(kMockResolverGLES);
47 std::vector<std::shared_ptr<fml::Mapping>>{},
54 SubmitWithoutCurrentContextIsAcceptedAndCompletesAfterReaction) {
55 auto mock_gles = MockGLES::Init();
56 auto context = CreateFakeGLESContext();
57 auto context_base = std::static_pointer_cast<Context>(
context);
58 auto worker = std::make_shared<ToggleWorker>(
false);
59 context->AddReactorWorker(worker);
64 bool callback_called =
false;
66 auto status = context_base->GetCommandQueue()->Submit(
68 callback_called =
true;
69 callback_status = status;
72 EXPECT_TRUE(status.ok());
73 EXPECT_FALSE(callback_called);
75 worker->SetAllowed(
true);
76 EXPECT_TRUE(
context->GetReactor()->React());
77 EXPECT_TRUE(callback_called);
82 auto mock_gles = MockGLES::Init();
83 auto context = CreateFakeGLESContext();
84 auto context_base = std::static_pointer_cast<Context>(
context);
85 auto worker = std::make_shared<ToggleWorker>(
false);
86 context->AddReactorWorker(worker);
91 EXPECT_TRUE(context_base->GetCommandQueue()->Submit({command_buffer}).ok());
95 bool callback_called =
false;
99 auto mock_gles = MockGLES::Init();
100 auto context = CreateFakeGLESContext();
101 auto context_base = std::static_pointer_cast<Context>(
context);
102 auto worker = std::make_shared<ToggleWorker>(
false);
103 context->AddReactorWorker(worker);
107 auto status = context_base->GetCommandQueue()->Submit(
109 callback_called =
true;
110 callback_status = status;
113 EXPECT_TRUE(status.ok());
114 EXPECT_FALSE(callback_called);
117 EXPECT_TRUE(callback_called);
122 auto mock_gles = MockGLES::Init();
123 auto context = CreateFakeGLESContext();
124 auto context_base = std::static_pointer_cast<Context>(
context);
125 auto worker = std::make_shared<ToggleWorker>(
false);
126 context->AddReactorWorker(worker);
128 std::vector<int> order;
129 ASSERT_TRUE(
context->GetReactor()->AddOperation(
135 auto status = context_base->GetCommandQueue()->Submit(
139 EXPECT_TRUE(status.ok());
140 EXPECT_TRUE(order.empty());
142 worker->SetAllowed(
true);
143 EXPECT_TRUE(
context->GetReactor()->React());
144 EXPECT_THAT(order, ::testing::ElementsAre(1, 2));
148 auto mock_gles = MockGLES::Init();
149 auto context = CreateFakeGLESContext();
150 auto context_base = std::static_pointer_cast<Context>(
context);
151 auto worker = std::make_shared<ToggleWorker>(
false);
152 context->AddReactorWorker(worker);
154 std::vector<int> order;
155 ASSERT_TRUE(
context->GetReactor()->AddOperation(
159 auto deferred_command_buffer = context_base->CreateCommandBuffer();
160 ASSERT_TRUE(deferred_command_buffer);
162 context_base->GetCommandQueue()->Submit({deferred_command_buffer}).ok());
163 EXPECT_TRUE(order.empty());
165 worker->SetAllowed(
true);
166 auto current_command_buffer = context_base->CreateCommandBuffer();
167 ASSERT_TRUE(current_command_buffer);
169 context_base->GetCommandQueue()
170 ->Submit({current_command_buffer},
173 EXPECT_THAT(order, ::testing::ElementsAre(1, 2));
177 auto mock_gles_impl = std::make_unique<NiceMock<MockGLESImpl>>();
178 auto& mock_gles_impl_ref = *mock_gles_impl;
179 auto mock_gles = MockGLES::Init(std::move(mock_gles_impl));
180 auto context = CreateFakeGLESContext();
181 auto context_base = std::static_pointer_cast<Context>(
context);
182 auto worker = std::make_shared<ToggleWorker>(
false);
183 context->AddReactorWorker(worker);
185 constexpr GLuint kTextureHandle = 1234;
186 bool texture_generated =
false;
187 bool texture_uploaded =
false;
188 EXPECT_CALL(mock_gles_impl_ref, GenTextures(1, _))
189 .WillOnce([&](GLsizei size, GLuint* textures) {
190 texture_generated =
true;
191 textures[0] = kTextureHandle;
193 EXPECT_CALL(mock_gles_impl_ref, BindTexture(GL_TEXTURE_2D, kTextureHandle))
194 .Times(::testing::AtLeast(1));
195 EXPECT_CALL(mock_gles_impl_ref,
196 TexImage2D(GL_TEXTURE_2D, 0, _, 2, 2, 0, _, _,
nullptr))
198 EXPECT_CALL(mock_gles_impl_ref,
199 TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, _, _, _))
200 .WillOnce([&](GLenum target, GLint level, GLint xoffset, GLint yoffset,
201 GLsizei width, GLsizei height, GLenum format, GLenum type,
202 const void* pixels) { texture_uploaded =
true; });
205 texture_descriptor.
size = {2, 2};
207 auto texture = context_base->GetResourceAllocator()->CreateTexture(
208 texture_descriptor,
true);
209 ASSERT_TRUE(texture);
211 const uint8_t pixels[16] = {};
213 context_base->GetResourceAllocator()->CreateBufferWithCopy(pixels, 16);
219 ASSERT_TRUE(blit_pass);
221 EXPECT_TRUE(blit_pass->AddCopy(
BufferView(buffer,
Range(0, 16)), texture,
223 "Deferred texture overwrite"));
224 EXPECT_TRUE(blit_pass->EncodeCommands());
225 EXPECT_TRUE(context_base->GetCommandQueue()->Submit({command_buffer}).ok());
226 EXPECT_FALSE(texture_generated);
227 EXPECT_FALSE(texture_uploaded);
229 worker->SetAllowed(
true);
230 EXPECT_TRUE(
context->GetReactor()->React());
231 EXPECT_TRUE(texture_generated);
232 EXPECT_TRUE(texture_uploaded);
static std::shared_ptr< ContextGLES > Create(const Flags &flags, std::unique_ptr< ProcTableGLES > gl, const std::vector< std::shared_ptr< fml::Mapping >> &shader_libraries, bool enable_gpu_tracing)
The reactor attempts to make thread-safe usage of OpenGL ES easier to reason about.
TEST(AllocationSizeTest, CanCreateTypedAllocations)
std::shared_ptr< ReactorGLES > reactor
std::shared_ptr< ContextGLES > context
std::shared_ptr< CommandBuffer > command_buffer
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...