embedder_config_builder.cc 9.8 KB
Newer Older
1 2 3 4 5 6
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/platform/embedder/tests/embedder_config_builder.h"

7
#include "flutter/runtime/dart_vm.h"
8
#include "flutter/shell/platform/embedder/embedder.h"
9
#include "third_party/skia/include/core/SkBitmap.h"
10

11
namespace flutter {
12 13
namespace testing {

14
EmbedderConfigBuilder::EmbedderConfigBuilder(
15
    EmbedderTestContext& context,
16 17
    InitializationPreference preference)
    : context_(context) {
18
  project_args_.struct_size = sizeof(project_args_);
19
  project_args_.shutdown_dart_vm_when_done = true;
20 21
  project_args_.platform_message_callback =
      [](const FlutterPlatformMessage* message, void* context) {
22 23
        reinterpret_cast<EmbedderTestContext*>(context)
            ->PlatformMessageCallback(message);
24
      };
25

26
  custom_task_runners_.struct_size = sizeof(FlutterCustomTaskRunners);
27 28 29

  opengl_renderer_config_.struct_size = sizeof(FlutterOpenGLRendererConfig);
  opengl_renderer_config_.make_current = [](void* context) -> bool {
30
    return reinterpret_cast<EmbedderTestContext*>(context)->GLMakeCurrent();
31 32
  };
  opengl_renderer_config_.clear_current = [](void* context) -> bool {
33
    return reinterpret_cast<EmbedderTestContext*>(context)->GLClearCurrent();
34 35
  };
  opengl_renderer_config_.present = [](void* context) -> bool {
36
    return reinterpret_cast<EmbedderTestContext*>(context)->GLPresent();
37 38
  };
  opengl_renderer_config_.fbo_callback = [](void* context) -> uint32_t {
39
    return reinterpret_cast<EmbedderTestContext*>(context)->GLGetFramebuffer();
40 41
  };
  opengl_renderer_config_.make_resource_current = [](void* context) -> bool {
42 43
    return reinterpret_cast<EmbedderTestContext*>(context)
        ->GLMakeResourceCurrent();
44 45 46
  };
  opengl_renderer_config_.gl_proc_resolver = [](void* context,
                                                const char* name) -> void* {
47 48
    return reinterpret_cast<EmbedderTestContext*>(context)->GLGetProcAddress(
        name);
49
  };
50 51 52 53 54 55
  opengl_renderer_config_.fbo_reset_after_present = true;
  opengl_renderer_config_.surface_transformation =
      [](void* context) -> FlutterTransformation {
    return reinterpret_cast<EmbedderTestContext*>(context)
        ->GetRootSurfaceTransformation();
  };
56 57

  software_renderer_config_.struct_size = sizeof(FlutterSoftwareRendererConfig);
58
  software_renderer_config_.surface_present_callback =
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
      [](void* context, const void* allocation, size_t row_bytes,
         size_t height) {
        auto image_info =
            SkImageInfo::MakeN32Premul(SkISize::Make(row_bytes / 4, height));
        SkBitmap bitmap;
        if (!bitmap.installPixels(image_info, const_cast<void*>(allocation),
                                  row_bytes)) {
          FML_LOG(ERROR) << "Could not copy pixels for the software "
                            "composition from the engine.";
          return false;
        }
        bitmap.setImmutable();
        return reinterpret_cast<EmbedderTestContext*>(context)->SofwarePresent(
            SkImage::MakeFromBitmap(bitmap));
      };
74

75 76 77 78
  // The first argument is treated as the executable name. Don't make tests have
  // to do this manually.
  AddCommandLineArgument("embedder_unittest");

79
  if (preference != InitializationPreference::kNoInitialize) {
80 81
    SetAssetsPath();
    SetIsolateCreateCallbackHook();
82
    SetSemanticsCallbackHooks();
83
    AddCommandLineArgument("--disable-observatory");
84 85 86 87 88 89 90 91 92

    if (preference == InitializationPreference::kSnapshotsInitialize ||
        preference == InitializationPreference::kMultiAOTInitialize) {
      SetSnapshots();
    }
    if (preference == InitializationPreference::kAOTDataInitialize ||
        preference == InitializationPreference::kMultiAOTInitialize) {
      SetAOTDataElf();
    }
93
  }
94 95 96 97
}

EmbedderConfigBuilder::~EmbedderConfigBuilder() = default;

98 99 100 101
FlutterProjectArgs& EmbedderConfigBuilder::GetProjectArgs() {
  return project_args_;
}

102
void EmbedderConfigBuilder::SetSoftwareRendererConfig(SkISize surface_size) {
103 104
  renderer_config_.type = FlutterRendererType::kSoftware;
  renderer_config_.software = software_renderer_config_;
105 106 107 108 109

  // TODO(chinmaygarde): The compositor still uses a GL surface for operation.
  // Once this is no longer the case, don't setup the GL surface when using the
  // software renderer config.
  context_.SetupOpenGLSurface(surface_size);
110 111
}

112
void EmbedderConfigBuilder::SetOpenGLRendererConfig(SkISize surface_size) {
113 114
  renderer_config_.type = FlutterRendererType::kOpenGL;
  renderer_config_.open_gl = opengl_renderer_config_;
115
  context_.SetupOpenGLSurface(surface_size);
116 117
}

118 119
void EmbedderConfigBuilder::SetAssetsPath() {
  project_args_.assets_path = context_.GetAssetsPath().c_str();
120 121
}

122 123
void EmbedderConfigBuilder::SetSnapshots() {
  if (auto mapping = context_.GetVMSnapshotData()) {
124 125 126 127
    project_args_.vm_snapshot_data = mapping->GetMapping();
    project_args_.vm_snapshot_data_size = mapping->GetSize();
  }

128
  if (auto mapping = context_.GetVMSnapshotInstructions()) {
129 130 131 132
    project_args_.vm_snapshot_instructions = mapping->GetMapping();
    project_args_.vm_snapshot_instructions_size = mapping->GetSize();
  }

133
  if (auto mapping = context_.GetIsolateSnapshotData()) {
134 135 136 137
    project_args_.isolate_snapshot_data = mapping->GetMapping();
    project_args_.isolate_snapshot_data_size = mapping->GetSize();
  }

138
  if (auto mapping = context_.GetIsolateSnapshotInstructions()) {
139 140 141 142 143
    project_args_.isolate_snapshot_instructions = mapping->GetMapping();
    project_args_.isolate_snapshot_instructions_size = mapping->GetSize();
  }
}

144 145 146 147
void EmbedderConfigBuilder::SetAOTDataElf() {
  project_args_.aot_data = context_.GetAOTData();
}

148 149
void EmbedderConfigBuilder::SetIsolateCreateCallbackHook() {
  project_args_.root_isolate_create_callback =
150
      EmbedderTestContext::GetIsolateCreateCallbackHook();
151 152
}

153 154
void EmbedderConfigBuilder::SetSemanticsCallbackHooks() {
  project_args_.update_semantics_node_callback =
155
      EmbedderTestContext::GetUpdateSemanticsNodeCallbackHook();
156
  project_args_.update_semantics_custom_action_callback =
157
      EmbedderTestContext::GetUpdateSemanticsCustomActionCallbackHook();
158 159
}

160 161 162 163 164 165 166 167 168
void EmbedderConfigBuilder::SetDartEntrypoint(std::string entrypoint) {
  if (entrypoint.size() == 0) {
    return;
  }

  dart_entrypoint_ = std::move(entrypoint);
  project_args_.custom_dart_entrypoint = dart_entrypoint_.c_str();
}

169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
void EmbedderConfigBuilder::AddCommandLineArgument(std::string arg) {
  if (arg.size() == 0) {
    return;
  }

  command_line_arguments_.emplace_back(std::move(arg));
}

void EmbedderConfigBuilder::SetPlatformTaskRunner(
    const FlutterTaskRunnerDescription* runner) {
  if (runner == nullptr) {
    return;
  }
  custom_task_runners_.platform_task_runner = runner;
  project_args_.custom_task_runners = &custom_task_runners_;
}

186 187 188 189 190 191 192 193 194 195
void EmbedderConfigBuilder::SetRenderTaskRunner(
    const FlutterTaskRunnerDescription* runner) {
  if (runner == nullptr) {
    return;
  }

  custom_task_runners_.render_task_runner = runner;
  project_args_.custom_task_runners = &custom_task_runners_;
}

196
void EmbedderConfigBuilder::SetPlatformMessageCallback(
197
    const std::function<void(const FlutterPlatformMessage*)>& callback) {
198 199 200
  context_.SetPlatformMessageCallback(callback);
}

201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
void EmbedderConfigBuilder::SetCompositor() {
  context_.SetupCompositor();
  auto& compositor = context_.GetCompositor();
  compositor_.struct_size = sizeof(compositor_);
  compositor_.user_data = &compositor;
  compositor_.create_backing_store_callback =
      [](const FlutterBackingStoreConfig* config,  //
         FlutterBackingStore* backing_store_out,   //
         void* user_data                           //
      ) {
        return reinterpret_cast<EmbedderTestCompositor*>(user_data)
            ->CreateBackingStore(config, backing_store_out);
      };
  compositor_.collect_backing_store_callback =
      [](const FlutterBackingStore* backing_store,  //
         void* user_data                            //
      ) {
        return reinterpret_cast<EmbedderTestCompositor*>(user_data)
            ->CollectBackingStore(backing_store);
      };
  compositor_.present_layers_callback = [](const FlutterLayer** layers,  //
                                           size_t layers_count,          //
                                           void* user_data               //
                                        ) {
    return reinterpret_cast<EmbedderTestCompositor*>(user_data)->Present(
        layers,       //
        layers_count  //

    );
  };
  project_args_.compositor = &compositor_;
}

FlutterCompositor& EmbedderConfigBuilder::GetCompositor() {
  return compositor_;
}

238
UniqueEngine EmbedderConfigBuilder::LaunchEngine() const {
239 240 241 242 243 244 245 246
  return SetupEngine(true);
}

UniqueEngine EmbedderConfigBuilder::InitializeEngine() const {
  return SetupEngine(false);
}

UniqueEngine EmbedderConfigBuilder::SetupEngine(bool run) const {
247
  FlutterEngine engine = nullptr;
248
  FlutterProjectArgs project_args = project_args_;
249 250 251 252 253 254 255 256 257

  std::vector<const char*> args;
  args.reserve(command_line_arguments_.size());

  for (const auto& arg : command_line_arguments_) {
    args.push_back(arg.c_str());
  }

  if (args.size() > 0) {
258 259
    project_args.command_line_argv = args.data();
    project_args.command_line_argc = args.size();
260 261 262
  } else {
    // Clear it out in case this is not the first engine launch from the
    // embedder config builder.
263 264
    project_args.command_line_argv = nullptr;
    project_args.command_line_argc = 0;
265 266
  }

267 268 269 270 271
  auto result =
      run ? FlutterEngineRun(FLUTTER_ENGINE_VERSION, &renderer_config_,
                             &project_args, &context_, &engine)
          : FlutterEngineInitialize(FLUTTER_ENGINE_VERSION, &renderer_config_,
                                    &project_args, &context_, &engine);
272 273 274 275 276 277 278 279 280

  if (result != kSuccess) {
    return {};
  }

  return UniqueEngine{engine};
}

}  // namespace testing
281
}  // namespace flutter