Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build embedder for Windows #4730

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 2 additions & 8 deletions BUILD.gn
Expand Up @@ -43,8 +43,9 @@ group("flutter") {
"$flutter_root/shell/platform/embedder:flutter_embedder_framework",
]
}

public_deps += [
"$flutter_root/shell/platform/embedder:embedder_unittests",
"$flutter_root/shell/platform/embedder:flutter_engine",
"$flutter_root/flow:flow_unittests",
"$flutter_root/fml:fml_unittests",
"$flutter_root/runtime:runtime_unittests",
Expand All @@ -54,13 +55,6 @@ group("flutter") {
"$flutter_root/third_party/txt:txt_unittests",
"//garnet/public/lib/fxl:fxl_unittests",
]

if (!is_win) {
public_deps += [
"$flutter_root/shell/platform/embedder:embedder_unittests",
"$flutter_root/shell/platform/embedder:flutter_engine",
]
}
}
}

Expand Down
14 changes: 12 additions & 2 deletions fml/platform/win/file_win.cc
Expand Up @@ -6,6 +6,7 @@

#include <Shlwapi.h>

#include <algorithm>
#include <sstream>

#include "flutter/fml/platform/win/wstring_conversion.h"
Expand Down Expand Up @@ -36,13 +37,19 @@ fml::UniqueFD OpenFile(const std::wstring& path,
break;
}

DWORD flags = FILE_ATTRIBUTE_NORMAL;

if (is_directory) {
flags |= FILE_FLAG_BACKUP_SEMANTICS;
}

return fml::UniqueFD{::CreateFile(
path.c_str(), // lpFileName
desired_access, // dwDesiredAccess
FILE_SHARE_READ, // dwShareMode
0, // lpSecurityAttributes
OPEN_EXISTING, // dwCreationDisposition
FILE_ATTRIBUTE_NORMAL, // dwFlagsAndAttributes
flags, // dwFlagsAndAttributes
0 // hTemplateFile
)};
}
Expand Down Expand Up @@ -83,7 +90,10 @@ fml::UniqueFD OpenFile(const fml::UniqueFD& base_directory,

std::wstringstream stream;
stream << GetFullHandlePath(base_directory) << "\\" << path;
return OpenFile(stream.str(), permission, is_directory);
std::wstring native_path = stream.str();
// native_path is a UNC path, so transform any forward slashes into back slashes
std::replace(native_path.begin(), native_path.end(), '/', '\\');
return OpenFile(native_path, permission, is_directory);
}

fml::UniqueFD Duplicate(fml::UniqueFD::element_type descriptor) {
Expand Down
7 changes: 7 additions & 0 deletions runtime/BUILD.gn
Expand Up @@ -142,4 +142,11 @@ executable("runtime_unittests") {
"//third_party/skia",
"//topaz/lib/tonic",
]

if (is_win) {
libs = [
"iphlpapi.lib",
"Rpcrt4.lib"
]
}
}
18 changes: 18 additions & 0 deletions runtime/dart_snapshot.cc
Expand Up @@ -13,6 +13,8 @@
#include "flutter/runtime/dart_snapshot_buffer.h"
#include "flutter/runtime/dart_vm.h"

#include "flutter/lib/snapshot/snapshot.h"

namespace blink {

const char* DartSnapshot::kVMDataSymbol = "kDartVmSnapshotData";
Expand All @@ -31,9 +33,13 @@ std::unique_ptr<DartSnapshotBuffer> ResolveVMData(const Settings& settings) {
}
}

#ifdef OS_WIN
return DartSnapshotBuffer::CreateWithRawStaticBuffer(kDartVmSnapshotData);
#else
auto loaded_process = fml::NativeLibrary::CreateForCurrentProcess();
return DartSnapshotBuffer::CreateWithSymbolInLibrary(
loaded_process, DartSnapshot::kVMDataSymbol);
#endif
}

