Flutter Impeller
device_buffer_gles_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/testing/testing.h" // IWYU pragma: keep
6 #include "gtest/gtest.h"
8 #include "impeller/renderer/backend/gles/test/mock_gles.h"
9 
10 namespace impeller {
11 namespace testing {
12 
13 using ::testing::_;
14 
15 namespace {
16 class TestWorker : public ReactorGLES::Worker {
17  public:
18  bool CanReactorReactOnCurrentThreadNow(
19  const ReactorGLES& reactor) const override {
20  return true;
21  }
22 };
23 } // namespace
24 
25 // A Flush() that lands while BindAndUploadDataIfNecessary is mid-upload (as
26 // happens when another thread writes to a host-visible buffer during the GL
27 // upload) must not be discarded; the next bind must upload the new range.
28 TEST(DeviceBufferGLESTest, FlushDuringUploadIsNotDiscarded) {
29  auto mock_gles_impl = std::make_unique<MockGLESImpl>();
30 
31  DeviceBufferGLES* device_buffer_ptr = nullptr;
32  int upload_count = 0;
33  EXPECT_CALL(*mock_gles_impl, BufferSubData(_, _, _, _))
34  .Times(2)
35  .WillRepeatedly([&](GLenum target, GLintptr offset, GLsizeiptr size,
36  const void* data) {
37  ++upload_count;
38  if (upload_count == 1) {
39  // Simulates a writer thread flushing new data during the upload.
40  device_buffer_ptr->Flush(Range{0, 4});
41  }
42  });
43 
44  std::shared_ptr<MockGLES> mock_gles =
45  MockGLES::Init(std::move(mock_gles_impl));
46  ProcTableGLES::Resolver resolver = kMockResolverGLES;
47  auto proc_table = std::make_unique<ProcTableGLES>(resolver);
48  auto worker = std::make_shared<TestWorker>();
49  auto reactor = std::make_shared<ReactorGLES>(std::move(proc_table));
50  reactor->AddWorker(worker);
51 
52  auto backing_store = std::make_unique<Allocation>();
53  ASSERT_TRUE(backing_store->Truncate(Bytes{16}));
55  std::move(backing_store));
56  device_buffer_ptr = &device_buffer;
57 
58  device_buffer.Flush(Range{0, 4});
59  // First bind uploads the flushed range; the mock flushes again mid-upload.
60  EXPECT_TRUE(device_buffer.BindAndUploadDataIfNecessary(
62  // Second bind must see the mid-upload flush and upload again.
63  EXPECT_TRUE(device_buffer.BindAndUploadDataIfNecessary(
65  EXPECT_EQ(upload_count, 2);
66 }
67 
68 TEST(DeviceBufferGLESTest, BindUniformData) {
69  auto mock_gles_impl = std::make_unique<MockGLESImpl>();
70 
71  EXPECT_CALL(*mock_gles_impl, GenBuffers(1, _)).Times(1);
72 
73  std::shared_ptr<MockGLES> mock_gled =
74  MockGLES::Init(std::move(mock_gles_impl));
75  ProcTableGLES::Resolver resolver = kMockResolverGLES;
76  auto proc_table = std::make_unique<ProcTableGLES>(resolver);
77  auto worker = std::make_shared<TestWorker>();
78  auto reactor = std::make_shared<ReactorGLES>(std::move(proc_table));
79  reactor->AddWorker(worker);
80 
81  auto backing_store = std::make_unique<Allocation>();
82  ASSERT_TRUE(backing_store->Truncate(Bytes{sizeof(float)}));
83  DeviceBufferGLES device_buffer(DeviceBufferDescriptor{.size = sizeof(float)},
84  reactor, std::move(backing_store));
85  EXPECT_FALSE(device_buffer.GetHandle().has_value());
86  EXPECT_TRUE(device_buffer.BindAndUploadDataIfNecessary(
88  EXPECT_TRUE(device_buffer.GetHandle().has_value());
89 }
90 
91 } // namespace testing
92 } // namespace impeller
void Flush(std::optional< Range > range=std::nullopt) const override
std::function< void *(const char *function_name)> Resolver
TEST(AllocationSizeTest, CanCreateTypedAllocations)
std::shared_ptr< ReactorGLES > reactor