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>(
67  Playground::GLProcAddressResolver playground_gl_proc_address_callback =
69  ImpellerProcAddressCallback gl_proc_address_callback =
70  [](const char* proc_name, void* user_data) -> void* {
71  return (*reinterpret_cast<Playground::GLProcAddressResolver*>(
72  user_data))(proc_name);
73  };
74  return Adopt<Context>(ImpellerContextCreateOpenGLESNew(
75  ImpellerGetVersion(), gl_proc_address_callback,
76  &playground_gl_proc_address_callback));
77  }
79  ImpellerContextVulkanSettings settings = {};
80  struct UserData {
82  } user_data;
83  user_data.resolver = CreateVKProcAddressResolver();
84  settings.user_data = &user_data;
85  settings.enable_vulkan_validation =
87  settings.proc_address_callback = [](void* instance, //
88  const char* proc_name, //
89  void* user_data //
90  ) -> void* {
91  auto resolver = reinterpret_cast<UserData*>(user_data)->resolver;
92  if (resolver) {
93  return resolver(instance, proc_name);
94  } else {
95  return nullptr;
96  }
97  };
98  return Adopt<Context>(
100  }
101  FML_UNREACHABLE();
102 }
103 
105  PlaygroundBackend backend,
106  Context& context,
107  std::shared_ptr<impeller::Surface> shared_surface) {
108  switch (backend) {
109 #if IMPELLER_ENABLE_METAL
112  return Adopt<Surface>(new SurfaceMTL(context, std::move(shared_surface)));
113 #endif
114 
115 #if IMPELLER_ENABLE_OPENGLES
118  return Adopt<Surface>(
119  new SurfaceGLES(context, std::move(shared_surface)));
120 #endif
121 
122 #if IMPELLER_ENABLE_VULKAN
124  return Adopt<Surface>(new SurfaceVK(context, std::move(shared_surface)));
125 #endif
126  default:
127  return nullptr;
128  }
129  FML_UNREACHABLE();
130 }
131 
133  auto interop_context = GetInteropContext();
134  if (!interop_context) {
135  return false;
136  }
137  return Playground::OpenPlaygroundHere([&](RenderTarget& target) -> bool {
138  auto impeller_surface = std::make_shared<impeller::Surface>(target);
139  auto surface = CreateSharedSurface(GetBackend(), //
140  *interop_context.Get(), //
141  std::move(impeller_surface) //
142  );
143  if (!surface) {
144  VALIDATION_LOG << "Could not wrap test surface as an interop surface.";
145  return false;
146  }
147  return callback(interop_context, surface);
148  });
149 }
150 
152  PlaygroundBackend backend,
153  std::shared_ptr<impeller::Context> shared_context) {
154  switch (backend) {
155 #if IMPELLER_ENABLE_METAL
158  return ContextMTL::Create(shared_context);
159 #endif
160 #if IMPELLER_ENABLE_OPENGLES
163  return ContextGLES::Create(std::move(shared_context));
164 #endif
165 #if IMPELLER_ENABLE_VULKAN
167  return ContextVK::Create(std::move(shared_context));
168 #endif
169  default:
170  return nullptr;
171  }
172  FML_UNREACHABLE();
173 }
174 
176  if (interop_context_) {
177  return interop_context_;
178  }
179 
181  if (!context) {
182  return nullptr;
183  }
184  interop_context_ = std::move(context);
185  return interop_context_;
186 }
187 
189  auto c_context = GetInteropContext().GetC();
190  ImpellerContextRetain(c_context);
191  return hpp::Context{c_context, hpp::AdoptTag::kAdopt};
192 }
193 
194 std::unique_ptr<hpp::Mapping> PlaygroundTest::OpenAssetAsHPPMapping(
195  std::string asset_name) const {
196  std::shared_ptr<fml::Mapping> data =
197  OpenAssetAsMapping(std::move(asset_name));
198  if (!data) {
199  return nullptr;
200  }
201  return std::make_unique<hpp::Mapping>(data->GetMapping(), //
202  data->GetSize(), //
203  [data]() {} //
204  );
205 }
206 
207 hpp::Texture PlaygroundTest::OpenAssetAsHPPTexture(std::string asset_name) {
208  auto compressed_data = OpenAssetAsMapping(std::move(asset_name));
209  if (!compressed_data) {
210  return {nullptr, hpp::AdoptTag::kAdopt};
211  }
212  auto compressed_image =
213  LoadFixtureImageCompressed(std::move(compressed_data));
214  if (!compressed_image) {
215  return {nullptr, hpp::AdoptTag::kAdopt};
216  }
217  auto decompressed_image = DecodeImageRGBA(compressed_image);
218  if (!decompressed_image.has_value()) {
219  return {nullptr, hpp::AdoptTag::kAdopt};
220  }
221  auto rgba_decompressed_image =
222  std::make_shared<DecompressedImage>(decompressed_image->ConvertToRGBA());
223  if (!rgba_decompressed_image || !rgba_decompressed_image->IsValid()) {
224  return {nullptr, hpp::AdoptTag::kAdopt};
225  }
226  auto context = GetHPPContext();
227  if (!context) {
228  return {nullptr, hpp::AdoptTag::kAdopt};
229  }
230 
231  auto rgba_mapping = std::make_unique<hpp::Mapping>(
232  rgba_decompressed_image->GetAllocation()->GetMapping(),
233  rgba_decompressed_image->GetAllocation()->GetSize(),
234  [rgba_decompressed_image]() {});
235 
236  return hpp::Texture::WithContents(
237  context,
240  .size = {rgba_decompressed_image->GetSize().width,
241  rgba_decompressed_image->GetSize().height},
242  .mip_count = 1u,
243  },
244  std::move(rgba_mapping));
245 }
246 
247 } // namespace impeller::interop::testing
bool OpenPlaygroundHere(const RenderCallback &render_callback)
Definition: playground.cc:287
static std::shared_ptr< CompressedImage > LoadFixtureImageCompressed(std::shared_ptr< fml::Mapping > mapping)
Definition: playground.cc:450
const PlaygroundSwitches & GetSwitches() const
Return an unmodifiable reference to the current switches. The switches might change at the start of a...
Definition: playground.h:167
GLProcAddressResolver CreateGLProcAddressResolver() const
Definition: playground.cc:610
std::shared_ptr< Context > GetContext() const
Definition: playground.cc:126
std::function< void *(void *instance, const char *proc_name)> VKProcAddressResolver
Definition: playground.h:111
std::function< void *(const char *proc_name)> GLProcAddressResolver
Definition: playground.h:107
static std::optional< DecompressedImage > DecodeImageRGBA(const std::shared_ptr< CompressedImage > &compressed)
Definition: playground.cc:461
VKProcAddressResolver CreateVKProcAddressResolver() const
Definition: playground.cc:615
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:27
std::shared_ptr< ContextGLES > context
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