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()) {
62  return Adopt<Context>(
65  Playground::GLProcAddressResolver playground_gl_proc_address_callback =
67  ImpellerProcAddressCallback gl_proc_address_callback =
68  [](const char* proc_name, void* user_data) -> void* {
69  return (*reinterpret_cast<Playground::GLProcAddressResolver*>(
70  user_data))(proc_name);
71  };
72  return Adopt<Context>(ImpellerContextCreateOpenGLESNew(
73  ImpellerGetVersion(), gl_proc_address_callback,
74  &playground_gl_proc_address_callback));
75  }
77  ImpellerContextVulkanSettings settings = {};
78  struct UserData {
80  } user_data;
81  user_data.resolver = CreateVKProcAddressResolver();
82  settings.user_data = &user_data;
84  settings.proc_address_callback = [](void* instance, //
85  const char* proc_name, //
86  void* user_data //
87  ) -> void* {
88  auto resolver = reinterpret_cast<UserData*>(user_data)->resolver;
89  if (resolver) {
90  return resolver(instance, proc_name);
91  } else {
92  return nullptr;
93  }
94  };
95  return Adopt<Context>(
97  }
98  FML_UNREACHABLE();
99 }
100 
102  PlaygroundBackend backend,
103  Context& context,
104  std::shared_ptr<impeller::Surface> shared_surface) {
105  switch (backend) {
106 #if IMPELLER_ENABLE_METAL
108  return Adopt<Surface>(new SurfaceMTL(context, std::move(shared_surface)));
109 #endif
110 
111 #if IMPELLER_ENABLE_OPENGLES
113  return Adopt<Surface>(
114  new SurfaceGLES(context, std::move(shared_surface)));
115 #endif
116 
117 #if IMPELLER_ENABLE_VULKAN
119  return Adopt<Surface>(new SurfaceVK(context, std::move(shared_surface)));
120 #endif
121  default:
122  return nullptr;
123  }
124  FML_UNREACHABLE();
125 }
126 
128  auto interop_context = GetInteropContext();
129  if (!interop_context) {
130  return false;
131  }
132  return Playground::OpenPlaygroundHere([&](RenderTarget& target) -> bool {
133  auto impeller_surface = std::make_shared<impeller::Surface>(target);
134  auto surface = CreateSharedSurface(GetBackend(), //
135  *interop_context.Get(), //
136  std::move(impeller_surface) //
137  );
138  if (!surface) {
139  VALIDATION_LOG << "Could not wrap test surface as an interop surface.";
140  return false;
141  }
142  return callback(interop_context, surface);
143  });
144 }
145 
147  PlaygroundBackend backend,
148  std::shared_ptr<impeller::Context> shared_context) {
149  switch (backend) {
150 #if IMPELLER_ENABLE_METAL
152  return ContextMTL::Create(shared_context);
153 #endif
154 #if IMPELLER_ENABLE_OPENGLES
156  return ContextGLES::Create(std::move(shared_context));
157 #endif
158 #if IMPELLER_ENABLE_VULKAN
160  return ContextVK::Create(std::move(shared_context));
161 #endif
162  default:
163  return nullptr;
164  }
165  FML_UNREACHABLE();
166 }
167 
169  if (interop_context_) {
170  return interop_context_;
171  }
172 
173  auto context = CreateSharedContext(GetBackend(), GetContext());
174  if (!context) {
175  return nullptr;
176  }
177  interop_context_ = std::move(context);
178  return interop_context_;
179 }
180 
182  auto c_context = GetInteropContext().GetC();
183  ImpellerContextRetain(c_context);
184  return hpp::Context{c_context, hpp::AdoptTag::kAdopt};
185 }
186 
187 std::unique_ptr<hpp::Mapping> PlaygroundTest::OpenAssetAsHPPMapping(
188  std::string asset_name) const {
189  std::shared_ptr<fml::Mapping> data =
190  OpenAssetAsMapping(std::move(asset_name));
191  if (!data) {
192  return nullptr;
193  }
194  return std::make_unique<hpp::Mapping>(data->GetMapping(), //
195  data->GetSize(), //
196  [data]() {} //
197  );
198 }
199 
200 hpp::Texture PlaygroundTest::OpenAssetAsHPPTexture(std::string asset_name) {
201  auto compressed_data = OpenAssetAsMapping(std::move(asset_name));
202  if (!compressed_data) {
203  return {nullptr, hpp::AdoptTag::kAdopt};
204  }
205  auto compressed_image =
206  LoadFixtureImageCompressed(std::move(compressed_data));
207  if (!compressed_image) {
208  return {nullptr, hpp::AdoptTag::kAdopt};
209  }
210  auto decompressed_image = DecodeImageRGBA(compressed_image);
211  if (!decompressed_image.has_value()) {
212  return {nullptr, hpp::AdoptTag::kAdopt};
213  }
214  auto rgba_decompressed_image =
215  std::make_shared<DecompressedImage>(decompressed_image->ConvertToRGBA());
216  if (!rgba_decompressed_image || !rgba_decompressed_image->IsValid()) {
217  return {nullptr, hpp::AdoptTag::kAdopt};
218  }
219  auto context = GetHPPContext();
220  if (!context) {
221  return {nullptr, hpp::AdoptTag::kAdopt};
222  }
223 
224  auto rgba_mapping = std::make_unique<hpp::Mapping>(
225  rgba_decompressed_image->GetAllocation()->GetMapping(),
226  rgba_decompressed_image->GetAllocation()->GetSize(),
227  [rgba_decompressed_image]() {});
228 
229  return hpp::Texture::WithContents(
230  context,
233  .size = {rgba_decompressed_image->GetSize().width,
234  rgba_decompressed_image->GetSize().height},
235  .mip_count = 1u,
236  },
237  std::move(rgba_mapping));
238 }
239 
240 } // namespace impeller::interop::testing
bool OpenPlaygroundHere(const RenderCallback &render_callback)
Definition: playground.cc:201
static std::shared_ptr< CompressedImage > LoadFixtureImageCompressed(std::shared_ptr< fml::Mapping > mapping)
Definition: playground.cc:361
GLProcAddressResolver CreateGLProcAddressResolver() const
Definition: playground.cc:520
const PlaygroundSwitches switches_
Definition: playground.h:131
std::shared_ptr< Context > GetContext() const
Definition: playground.cc:91
std::function< void *(void *instance, const char *proc_name)> VKProcAddressResolver
Definition: playground.h:122
std::function< void *(const char *proc_name)> GLProcAddressResolver
Definition: playground.h:118
static std::optional< DecompressedImage > DecodeImageRGBA(const std::shared_ptr< CompressedImage > &compressed)
Definition: playground.cc:372
VKProcAddressResolver CreateVKProcAddressResolver() const
Definition: playground.cc:525
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:45
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:151
IMPELLER_EXTERN_C ImpellerContext ImpellerContextCreateMetalNew(uint32_t version)
Definition: impeller.cc:133
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
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
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:68
#define IMPELLER_HPP_PROC(name)
#define VALIDATION_LOG
Definition: validation.h:91