Jason Simmons 48de25e19b Do not modify the set of active streams within the embedder tracing callbacks (#2600)
Dart invokes Start/StopTracing callbacks within the _setVMTimelineFlags service
method whenever the embedder timeline stream toggles on or off.  Flutter's
implementation of these callbacks was modifying the set of enabled streams,
which could override the intended behavior of _setVMTimelineFlags.

Start/StopTracing will now only control Flutter's embedder-specific log.

Also needed to change the Flutter engine's --trace-startup flag to set the
corresponding timeline stream flag on the Dart VM.
2016-04-19 10:38:22 -07:00

183 lines
5.4 KiB
C++

// Copyright 2015 The Chromium 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 "sky/shell/shell.h"
#include <fcntl.h>
#include <memory>
#include <sstream>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/i18n/icu_util.h"
#include "base/lazy_instance.h"
#include "base/memory/discardable_memory.h"
#include "base/memory/discardable_memory_allocator.h"
#include "base/posix/eintr_wrapper.h"
#include "base/single_thread_task_runner.h"
#include "base/trace_event/trace_event.h"
#include "mojo/message_pump/message_pump_mojo.h"
#include "sky/engine/core/script/dart_init.h"
#include "sky/engine/public/platform/sky_settings.h"
#include "sky/shell/diagnostic/diagnostic_server.h"
#include "sky/shell/switches.h"
#include "sky/shell/ui/engine.h"
namespace sky {
namespace shell {
namespace {
static Shell* g_shell = nullptr;
scoped_ptr<base::MessagePump> CreateMessagePumpMojo() {
return make_scoped_ptr(new mojo::common::MessagePumpMojo);
}
bool IsInvalid(const base::WeakPtr<Rasterizer>& rasterizer) {
return !rasterizer;
}
class NonDiscardableMemory : public base::DiscardableMemory {
public:
explicit NonDiscardableMemory(size_t size) : data_(new uint8_t[size]) {}
bool Lock() override { return false; }
void Unlock() override {}
void* data() const override { return data_.get(); }
private:
std::unique_ptr<uint8_t[]> data_;
};
class NonDiscardableMemoryAllocator : public base::DiscardableMemoryAllocator {
public:
scoped_ptr<base::DiscardableMemory> AllocateLockedDiscardableMemory(
size_t size) override {
return make_scoped_ptr(new NonDiscardableMemory(size));
}
};
base::LazyInstance<NonDiscardableMemoryAllocator> g_discardable;
void ServiceIsolateHook(bool running_precompiled) {
if (!running_precompiled) {
const blink::SkySettings& settings = blink::SkySettings::Get();
if (settings.enable_observatory)
DiagnosticServer::Start();
}
}
} // namespace
Shell::Shell() {
DCHECK(!g_shell);
base::Thread::Options options;
options.message_pump_factory = base::Bind(&CreateMessagePumpMojo);
gpu_thread_.reset(new base::Thread("gpu_thread"));
gpu_thread_->StartWithOptions(options);
gpu_task_runner_ = gpu_thread_->message_loop()->task_runner();
gpu_task_runner_->PostTask(FROM_HERE,
base::Bind(&Shell::InitGpuThread, base::Unretained(this)));
ui_thread_.reset(new base::Thread("ui_thread"));
ui_thread_->StartWithOptions(options);
ui_task_runner_ = ui_thread_->message_loop()->task_runner();
io_thread_.reset(new base::Thread("io_thread"));
io_thread_->StartWithOptions(options);
io_task_runner_ = io_thread_->message_loop()->task_runner();
blink::SetServiceIsolateHook(ServiceIsolateHook);
}
Shell::~Shell() {}
void Shell::InitStandalone(std::string icu_data_path) {
TRACE_EVENT0("flutter", "Shell::InitStandalone");
int file_descriptor =
icu_data_path.size() != 0
? HANDLE_EINTR(::open(icu_data_path.data(), O_RDONLY))
: -1;
if (file_descriptor == -1) {
// If the embedder did not specify a valid file, fallback to looking through
// internal search paths.
CHECK(base::i18n::InitializeICU());
} else {
auto region = base::MemoryMappedFile::Region::kWholeFile;
CHECK(base::i18n::InitializeICUWithFileDescriptor(file_descriptor, region));
HANDLE_EINTR(::close(file_descriptor));
}
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
blink::SkySettings settings;
// Enable Observatory
settings.enable_observatory =
!command_line.HasSwitch(switches::kNonInteractive);
// Set Observatory Port
if (command_line.HasSwitch(switches::kDeviceObservatoryPort)) {
auto port_string =
command_line.GetSwitchValueASCII(switches::kDeviceObservatoryPort);
std::stringstream stream(port_string);
uint32_t port = 0;
if (stream >> port) {
settings.observatory_port = port;
} else {
LOG(INFO)
<< "Observatory port specified was malformed. Will default to "
<< settings.observatory_port;
}
}
settings.start_paused = command_line.HasSwitch(switches::kStartPaused);
settings.enable_dart_checked_mode =
command_line.HasSwitch(switches::kEnableCheckedMode);
settings.trace_startup = command_line.HasSwitch(switches::kTraceStartup);
blink::SkySettings::Set(settings);
Init();
}
void Shell::Init() {
base::DiscardableMemoryAllocator::SetInstance(&g_discardable.Get());
DCHECK(!g_shell);
g_shell = new Shell();
g_shell->ui_task_runner()->PostTask(FROM_HERE, base::Bind(&Engine::Init));
}
Shell& Shell::Shared() {
DCHECK(g_shell);
return *g_shell;
}
TracingController& Shell::tracing_controller() {
return tracing_controller_;
}
void Shell::InitGpuThread() {
gpu_thread_checker_.reset(new base::ThreadChecker());
}
void Shell::AddRasterizer(const base::WeakPtr<Rasterizer>& rasterizer) {
DCHECK(gpu_thread_checker_ && gpu_thread_checker_->CalledOnValidThread());
rasterizers_.push_back(rasterizer);
}
void Shell::PurgeRasterizers() {
DCHECK(gpu_thread_checker_ && gpu_thread_checker_->CalledOnValidThread());
rasterizers_.erase(
std::remove_if(rasterizers_.begin(), rasterizers_.end(), IsInvalid),
rasterizers_.end());
}
void Shell::GetRasterizers(std::vector<base::WeakPtr<Rasterizer>>* rasterizers) {
DCHECK(gpu_thread_checker_ && gpu_thread_checker_->CalledOnValidThread());
*rasterizers = rasterizers_;
}
} // namespace shell
} // namespace sky