std::unique_ptr<DartSnapshotBuffer> ResolveVMInstructions(
Expand All @@ -56,9 +62,13 @@ std::unique_ptr<DartSnapshotBuffer> ResolveVMInstructions(
}
}

#ifdef OS_WIN
return DartSnapshotBuffer::CreateWithRawStaticBuffer(kDartVmSnapshotInstructions);
#else
auto loaded_process = fml::NativeLibrary::CreateForCurrentProcess();
return DartSnapshotBuffer::CreateWithSymbolInLibrary(
loaded_process, DartSnapshot::kVMInstructionsSymbol);
#endif
}

std::unique_ptr<DartSnapshotBuffer> ResolveIsolateData(
Expand All @@ -73,9 +83,13 @@ std::unique_ptr<DartSnapshotBuffer> ResolveIsolateData(
}
}

#ifdef OS_WIN
return DartSnapshotBuffer::CreateWithRawStaticBuffer(kDartIsolateSnapshotData);
#else
auto loaded_process = fml::NativeLibrary::CreateForCurrentProcess();
return DartSnapshotBuffer::CreateWithSymbolInLibrary(
loaded_process, DartSnapshot::kIsolateDataSymbol);
#endif
}

std::unique_ptr<DartSnapshotBuffer> ResolveIsolateInstructions(
Expand All @@ -99,9 +113,13 @@ std::unique_ptr<DartSnapshotBuffer> ResolveIsolateInstructions(
}
}

#ifdef OS_WIN
return DartSnapshotBuffer::CreateWithRawStaticBuffer(kDartIsolateSnapshotInstructions);
#else
auto loaded_process = fml::NativeLibrary::CreateForCurrentProcess();
return DartSnapshotBuffer::CreateWithSymbolInLibrary(
loaded_process, DartSnapshot::kIsolateInstructionsSymbol);
#endif
}

