5 #include <initializer_list>
8 #include "flutter/testing/testing.h"
9 #include "gtest/gtest.h"
13 #include "impeller/renderer/backend/gles/test/mock_gles.h"
20 using ::testing::Return;
44 const std::shared_ptr<ReactorGLES>&
reactor,
48 tex_desc.
size = {10, 10};
50 auto texture = std::make_shared<TextureGLES>(
reactor, tex_desc);
54 std::shared_ptr<DeviceBufferGLES> CreateBuffer(
55 const std::shared_ptr<ReactorGLES>&
reactor) {
56 DeviceBufferDescriptor buffer_desc;
57 buffer_desc.size = 10 * 10 * 4;
59 auto allocation = std::make_unique<Allocation>();
60 FML_CHECK(allocation->Truncate(Bytes(buffer_desc.size)));
61 auto buffer = std::make_shared<DeviceBufferGLES>(buffer_desc,
reactor,
62 std::move(allocation));
66 BlitCopyBufferToTextureCommandGLES CreateCopyBufferToTextureCommand(
67 const std::shared_ptr<DeviceBufferGLES>& source,
68 const std::shared_ptr<TextureGLES>& dest) {
69 BlitCopyBufferToTextureCommandGLES command;
71 command.destination = dest;
72 command.destination_region =
74 command.mip_level = 0;
76 command.label =
"TestBlit";
80 BlitCopyTextureToBufferCommandGLES CreateCopyTextureToBufferCommand(
81 const std::shared_ptr<TextureGLES>& source,
82 const std::shared_ptr<DeviceBufferGLES>& dest) {
83 BlitCopyTextureToBufferCommandGLES command;
84 command.source = source;
85 command.destination = dest;
86 command.source_region =
IRect::MakeSize(source->GetTextureDescriptor().size);
87 command.label =
"TestBlit";
93 TEST(BlitCommandGLESTest, BlitCopyBufferToTextureCommandGLESRGBA) {
94 auto mock_gles_impl = std::make_unique<MockGLESImpl>();
95 auto& mock_gles_impl_ref = *mock_gles_impl;
97 std::shared_ptr<MockGLES>
mock_gl = MockGLES::Init(std::move(mock_gles_impl));
98 auto reactor = std::make_shared<TestReactorGLES>();
99 auto worker = std::make_shared<MockWorker>();
103 std::shared_ptr<TextureGLES> dest_texture =
105 std::shared_ptr<DeviceBufferGLES> source_buffer = CreateBuffer(
reactor);
107 CreateCopyBufferToTextureCommand(source_buffer, dest_texture);
110 EXPECT_CALL(mock_gles_impl_ref,
111 TexSubImage2D(GL_TEXTURE_2D, _, _, _, _, _, GL_RGBA, _, _))
117 TEST(BlitCommandGLESTest, BlitCopyBufferToTextureCommandGLESBGRA) {
118 auto mock_gles_impl = std::make_unique<MockGLESImpl>();
119 auto& mock_gles_impl_ref = *mock_gles_impl;
122 std::shared_ptr<MockGLES>
mock_gl = MockGLES::Init(
123 std::move(mock_gles_impl),
124 std::vector<const char*>{
"GL_EXT_texture_format_BGRA8888"});
125 auto reactor = std::make_shared<TestReactorGLES>();
126 auto worker = std::make_shared<MockWorker>();
130 std::shared_ptr<TextureGLES> dest_texture =
132 std::shared_ptr<DeviceBufferGLES> source_buffer = CreateBuffer(
reactor);
134 CreateCopyBufferToTextureCommand(source_buffer, dest_texture);
137 EXPECT_CALL(mock_gles_impl_ref,
138 TexSubImage2D(GL_TEXTURE_2D, _, _, _, _, _, GL_BGRA_EXT, _, _))
146 TEST(BlitCommandGLESTest, BlitCopyTextureToBufferCommandGLESBindsFramebuffer) {
147 auto mock_gles_impl = std::make_unique<MockGLESImpl>();
148 auto& mock_gles_impl_ref = *mock_gles_impl;
150 EXPECT_CALL(mock_gles_impl_ref, GenFramebuffers(1, _))
151 .WillOnce(::testing::SetArgPointee<1>(3));
152 EXPECT_CALL(mock_gles_impl_ref, GenTextures(1, _))
153 .WillOnce(::testing::SetArgPointee<1>(1));
154 EXPECT_CALL(mock_gles_impl_ref, BindFramebuffer(GL_FRAMEBUFFER, 3)).Times(1);
155 EXPECT_CALL(mock_gles_impl_ref, CheckFramebufferStatus(GL_FRAMEBUFFER))
156 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE));
157 EXPECT_CALL(mock_gles_impl_ref, ReadPixels(_, _, _, _, _, _, _)).Times(1);
158 EXPECT_CALL(mock_gles_impl_ref, BindFramebuffer(GL_FRAMEBUFFER, 0)).Times(1);
160 std::shared_ptr<MockGLES>
mock_gl = MockGLES::Init(std::move(mock_gles_impl));
161 auto reactor = std::make_shared<TestReactorGLES>();
162 auto worker = std::make_shared<MockWorker>();
165 std::shared_ptr<TextureGLES> source_texture =
167 std::shared_ptr<DeviceBufferGLES> dest_buffer = CreateBuffer(
reactor);
172 CreateCopyTextureToBufferCommand(source_texture, dest_buffer);
176 source_texture.reset();
182 TEST(BlitCommandGLESTest, BlitCopyTextureToBufferCommandGLESRGBA) {
183 auto mock_gles_impl = std::make_unique<MockGLESImpl>();
184 auto& mock_gles_impl_ref = *mock_gles_impl;
186 std::shared_ptr<MockGLES>
mock_gl = MockGLES::Init(std::move(mock_gles_impl));
187 auto reactor = std::make_shared<TestReactorGLES>();
188 auto worker = std::make_shared<MockWorker>();
192 std::shared_ptr<TextureGLES> source_texture =
194 std::shared_ptr<DeviceBufferGLES> dest_buffer = CreateBuffer(
reactor);
196 CreateCopyTextureToBufferCommand(source_texture, dest_buffer);
198 EXPECT_CALL(mock_gles_impl_ref, CheckFramebufferStatus(_))
199 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE));
201 EXPECT_CALL(mock_gles_impl_ref, ReadPixels(_, _, _, _, GL_RGBA, _, _))
207 TEST(BlitCommandGLESTest, BlitCopyTextureToBufferCommandGLESBGRA) {
208 auto mock_gles_impl = std::make_unique<MockGLESImpl>();
209 auto& mock_gles_impl_ref = *mock_gles_impl;
212 std::shared_ptr<MockGLES>
mock_gl = MockGLES::Init(
213 std::move(mock_gles_impl),
214 std::vector<const char*>{
"GL_EXT_texture_format_BGRA8888"});
215 auto reactor = std::make_shared<TestReactorGLES>();
216 auto worker = std::make_shared<MockWorker>();
220 std::shared_ptr<TextureGLES> source_texture =
222 std::shared_ptr<DeviceBufferGLES> dest_buffer = CreateBuffer(
reactor);
224 CreateCopyTextureToBufferCommand(source_texture, dest_buffer);
226 EXPECT_CALL(mock_gles_impl_ref, CheckFramebufferStatus(_))
227 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE));
229 EXPECT_CALL(mock_gles_impl_ref, ReadPixels(_, _, _, _, GL_BGRA_EXT, _, _))
236 BlitCopyTextureToBufferCommandGLESUnsupportedPixelFormats) {
237 auto mock_gles_impl = std::make_unique<MockGLESImpl>();
238 auto& mock_gles_impl_ref = *mock_gles_impl;
240 std::shared_ptr<MockGLES>
mock_gl = MockGLES::Init(std::move(mock_gles_impl));
241 auto reactor = std::make_shared<TestReactorGLES>();
242 auto worker = std::make_shared<MockWorker>();
245 std::shared_ptr<DeviceBufferGLES> dest_buffer = CreateBuffer(
reactor);
247 std::shared_ptr<TextureGLES> source_texture_D32FloatS8Uint =
250 CreateCopyTextureToBufferCommand(source_texture_D32FloatS8Uint,
253 std::shared_ptr<TextureGLES> source_texture_R8G8UNormInt =
256 CreateCopyTextureToBufferCommand(source_texture_R8G8UNormInt,
259 EXPECT_CALL(mock_gles_impl_ref, CheckFramebufferStatus(_)).Times(0);
270 std::shared_ptr<TextureGLES> CreateMipTexture(
271 const std::shared_ptr<ReactorGLES>&
reactor,
278 tex_desc.
size = size;
280 tex_desc.
type = type;
282 auto texture = std::make_shared<TextureGLES>(
reactor, tex_desc);
286 std::shared_ptr<DeviceBufferGLES> CreateMipBuffer(
287 const std::shared_ptr<ReactorGLES>&
reactor,
289 DeviceBufferDescriptor buffer_desc;
290 buffer_desc.size = size_bytes;
292 auto allocation = std::make_unique<Allocation>();
293 FML_CHECK(allocation->Truncate(Bytes(buffer_desc.size)));
294 return std::make_shared<DeviceBufferGLES>(buffer_desc,
reactor,
295 std::move(allocation));
304 BlitCopyBufferToTextureCommandAllocatesOnlyTheRequestedBaseMip) {
305 auto mock_gles_impl = std::make_unique<MockGLESImpl>();
306 auto& mock_gles_impl_ref = *mock_gles_impl;
307 std::shared_ptr<MockGLES>
mock_gl = MockGLES::Init(std::move(mock_gles_impl));
308 auto reactor = std::make_shared<TestReactorGLES>();
309 auto worker = std::make_shared<MockWorker>();
314 auto source = CreateMipBuffer(
reactor, 8 * 8 * 4);
322 command.
label =
"TestBlit";
324 EXPECT_CALL(mock_gles_impl_ref,
325 TexImage2D(GL_TEXTURE_2D, 0, _, 8, 8, _, _, _,
nullptr))
328 EXPECT_CALL(mock_gles_impl_ref,
329 TexImage2D(GL_TEXTURE_2D, 1, _, _, _, _, _, _,
nullptr))
331 EXPECT_CALL(mock_gles_impl_ref,
332 TexImage2D(GL_TEXTURE_2D, 2, _, _, _, _, _, _,
nullptr))
334 EXPECT_CALL(mock_gles_impl_ref,
335 TexSubImage2D(GL_TEXTURE_2D, 0, _, _, 8, 8, _, _, _))
347 BlitCopyBufferToTextureCommandAllocatesNonZeroMipLevelOnFirstUpload) {
348 auto mock_gles_impl = std::make_unique<MockGLESImpl>();
349 auto& mock_gles_impl_ref = *mock_gles_impl;
350 std::shared_ptr<MockGLES>
mock_gl = MockGLES::Init(std::move(mock_gles_impl));
351 auto reactor = std::make_shared<TestReactorGLES>();
352 auto worker = std::make_shared<MockWorker>();
357 auto source = CreateMipBuffer(
reactor, 4 * 4 * 4);
365 command.
label =
"TestBlit";
368 EXPECT_CALL(mock_gles_impl_ref,
369 TexImage2D(GL_TEXTURE_2D, 1, _, 4, 4, _, _, _,
nullptr))
371 EXPECT_CALL(mock_gles_impl_ref,
372 TexImage2D(GL_TEXTURE_2D, 0, _, _, _, _, _, _,
nullptr))
374 EXPECT_CALL(mock_gles_impl_ref,
375 TexImage2D(GL_TEXTURE_2D, 2, _, _, _, _, _, _,
nullptr))
377 EXPECT_CALL(mock_gles_impl_ref,
378 TexSubImage2D(GL_TEXTURE_2D, 1, _, _, 4, 4, _, _, _))
390 BlitCopyBufferToTextureCommandAllocatesEachMipLevelOnFirstWrite) {
391 auto mock_gles_impl = std::make_unique<MockGLESImpl>();
392 auto& mock_gles_impl_ref = *mock_gles_impl;
393 std::shared_ptr<MockGLES>
mock_gl = MockGLES::Init(std::move(mock_gles_impl));
394 auto reactor = std::make_shared<TestReactorGLES>();
395 auto worker = std::make_shared<MockWorker>();
402 auto source0 = CreateMipBuffer(
reactor, 8 * 8 * 4);
403 auto source1 = CreateMipBuffer(
reactor, 4 * 4 * 4);
404 auto source2 = CreateMipBuffer(
reactor, 2 * 2 * 4);
406 EXPECT_CALL(mock_gles_impl_ref,
407 TexImage2D(GL_TEXTURE_2D, 0, _, 8, 8, _, _, _,
nullptr))
409 EXPECT_CALL(mock_gles_impl_ref,
410 TexImage2D(GL_TEXTURE_2D, 1, _, 4, 4, _, _, _,
nullptr))
412 EXPECT_CALL(mock_gles_impl_ref,
413 TexImage2D(GL_TEXTURE_2D, 2, _, 2, 2, _, _, _,
nullptr))
415 EXPECT_CALL(mock_gles_impl_ref,
416 TexSubImage2D(GL_TEXTURE_2D, 0, _, _, 8, 8, _, _, _))
418 EXPECT_CALL(mock_gles_impl_ref,
419 TexSubImage2D(GL_TEXTURE_2D, 1, _, _, 4, 4, _, _, _))
421 EXPECT_CALL(mock_gles_impl_ref,
422 TexSubImage2D(GL_TEXTURE_2D, 2, _, _, 2, 2, _, _, _))
425 for (
const auto& [level, w, source] : std::initializer_list<
426 std::tuple<uint32_t, int32_t, std::shared_ptr<DeviceBufferGLES>>>{
427 {0, 8, source0}, {1, 4, source1}, {2, 2, source2}}) {
434 command.
label =
"TestBlit";
442 BlitCopyBufferToTextureCommandDoesNotReallocateOnSubsequentUpload) {
443 auto mock_gles_impl = std::make_unique<MockGLESImpl>();
444 auto& mock_gles_impl_ref = *mock_gles_impl;
445 std::shared_ptr<MockGLES>
mock_gl = MockGLES::Init(std::move(mock_gles_impl));
446 auto reactor = std::make_shared<TestReactorGLES>();
447 auto worker = std::make_shared<MockWorker>();
452 auto source = CreateMipBuffer(
reactor, 4 * 4 * 4);
460 command.
label =
"TestBlit";
463 EXPECT_CALL(mock_gles_impl_ref,
464 TexImage2D(GL_TEXTURE_2D, 0, _, 4, 4, _, _, _,
nullptr))
466 EXPECT_CALL(mock_gles_impl_ref,
467 TexImage2D(GL_TEXTURE_2D, 1, _, _, _, _, _, _,
nullptr))
469 EXPECT_CALL(mock_gles_impl_ref,
470 TexSubImage2D(GL_TEXTURE_2D, 0, _, _, _, _, _, _, _))
482 BlitCopyBufferToTextureCommandUsesCubemapFaceTargetForCubemap) {
483 auto mock_gles_impl = std::make_unique<MockGLESImpl>();
484 auto& mock_gles_impl_ref = *mock_gles_impl;
485 std::shared_ptr<MockGLES>
mock_gl = MockGLES::Init(std::move(mock_gles_impl));
486 auto reactor = std::make_shared<TestReactorGLES>();
487 auto worker = std::make_shared<MockWorker>();
493 auto source = CreateMipBuffer(
reactor, 4 * 4 * 4);
501 command.
label =
"TestBlit";
503 const GLenum face_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + 2;
507 EXPECT_CALL(mock_gles_impl_ref, BindTexture(GL_TEXTURE_CUBE_MAP, _)).Times(1);
508 EXPECT_CALL(mock_gles_impl_ref,
509 TexImage2D(face_target, 0, _, 4, 4, _, _, _,
nullptr))
512 EXPECT_CALL(mock_gles_impl_ref,
513 TexImage2D(face_target, 1, _, _, _, _, _, _,
nullptr))
516 EXPECT_CALL(mock_gles_impl_ref, TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, _,
517 _, _, _, _, _, _,
nullptr))
519 EXPECT_CALL(mock_gles_impl_ref,
520 TexImage2D(GL_TEXTURE_2D, _, _, _, _, _, _, _,
nullptr))
522 EXPECT_CALL(mock_gles_impl_ref,
523 TexSubImage2D(face_target, 0, _, _, 4, 4, _, _, _))
static BufferView AsBufferView(std::shared_ptr< DeviceBuffer > buffer)
Create a buffer view of this entire buffer.
A delegate implemented by a thread on which an OpenGL context is current. There may be multiple worke...
The reactor attempts to make thread-safe usage of OpenGL ES easier to reason about.
bool CanReactorReactOnCurrentThreadNow(const ReactorGLES &reactor) const override
Determines the ability of the worker to service a reaction on the current thread. The OpenGL context ...
~TestReactorGLES()=default
TEST(AllocationSizeTest, CanCreateTypedAllocations)
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Mask< TextureUsage > TextureUsageMask
std::shared_ptr< Texture > CreateTexture(const TextureDescriptor &texture_descriptor, const std::vector< uint8_t > &data, const std::shared_ptr< impeller::Context > &context, std::string_view debug_label)
std::shared_ptr< ReactorGLES > reactor
std::shared_ptr< MockGLES > mock_gl
bool Encode(const ReactorGLES &reactor) const override
std::shared_ptr< Texture > destination
bool Encode(const ReactorGLES &reactor) const override
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
constexpr static TRect MakeSize(const TSize< U > &size)
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...