Flutter Impeller
playground_test.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 
6 
8 
9 #if IMPELLER_ENABLE_METAL
12 #endif // IMPELLER_ENABLE_METAL
13 
14 #if IMPELLER_ENABLE_OPENGLES
17 #endif // IMPELLER_ENABLE_METAL
18 
19 #if IMPELLER_ENABLE_VULKAN
22 #endif // IMPELLER_ENABLE_VULKAN
23 
24 namespace IMPELLER_HPP_NAMESPACE {
26 } // namespace IMPELLER_HPP_NAMESPACE
27 
29 
31  static std::once_flag sOnceFlag;
32  std::call_once(sOnceFlag, []() {
33  std::map<std::string, void*> proc_map;
34 #define IMPELLER_HPP_PROC(name) \
35  proc_map[#name] = reinterpret_cast<void*>(&name);
37 #undef IMPELLER_HPP_PROC
39  [&](auto name) { return proc_map.at(name); });
40  });
41 }
42 
45 }
46 
48 
49 // |PlaygroundTest|
52 }
53 
54 // |PlaygroundTest|
57 }
58 
60  switch (GetBackend()) {
63  return Adopt<Context>(
66  Playground::GLProcAddressResolver playground_gl_proc_address_callback =
68  ImpellerProcAddressCallback gl_proc_address_callback =
69  [](const char* proc_name, void* user_data) -> void* {
70  return (*reinterpret_cast<Playground::GLProcAddressResolver*>(
71  user_data))(proc_name);
72  };
73  return Adopt<Context>(ImpellerContextCreateOpenGLESNew(
74  ImpellerGetVersion(), gl_proc_address_callback,
75  &playground_gl_proc_address_callback));
76  }
78  ImpellerContextVulkanSettings settings = {};
79  struct UserData {
81  } user_data;
82  user_data.resolver = CreateVKProcAddressResolver();
83  settings.user_data = &user_data;
85  settings.proc_address_callback = [](void* instance, //
86  const char* proc_name, //
87  void* user_data //
88  ) -> void* {
89  auto resolver = reinterpret_cast<UserData*>(user_data)->resolver;
90  if (resolver) {
91  return resolver(instance, proc_name);
92  } else {
93  return nullptr;
94  }
95  };
96  return Adopt<Context>(
98  }
99  FML_UNREACHABLE();
100 }
101 
103  PlaygroundBackend backend,
104  Context& context,
105  std::shared_ptr<impeller::Surface> shared_surface) {
106  switch (backend) {
107 #if IMPELLER_ENABLE_METAL
110  return Adopt<Surface>(new SurfaceMTL(context, std::move(shared_surface)));
111 #endif
112 
113 #if IMPELLER_ENABLE_OPENGLES
115  return Adopt<Surface>(
116  new SurfaceGLES(context, std::move(shared_surface)));
117 #endif
118 
119 #if IMPELLER_ENABLE_VULKAN
121  return Adopt<Surface>(new SurfaceVK(context, std::move(shared_surface)));
122 #endif
123  default:
124  return nullptr;
125  }
126  FML_UNREACHABLE();
127 }
128 
130  auto interop_context = GetInteropContext();
131  if (!interop_context) {
132  return false;
133  }
134  return Playground::OpenPlaygroundHere([&](RenderTarget& target) -> bool {
135  auto impeller_surface = std::make_shared<impeller::Surface>(target);
136  auto surface = CreateSharedSurface(GetBackend(), //
137  *interop_context.Get(), //
138  std::move(impeller_surface) //
139  );
140  if (!surface) {
141  VALIDATION_LOG << "Could not wrap test surface as an interop surface.";
142  return false;
143  }
144  return callback(interop_context, surface);
145  });
146 }
147 
149  PlaygroundBackend backend,
150  std::shared_ptr<impeller::Context> shared_context) {
151  switch (backend) {
152 #if IMPELLER_ENABLE_METAL
155  return ContextMTL::Create(shared_context);
156 #endif
157 #if IMPELLER_ENABLE_OPENGLES
159  return ContextGLES::Create(std::move(shared_context));
160 #endif
161 #if IMPELLER_ENABLE_VULKAN
163  return ContextVK::Create(std::move(shared_context));
164 #endif
165  default:
166  return nullptr;
167  }
168  FML_UNREACHABLE();
169 }
170 
172  if (interop_context_) {
173  return interop_context_;
174  }
175 
176  auto context = CreateSharedContext(GetBackend(), GetContext());
177  if (!context) {
178  return nullptr;
179  }
180  interop_context_ = std::move(context);
181  return interop_context_;
182 }
183 
185  auto c_context = GetInteropContext().GetC();
186  ImpellerContextRetain(c_context);
187  return hpp::Context{c_context, hpp::AdoptTag::kAdopt};
188 }
189 
190 std::unique_ptr<hpp::Mapping> PlaygroundTest::OpenAssetAsHPPMapping(
191  std::string asset_name) const {
192  std::shared_ptr<fml::Mapping> data =
193  OpenAssetAsMapping(std::move(asset_name));
194  if (!data) {
195  return nullptr;
196  }
197  return std::make_unique<hpp::Mapping>(data->GetMapping(), //
198  data->GetSize(), //
199  [data]() {} //
200  );
201 }
202 
203 hpp::Texture PlaygroundTest::OpenAssetAsHPPTexture(std::string asset_name) {
204  auto compressed_data = OpenAssetAsMapping(std::move(asset_name));
205  if (!compressed_data) {
206  return {nullptr, hpp::AdoptTag::kAdopt};
207  }
208  auto compressed_image =
209  LoadFixtureImageCompressed(std::move(compressed_data));
210  if (!compressed_image) {
211  return {nullptr, hpp::AdoptTag::kAdopt};
212  }
213  auto decompressed_image = DecodeImageRGBA(compressed_image);
214  if (!decompressed_image.has_value()) {
215  return {nullptr, hpp::AdoptTag::kAdopt};
216  }
217  auto rgba_decompressed_image =
218  std::make_shared<DecompressedImage>(decompressed_image->ConvertToRGBA());
219  if (!rgba_decompressed_image || !rgba_decompressed_image->IsValid()) {
220  return {nullptr, hpp::AdoptTag::kAdopt};
221  }
222  auto context = GetHPPContext();
223  if (!context) {
224  return {nullptr, hpp::AdoptTag::kAdopt};
225  }
226 
227  auto rgba_mapping = std::make_unique<hpp::Mapping>(
228  rgba_decompressed_image->GetAllocation()->GetMapping(),
229  rgba_decompressed_image->GetAllocation()->GetSize(),
230  [rgba_decompressed_image]() {});
231 
232  return hpp::Texture::WithContents(
233  context,
236  .size = {rgba_decompressed_image->GetSize().width,
237  rgba_decompressed_image->GetSize().height},
238  .mip_count = 1u,
239  },
240  std::move(rgba_mapping));
241 }
242 
243 } // namespace impeller::interop::testing
bool OpenPlaygroundHere(const RenderCallback &render_callback)
Definition: playground.cc:205
static std::shared_ptr< CompressedImage > LoadFixtureImageCompressed(std::shared_ptr< fml::Mapping > mapping)
Definition: playground.cc:365
GLProcAddressResolver CreateGLProcAddressResolver() const
Definition: playground.cc:524
const PlaygroundSwitches switches_
Definition: playground.h:120
std::shared_ptr< Context > GetContext() const
Definition: playground.cc:94
std::function< void *(void *instance, const char *proc_name)> VKProcAddressResolver
Definition: playground.h:109
std::function< void *(const char *proc_name)> GLProcAddressResolver
Definition: playground.h:105
static std::optional< DecompressedImage > DecodeImageRGBA(const std::shared_ptr< CompressedImage > &compressed)
Definition: playground.cc:376
VKProcAddressResolver CreateVKProcAddressResolver() const
Definition: playground.cc:529
std::unique_ptr< fml::Mapping > OpenAssetAsMapping(std::string asset_name) const override
PlaygroundBackend GetBackend() const
static ScopedObject< Context > Create(std::function< void *(const char *gl_proc_name)> proc_address_callback)
Definition: context_gles.cc:14
static ScopedObject< Context > Create()
Definition: context_mtl.mm:29
static ScopedObject< Context > Create(const Settings &settings)
Definition: context_vk.cc:44
hpp::Texture OpenAssetAsHPPTexture(std::string asset_name)
ScopedObject< Context > CreateContext() const
std::unique_ptr< hpp::Mapping > OpenAssetAsHPPMapping(std::string asset_name) const
std::function< bool(const ScopedObject< Context > &context, const ScopedObject< Surface > &surface)> InteropPlaygroundCallback
bool OpenPlaygroundHere(InteropPlaygroundCallback callback)
void *IMPELLER_NULLABLE(* ImpellerProcAddressCallback)(const char *IMPELLER_NONNULL proc_name, void *IMPELLER_NULLABLE user_data)
Definition: impeller.h:347
@ kImpellerPixelFormatRGBA8888
Definition: impeller.h:425
#define IMPELLER_HPP_EACH_PROC(PROC)
Definition: impeller.hpp:48
static ScopedObject< Context > CreateSharedContext(PlaygroundBackend backend, std::shared_ptr< impeller::Context > shared_context)
static ScopedObject< Surface > CreateSharedSurface(PlaygroundBackend backend, Context &context, std::shared_ptr< impeller::Surface > shared_surface)
static void SetupImpellerHPPProcTableOnce()
IMPELLER_EXTERN_C uint32_t ImpellerGetVersion()
Definition: impeller.cc:92
IMPELLER_EXTERN_C ImpellerContext ImpellerContextCreateVulkanNew(uint32_t version, const ImpellerContextVulkanSettings *settings)
Definition: impeller.cc:152
IMPELLER_EXTERN_C ImpellerContext ImpellerContextCreateMetalNew(uint32_t version)
Definition: impeller.cc:134
IMPELLER_EXTERN_C ImpellerContext ImpellerContextCreateOpenGLESNew(uint32_t version, ImpellerProcAddressCallback gl_proc_address_callback, void *gl_proc_address_callback_user_data)
Definition: impeller.cc:108
IMPELLER_EXTERN_C void ImpellerContextRetain(ImpellerContext context)
Definition: impeller.cc:171
PlaygroundBackend
Definition: playground.h:26
bool Initialize(const std::function< void *(const char *function_name)> &resolver)
Definition: impeller.hpp:227
ImpellerVulkanProcAddressCallback IMPELLER_NONNULL proc_address_callback
Definition: impeller.h:634
void *IMPELLER_NULLABLE user_data
Definition: impeller.h:633
ImpellerPixelFormat pixel_format
Definition: impeller.h:621
#define IMPELLER_HPP_PROC(name)
#define VALIDATION_LOG
Definition: validation.h:91