fxl::RefPtr<DartSnapshot> DartSnapshot::VMSnapshotFromSettings(
Expand Down
21 changes: 21 additions & 0 deletions runtime/dart_snapshot_buffer.cc
Expand Up @@ -31,6 +31,21 @@ class NativeLibrarySnapshotBuffer final : public DartSnapshotBuffer {
FXL_DISALLOW_COPY_AND_ASSIGN(NativeLibrarySnapshotBuffer);
};

class StaticSnapshotBuffer final : public DartSnapshotBuffer {
public:
StaticSnapshotBuffer(const uint8_t* static_buffer)
: static_buffer_(static_buffer) {}

const uint8_t* GetSnapshotPointer() const override { return static_buffer_; }

size_t GetSnapshotSize() const override { return 0; }

private:
const uint8_t* static_buffer_ = nullptr;

FXL_DISALLOW_COPY_AND_ASSIGN(StaticSnapshotBuffer);
};

class FileSnapshotBuffer final : public DartSnapshotBuffer {
public:
FileSnapshotBuffer(const char* path, bool executable)
Expand Down Expand Up @@ -74,6 +89,12 @@ DartSnapshotBuffer::CreateWithSymbolInLibrary(
return source->GetSnapshotPointer() == nullptr ? nullptr : std::move(source);
}

std::unique_ptr<DartSnapshotBuffer>
DartSnapshotBuffer::CreateWithRawStaticBuffer(const uint8_t *ptr) {
auto source = std::make_unique<StaticSnapshotBuffer>(ptr);
return source->GetSnapshotPointer() == nullptr ? nullptr : std::move(source);
}

std::unique_ptr<DartSnapshotBuffer>
DartSnapshotBuffer::CreateWithContentsOfFile(const char* file_path,
bool executable) {
Expand Down
3 changes: 3 additions & 0 deletions runtime/dart_snapshot_buffer.h
Expand Up @@ -18,6 +18,9 @@ class DartSnapshotBuffer {
fxl::RefPtr<fml::NativeLibrary> library,
const char* symbol_name);

static std::unique_ptr<DartSnapshotBuffer> CreateWithRawStaticBuffer(
const uint8_t *ptr);

static std::unique_ptr<DartSnapshotBuffer> CreateWithContentsOfFile(
const char* file_path,
bool executable);
Expand Down
7 changes: 7 additions & 0 deletions shell/common/BUILD.gn
Expand Up @@ -134,4 +134,11 @@ executable("shell_unittests") {
"//third_party/skia",
"//topaz/lib/tonic",
]

if (is_win) {
libs = [
"iphlpapi.lib",
"Rpcrt4.lib"
]
}
}
17 changes: 12 additions & 5 deletions shell/gpu/gpu_surface_gl.cc
Expand Up @@ -11,6 +11,11 @@
#include <OpenGL/gl3.h>
#elif OS_LINUX
#include <GL/gl.h>
#elif OS_WIN
// APIENTRY and WINGDIAPI are explicitly defined because importing Windows.h clobbers FXL macros
#define APIENTRY __stdcall
#define WINGDIAPI __declspec(dllimport)
#include <GL/gl.h>
#else
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
Expand Down Expand Up @@ -89,13 +94,16 @@ static SkColorType FirstSupportedColorType(GrContext* context, GLenum* format) {
*format = (y); \
return (x); \
}
#if (OS_MACOSX && !OS_IOS) || OS_LINUX
#if (OS_MACOSX && !OS_IOS) || OS_LINUX || OS_WIN
RETURN_IF_RENDERABLE(kRGBA_8888_SkColorType, GL_RGBA8);
#else
RETURN_IF_RENDERABLE(kRGBA_8888_SkColorType, GL_RGBA8_OES);
#endif
RETURN_IF_RENDERABLE(kARGB_4444_SkColorType, GL_RGBA4);
// Windows doesn't define GL_RGB565 in their GL header
#if !OS_WIN
RETURN_IF_RENDERABLE(kRGB_565_SkColorType, GL_RGB565);
#endif
return kUnknown_SkColorType;
}

Expand All @@ -106,10 +114,9 @@ static sk_sp<SkSurface> WrapOnscreenSurface(GrContext* context,
GLenum format;
const SkColorType color_type = FirstSupportedColorType(context, &format);

const GrGLFramebufferInfo framebuffer_info = {
.fFBOID = static_cast<GrGLuint>(fbo),
.fFormat = format,
};
GrGLFramebufferInfo framebuffer_info;
framebuffer_info.fFBOID = static_cast<GrGLuint>(fbo);
framebuffer_info.fFormat = format;


GrBackendRenderTarget render_target(size.fWidth, // width
Expand Down
14 changes: 14 additions & 0 deletions shell/platform/embedder/BUILD.gn
Expand Up @@ -50,6 +50,13 @@ executable("embedder_unittests") {
":fixtures",
"$flutter_root/testing",
]

if (is_win) {
libs = [
"iphlpapi.lib",
"Rpcrt4.lib"
]
}
}

shared_library("flutter_engine") {
Expand All @@ -58,6 +65,13 @@ shared_library("flutter_engine") {
]

public_configs = [ "$flutter_root:config" ]

if (is_win) {
libs = [
"iphlpapi.lib",
"Rpcrt4.lib"
]
}
}

if (is_mac) {
Expand Down
32 changes: 15 additions & 17 deletions shell/platform/embedder/embedder.cc
Expand Up @@ -31,16 +31,14 @@
#include "lib/fxl/functional/make_copyable.h"

#define SAFE_ACCESS(pointer, member, default_value) \
({ \
auto _return_value = \
static_cast<__typeof__(pointer->member)>((default_value)); \
([=](){ \
if (offsetof(std::remove_pointer<decltype(pointer)>::type, member) + \
sizeof(pointer->member) <= \
pointer->struct_size) { \
_return_value = pointer->member; \
return pointer->member; \
} \
_return_value; \
})
return static_cast<decltype(pointer->member)>((default_value)); \
})()

bool IsRendererValid(const FlutterRendererConfig* config) {
if (config == nullptr || config->type != kOpenGL) {
Expand Down Expand Up @@ -112,11 +110,11 @@ FlutterResult FlutterEngineRun(size_t version,
user_data](fxl::RefPtr<blink::PlatformMessage> message) {
auto handle = new FlutterPlatformMessageResponseHandle();
const FlutterPlatformMessage incoming_message = {
.struct_size = sizeof(FlutterPlatformMessage),
.channel = message->channel().c_str(),
.message = message->data().data(),
.message_size = message->data().size(),
.response_handle = handle,
sizeof(FlutterPlatformMessage),
message->channel().c_str(),
message->data().data(),
message->data().size(),
handle,
};
handle->message = std::move(message);
return ptr(&incoming_message, user_data);
Expand Down Expand Up @@ -187,12 +185,12 @@ FlutterResult FlutterEngineRun(size_t version,
);

shell::PlatformViewEmbedder::DispatchTable dispatch_table = {
.gl_make_current_callback = make_current,
.gl_clear_current_callback = clear_current,
.gl_present_callback = present,
.gl_fbo_callback = fbo_callback,
.platform_message_response_callback = platform_message_response_callback,
.gl_make_resource_current_callback = make_resource_current_callback,
make_current,
clear_current,
present,
fbo_callback,
platform_message_response_callback,
make_resource_current_callback,
};

shell::Shell::CreateCallback<shell::PlatformView> on_create_platform_view =
Expand Down
8 changes: 8 additions & 0 deletions shell/platform/embedder/embedder.h
Expand Up @@ -14,7 +14,15 @@ extern "C" {
#endif

#ifndef FLUTTER_EXPORT
#if _WIN32
#ifdef FLUTTER_STATIC
#define FLUTTER_EXPORT
#else
#define FLUTTER_EXPORT __declspec(dllimport)
#endif // FLUTTER_STATIC
#else
#define FLUTTER_EXPORT
#endif
#endif // FLUTTER_EXPORT

#define FLUTTER_ENGINE_VERSION 1
Expand Down
24 changes: 13 additions & 11 deletions shell/platform/embedder/tests/embedder_unittests.cc
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

#include <string>
#define FLUTTER_STATIC
#include "embedder.h"
#include "flutter/testing/testing.h"

Expand All @@ -17,22 +18,23 @@ TEST(EmbedderTest, MustNotRunWithInvalidArgs) {

TEST(EmbedderTest, CanLaunchAndShutdownWithValidProjectArgs) {
FlutterOpenGLRendererConfig renderer = {
.struct_size = sizeof(FlutterOpenGLRendererConfig),
.make_current = [](void*) { return false; },
.clear_current = [](void*) { return false; },
.present = [](void*) { return false; },
.fbo_callback = [](void*) -> uint32_t { return 0; },
sizeof(FlutterOpenGLRendererConfig),
[](void*) { return false; },
[](void*) { return false; },
[](void*) { return false; },
[](void*) -> uint32_t { return 0; },
};

std::string main =
std::string(testing::GetFixturesPath()) + "/simple_main.dart";

FlutterRendererConfig config = {.type = FlutterRendererType::kOpenGL,
.open_gl = renderer};
FlutterProjectArgs args = {.struct_size = sizeof(FlutterProjectArgs),
.assets_path = "",
.main_path = main.c_str(),
.packages_path = ""};
FlutterRendererConfig config = { FlutterRendererType::kOpenGL, renderer };
FlutterProjectArgs args = {
sizeof(FlutterProjectArgs),
"",
main.c_str(),
""
};
FlutterEngine engine = nullptr;
FlutterResult result = FlutterEngineRun(FLUTTER_ENGINE_VERSION, &config,
&args, nullptr, &engine);
Expand Down
7 changes: 7 additions & 0 deletions shell/testing/BUILD.gn
Expand Up @@ -28,4 +28,11 @@ executable("testing") {
if (is_linux) {
ldflags = [ "-rdynamic" ]
}

if (is_win) {
libs = [
"iphlpapi.lib",
"Rpcrt4.lib"
]
}
}