Import Cobalt 4.11565
diff --git a/src/cobalt/audio/audio_node_input.cc b/src/cobalt/audio/audio_node_input.cc
index 2f42724..9be0c32 100644
--- a/src/cobalt/audio/audio_node_input.cc
+++ b/src/cobalt/audio/audio_node_input.cc
@@ -232,7 +232,12 @@
// TODO: Consider computing computedNumberOfChannels and do up-mix or
// down-mix base on computedNumberOfChannels. The current implementation
// is based on the fact that the channelCountMode is max.
- DCHECK_EQ(owner_node_->channel_count_mode(), AudioNode::kMax);
+ if (owner_node_->channel_count_mode() != AudioNode::kMax) {
+ DLOG(ERROR) << "Unsupported channel count mode: "
+ << owner_node_->channel_count_mode();
+ return;
+ }
+
// Pull audio buffer from connected audio input. When an input is connected
// from one or more AudioNode outputs. Fan-in is supported.
for (std::set<AudioNodeOutput*>::iterator iter = outputs_.begin();
diff --git a/src/cobalt/base/base.gyp b/src/cobalt/base/base.gyp
index a2822ab..19652ec 100644
--- a/src/cobalt/base/base.gyp
+++ b/src/cobalt/base/base.gyp
@@ -45,6 +45,7 @@
'log_message_handler.h',
'math.cc',
'math.h',
+ 'message_queue.h',
'poller.h',
'polymorphic_downcast.h',
'polymorphic_equatable.h',
diff --git a/src/cobalt/base/message_queue.h b/src/cobalt/base/message_queue.h
new file mode 100644
index 0000000..3c7ad78
--- /dev/null
+++ b/src/cobalt/base/message_queue.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef COBALT_BASE_MESSAGE_QUEUE_H_
+#define COBALT_BASE_MESSAGE_QUEUE_H_
+
+#include <queue>
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/synchronization/lock.h"
+
+namespace base {
+
+// A thread safe in-order message queue. In some situations this can be
+// preferred versus PostTask()ing directly to a MessageLoop since the data
+// stored within the queued Closures can be destroyed on demand, and also the
+// queue messages can be processed at a time of the user's choosing.
+class MessageQueue {
+ public:
+ ~MessageQueue() {
+ // Leave no message behind!
+ ProcessAll();
+ }
+
+ // Add a message to the end of the queue.
+ void AddMessage(const base::Closure& message) {
+ base::AutoLock lock(mutex_);
+ DCHECK(!message.is_null());
+ queue_.push(message);
+ }
+
+ // Execute all messages in the MessageQueue until the queue is empty and then
+ // return.
+ void ProcessAll() {
+ base::AutoLock lock(mutex_);
+
+ while (!queue_.empty()) {
+ queue_.front().Run();
+ queue_.pop();
+ }
+ }
+
+ private:
+ base::Lock mutex_;
+ std::queue<base::Closure> queue_;
+};
+
+} // namespace base
+
+#endif // COBALT_BASE_MESSAGE_QUEUE_H_
diff --git a/src/cobalt/bindings/testing/bindings_test_base.h b/src/cobalt/bindings/testing/bindings_test_base.h
index 25e9ea2..f634699 100644
--- a/src/cobalt/bindings/testing/bindings_test_base.h
+++ b/src/cobalt/bindings/testing/bindings_test_base.h
@@ -25,6 +25,7 @@
#include "cobalt/script/global_environment.h"
#include "cobalt/script/javascript_engine.h"
#include "cobalt/script/source_code.h"
+#include "cobalt/script/wrappable.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -71,6 +72,17 @@
return global_environment_->EvaluateScript(source, out_result);
}
+ bool EvaluateScript(const std::string& script,
+ const scoped_refptr<script::Wrappable>& owning_object,
+ base::optional<script::OpaqueHandleHolder::Reference>*
+ out_opaque_handle = NULL) {
+ scoped_refptr<script::SourceCode> source =
+ script::SourceCode::CreateSourceCode(
+ script, base::SourceLocation("[object BindingsTestBase]", 1, 1));
+ return global_environment_->EvaluateScript(source, owning_object,
+ out_opaque_handle);
+ }
+
void CollectGarbage() { engine_->CollectGarbage(); }
protected:
diff --git a/src/cobalt/bindings/testing/evaluate_script_test.cc b/src/cobalt/bindings/testing/evaluate_script_test.cc
new file mode 100644
index 0000000..61d74fa
--- /dev/null
+++ b/src/cobalt/bindings/testing/evaluate_script_test.cc
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "cobalt/bindings/testing/arbitrary_interface.h"
+#include "cobalt/bindings/testing/bindings_test_base.h"
+#include "cobalt/bindings/testing/object_type_bindings_interface.h"
+#include "cobalt/bindings/testing/script_object_owner.h"
+
+using cobalt::script::OpaqueHandleHolder;
+using ::testing::_;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::StrictMock;
+
+namespace cobalt {
+namespace bindings {
+namespace testing {
+
+namespace {
+class EvaluateScriptTest
+ : public InterfaceBindingsTest<ObjectTypeBindingsInterface> {};
+} // namespace
+
+TEST_F(EvaluateScriptTest, TwoArguments) {
+ std::string result;
+
+ std::string script =
+ "function fib(n) {\n"
+ " if (n <= 0) {\n"
+ " return 0;\n"
+ " } else if (n == 1) {\n"
+ " return 1;\n"
+ " } else {\n"
+ " return fib(n - 1) + fib(n - 2);\n"
+ " }\n"
+ "}\n"
+ "fib(8)";
+ EXPECT_TRUE(EvaluateScript(script, &result));
+ EXPECT_STREQ("21", result.c_str());
+}
+
+TEST_F(EvaluateScriptTest, ThreeArguments) {
+ std::string script =
+ "function fib(n) {\n"
+ " if (n <= 0) {\n"
+ " return 0;\n"
+ " } else if (n == 1) {\n"
+ " return 1;\n"
+ " } else {\n"
+ " return fib(n - 1) + fib(n - 2);\n"
+ " }\n"
+ "}\n"
+ "fib(8)";
+
+ // Call with null out handle.
+ scoped_refptr<StrictMock<ArbitraryInterface> > arbitrary_interface_mock(
+ new StrictMock<ArbitraryInterface>());
+ EXPECT_TRUE(EvaluateScript(script, arbitrary_interface_mock, NULL));
+
+ // Call with non-null, but unset optional handle.
+ base::optional<OpaqueHandleHolder::Reference> opaque_handle;
+ EXPECT_TRUE(EvaluateScript(script, arbitrary_interface_mock, &opaque_handle));
+ ASSERT_FALSE(opaque_handle->referenced_object().IsNull());
+
+ EXPECT_CALL(test_mock(), object_property())
+ .WillOnce(Return(&opaque_handle->referenced_object()));
+ std::string result;
+ EXPECT_TRUE(EvaluateScript("test.objectProperty == 21;", &result));
+ EXPECT_STREQ("true", result.c_str());
+}
+
+} // namespace testing
+} // namespace bindings
+} // namespace cobalt
diff --git a/src/cobalt/bindings/testing/global_constructors_idls_idl_files_list.tmp b/src/cobalt/bindings/testing/global_constructors_idls_idl_files_list.tmp
deleted file mode 100644
index 1f9a3fc..0000000
--- a/src/cobalt/bindings/testing/global_constructors_idls_idl_files_list.tmp
+++ /dev/null
@@ -1,45 +0,0 @@
-AnonymousIndexedGetterInterface.idl
-AnonymousNamedGetterInterface.idl
-AnonymousNamedIndexedGetterInterface.idl
-ArbitraryInterface.idl
-BaseInterface.idl
-BooleanTypeTestInterface.idl
-CallbackFunctionInterface.idl
-CallbackInterfaceInterface.idl
-ConditionalInterface.idl
-ConstantsInterface.idl
-ConstructorInterface.idl
-ConstructorWithArgumentsInterface.idl
-DerivedGetterSetterInterface.idl
-DerivedInterface.idl
-DisabledInterface.idl
-DOMStringTestInterface.idl
-EnumerationInterface.idl
-ExceptionObjectInterface.idl
-ExceptionsInterface.idl
-ExtendedIDLAttributesInterface.idl
-GarbageCollectionTestInterface.idl
-GetOpaqueRootInterface.idl
-GlobalInterfaceParent.idl
-IndexedGetterInterface.idl
-InterfaceWithUnsupportedProperties.idl
-NamedConstructorInterface.idl
-NamedGetterInterface.idl
-NamedIndexedGetterInterface.idl
-NestedPutForwardsInterface.idl
-NoConstructorInterface.idl
-NoInterfaceObjectInterface.idl
-NullableTypesTestInterface.idl
-NumericTypesTestInterface.idl
-ObjectTypeBindingsInterface.idl
-OperationsTestInterface.idl
-PutForwardsInterface.idl
-SingleOperationInterface.idl
-StringifierAnonymousOperationInterface.idl
-StringifierAttributeInterface.idl
-StringifierOperationInterface.idl
-StaticPropertiesInterface.idl
-TargetInterface.idl
-UnionTypesInterface.idl
-Window.idl
-UnsupportedInterface.idl
diff --git a/src/cobalt/bindings/testing/global_objects_idl_files_list.tmp b/src/cobalt/bindings/testing/global_objects_idl_files_list.tmp
deleted file mode 100644
index c1c7594..0000000
--- a/src/cobalt/bindings/testing/global_objects_idl_files_list.tmp
+++ /dev/null
@@ -1,44 +0,0 @@
-AnonymousIndexedGetterInterface.idl
-AnonymousNamedGetterInterface.idl
-AnonymousNamedIndexedGetterInterface.idl
-ArbitraryInterface.idl
-BaseInterface.idl
-BooleanTypeTestInterface.idl
-CallbackFunctionInterface.idl
-CallbackInterfaceInterface.idl
-ConditionalInterface.idl
-ConstantsInterface.idl
-ConstructorInterface.idl
-ConstructorWithArgumentsInterface.idl
-DerivedGetterSetterInterface.idl
-DerivedInterface.idl
-DisabledInterface.idl
-DOMStringTestInterface.idl
-EnumerationInterface.idl
-ExceptionObjectInterface.idl
-ExceptionsInterface.idl
-ExtendedIDLAttributesInterface.idl
-GarbageCollectionTestInterface.idl
-GetOpaqueRootInterface.idl
-GlobalInterfaceParent.idl
-IndexedGetterInterface.idl
-InterfaceWithUnsupportedProperties.idl
-NamedConstructorInterface.idl
-NamedGetterInterface.idl
-NamedIndexedGetterInterface.idl
-NestedPutForwardsInterface.idl
-NoConstructorInterface.idl
-NoInterfaceObjectInterface.idl
-NullableTypesTestInterface.idl
-NumericTypesTestInterface.idl
-ObjectTypeBindingsInterface.idl
-OperationsTestInterface.idl
-PutForwardsInterface.idl
-SingleOperationInterface.idl
-StringifierAnonymousOperationInterface.idl
-StringifierAttributeInterface.idl
-StringifierOperationInterface.idl
-StaticPropertiesInterface.idl
-TargetInterface.idl
-UnionTypesInterface.idl
-Window.idl
diff --git a/src/cobalt/bindings/testing/interfaces_info_individual_static_idl_files_list.tmp b/src/cobalt/bindings/testing/interfaces_info_individual_static_idl_files_list.tmp
deleted file mode 100644
index ff5e547..0000000
--- a/src/cobalt/bindings/testing/interfaces_info_individual_static_idl_files_list.tmp
+++ /dev/null
@@ -1,48 +0,0 @@
-AnonymousIndexedGetterInterface.idl
-AnonymousNamedGetterInterface.idl
-AnonymousNamedIndexedGetterInterface.idl
-ArbitraryInterface.idl
-BaseInterface.idl
-BooleanTypeTestInterface.idl
-CallbackFunctionInterface.idl
-CallbackInterfaceInterface.idl
-ConditionalInterface.idl
-ConstantsInterface.idl
-ConstructorInterface.idl
-ConstructorWithArgumentsInterface.idl
-DerivedGetterSetterInterface.idl
-DerivedInterface.idl
-DisabledInterface.idl
-DOMStringTestInterface.idl
-EnumerationInterface.idl
-ExceptionObjectInterface.idl
-ExceptionsInterface.idl
-ExtendedIDLAttributesInterface.idl
-GarbageCollectionTestInterface.idl
-GetOpaqueRootInterface.idl
-GlobalInterfaceParent.idl
-IndexedGetterInterface.idl
-InterfaceWithUnsupportedProperties.idl
-NamedConstructorInterface.idl
-NamedGetterInterface.idl
-NamedIndexedGetterInterface.idl
-NestedPutForwardsInterface.idl
-NoConstructorInterface.idl
-NoInterfaceObjectInterface.idl
-NullableTypesTestInterface.idl
-NumericTypesTestInterface.idl
-ObjectTypeBindingsInterface.idl
-OperationsTestInterface.idl
-PutForwardsInterface.idl
-SingleOperationInterface.idl
-StringifierAnonymousOperationInterface.idl
-StringifierAttributeInterface.idl
-StringifierOperationInterface.idl
-StaticPropertiesInterface.idl
-TargetInterface.idl
-UnionTypesInterface.idl
-Window.idl
-ImplementedInterface.idl
-PartialInterface.idl
-InterfaceWithUnsupportedProperties_partial.idl
-UnsupportedInterface.idl
diff --git a/src/cobalt/bindings/testing/testing.gyp b/src/cobalt/bindings/testing/testing.gyp
index 0286dcd..e9f6492 100644
--- a/src/cobalt/bindings/testing/testing.gyp
+++ b/src/cobalt/bindings/testing/testing.gyp
@@ -129,6 +129,7 @@
'dependent_interface_test.cc',
'dom_string_bindings_test.cc',
'enumeration_bindings_test.cc',
+ 'evaluate_script_test.cc',
'exceptions_bindings_test.cc',
'extended_attributes_test.cc',
'garbage_collection_test.cc',
diff --git a/src/cobalt/browser/application.cc b/src/cobalt/browser/application.cc
index 27c9f1a..7559d56 100644
--- a/src/cobalt/browser/application.cc
+++ b/src/cobalt/browser/application.cc
@@ -104,7 +104,6 @@
#endif // ENABLE_WEBDRIVER
GURL GetInitialURL() {
-#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
// Allow the user to override the default URL via a command line parameter.
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kInitialURL)) {
@@ -115,7 +114,6 @@
DLOG(INFO) << "URL from parameter is not valid, using default URL.";
}
}
-#endif // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
return GURL(kDefaultURL);
}
diff --git a/src/cobalt/browser/browser_module.cc b/src/cobalt/browser/browser_module.cc
index 692ee5d..73de733 100644
--- a/src/cobalt/browser/browser_module.cc
+++ b/src/cobalt/browser/browser_module.cc
@@ -139,6 +139,9 @@
options.network_module_options),
render_tree_combiner_(renderer_module_.pipeline(),
renderer_module_.render_target()->GetSize()),
+#if defined(ENABLE_SCREENSHOT)
+ screen_shot_writer_(new ScreenShotWriter(renderer_module_.pipeline())),
+#endif // defined(ENABLE_SCREENSHOT)
web_module_loaded_(true /* manually_reset */,
false /* initially_signalled */),
web_module_recreated_callback_(options.web_module_recreated_callback),
@@ -158,9 +161,6 @@
kScreenshotCommandShortHelp, kScreenshotCommandLongHelp)),
#endif // defined(ENABLE_SCREENSHOT)
#endif // defined(ENABLE_DEBUG_CONSOLE)
-#if defined(ENABLE_SCREENSHOT)
- screen_shot_writer_(new ScreenShotWriter(renderer_module_.pipeline())),
-#endif // defined(ENABLE_SCREENSHOT)
ALLOW_THIS_IN_INITIALIZER_LIST(
h5vcc_url_handler_(this, system_window, account_manager)),
web_module_options_(options.web_module_options),
@@ -190,7 +190,7 @@
#if defined(ENABLE_DEBUG_CONSOLE)
debug_console_.reset(new DebugConsole(
- base::Bind(&BrowserModule::OnDebugConsoleRenderTreeProduced,
+ base::Bind(&BrowserModule::QueueOnDebugConsoleRenderTreeProduced,
base::Unretained(this)),
media_module_.get(), &network_module_,
renderer_module_.render_target()->GetSize(),
@@ -239,18 +239,19 @@
}
// Destroy old WebModule first, so we don't get a memory high-watermark after
- // the second WebModule's construtor runs, but before scoped_ptr::reset() is
+ // the second WebModule's constructor runs, but before scoped_ptr::reset() is
// run.
web_module_.reset(NULL);
// Show a splash screen while we're waiting for the web page to load.
const math::Size& viewport_size = renderer_module_.render_target()->GetSize();
DestroySplashScreen();
- splash_screen_.reset(new SplashScreen(
- base::Bind(&BrowserModule::OnRenderTreeProduced, base::Unretained(this)),
- &network_module_, viewport_size,
- renderer_module_.pipeline()->GetResourceProvider(),
- kLayoutMaxRefreshFrequencyInHz));
+ splash_screen_.reset(
+ new SplashScreen(base::Bind(&BrowserModule::QueueOnRenderTreeProduced,
+ base::Unretained(this)),
+ &network_module_, viewport_size,
+ renderer_module_.pipeline()->GetResourceProvider(),
+ kLayoutMaxRefreshFrequencyInHz));
// Create new WebModule.
#if !defined(COBALT_FORCE_CSP)
@@ -270,9 +271,10 @@
options.image_cache_capacity_multiplier_when_playing_video =
COBALT_IMAGE_CACHE_CAPACITY_MULTIPLIER_WHEN_PLAYING_VIDEO;
web_module_.reset(new WebModule(
- url,
- base::Bind(&BrowserModule::OnRenderTreeProduced, base::Unretained(this)),
+ url, base::Bind(&BrowserModule::QueueOnRenderTreeProduced,
+ base::Unretained(this)),
base::Bind(&BrowserModule::OnError, base::Unretained(this)),
+ base::Bind(&BrowserModule::OnWindowClose, base::Unretained(this)),
media_module_.get(), &network_module_, viewport_size,
renderer_module_.pipeline()->GetResourceProvider(),
kLayoutMaxRefreshFrequencyInHz, options));
@@ -282,6 +284,14 @@
}
void BrowserModule::OnLoad() {
+ // Repost to our own message loop if necessary. This also prevents
+ // asynchonrous access to this object by |web_module_| during destruction.
+ if (MessageLoop::current() != self_message_loop_) {
+ self_message_loop_->PostTask(
+ FROM_HERE, base::Bind(&BrowserModule::OnLoad, weak_this_));
+ return;
+ }
+
DestroySplashScreen();
web_module_loaded_.Signal();
}
@@ -303,16 +313,28 @@
}
#endif
+void BrowserModule::ProcessRenderTreeSubmissionQueue() {
+ TRACE_EVENT0("cobalt::browser",
+ "BrowserModule::ProcessRenderTreeSubmissionQueue()");
+ DCHECK_EQ(MessageLoop::current(), self_message_loop_);
+ render_tree_submission_queue_.ProcessAll();
+}
+
+void BrowserModule::QueueOnRenderTreeProduced(
+ const browser::WebModule::LayoutResults& layout_results) {
+ TRACE_EVENT0("cobalt::browser", "BrowserModule::QueueOnRenderTreeProduced()");
+ render_tree_submission_queue_.AddMessage(
+ base::Bind(&BrowserModule::OnRenderTreeProduced, base::Unretained(this),
+ layout_results));
+ self_message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&BrowserModule::ProcessRenderTreeSubmissionQueue, weak_this_));
+}
+
void BrowserModule::OnRenderTreeProduced(
const browser::WebModule::LayoutResults& layout_results) {
TRACE_EVENT0("cobalt::browser", "BrowserModule::OnRenderTreeProduced()");
- if (MessageLoop::current() != self_message_loop_) {
- self_message_loop_->PostTask(
- FROM_HERE,
- base::Bind(&BrowserModule::OnRenderTreeProduced, weak_this_,
- layout_results));
- return;
- }
+ DCHECK_EQ(MessageLoop::current(), self_message_loop_);
renderer::Submission renderer_submission(layout_results.render_tree,
layout_results.layout_time);
@@ -328,6 +350,20 @@
#endif
}
+void BrowserModule::OnWindowClose() {
+#if defined(ENABLE_DEBUG_CONSOLE)
+ if (input_device_manager_fuzzer_) {
+ return;
+ }
+#endif
+
+#if defined(OS_STARBOARD)
+ SbSystemRequestStop(0);
+#else
+ LOG(WARNING) << "window.close is not supported on this platform.";
+#endif
+}
+
#if defined(ENABLE_DEBUG_CONSOLE)
void BrowserModule::OnFuzzerToggle(const std::string& message) {
if (MessageLoop::current() != self_message_loop_) {
@@ -372,17 +408,23 @@
}
}
+void BrowserModule::QueueOnDebugConsoleRenderTreeProduced(
+ const browser::WebModule::LayoutResults& layout_results) {
+ TRACE_EVENT0("cobalt::browser",
+ "BrowserModule::QueueOnDebugConsoleRenderTreeProduced()");
+ render_tree_submission_queue_.AddMessage(
+ base::Bind(&BrowserModule::OnDebugConsoleRenderTreeProduced,
+ base::Unretained(this), layout_results));
+ self_message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&BrowserModule::ProcessRenderTreeSubmissionQueue, weak_this_));
+}
+
void BrowserModule::OnDebugConsoleRenderTreeProduced(
const browser::WebModule::LayoutResults& layout_results) {
TRACE_EVENT0("cobalt::browser",
"BrowserModule::OnDebugConsoleRenderTreeProduced()");
- if (MessageLoop::current() != self_message_loop_) {
- self_message_loop_->PostTask(
- FROM_HERE,
- base::Bind(&BrowserModule::OnDebugConsoleRenderTreeProduced, weak_this_,
- layout_results));
- return;
- }
+ DCHECK_EQ(MessageLoop::current(), self_message_loop_);
render_tree_combiner_.UpdateDebugConsoleRenderTree(renderer::Submission(
layout_results.render_tree, layout_results.layout_time));
diff --git a/src/cobalt/browser/browser_module.h b/src/cobalt/browser/browser_module.h
index df6da73..d589084 100644
--- a/src/cobalt/browser/browser_module.h
+++ b/src/cobalt/browser/browser_module.h
@@ -17,13 +17,14 @@
#ifndef COBALT_BROWSER_BROWSER_MODULE_H_
#define COBALT_BROWSER_BROWSER_MODULE_H_
-#include <list>
#include <string>
+#include <vector>
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "cobalt/account/account_manager.h"
+#include "cobalt/base/message_queue.h"
#include "cobalt/browser/h5vcc_url_handler.h"
#include "cobalt/browser/render_tree_combiner.h"
#include "cobalt/browser/screen_shot_writer.h"
@@ -70,7 +71,7 @@
// Type for a collection of URL handler callbacks that can potentially handle
// a URL before using it to initialize a new WebModule.
- typedef std::list<URLHandler::URLHandlerCallback> URLHandlerCollection;
+ typedef std::vector<URLHandler::URLHandlerCallback> URLHandlerCollection;
BrowserModule(const GURL& url, system_window::SystemWindow* system_window,
account::AccountManager* account_manager,
@@ -126,6 +127,8 @@
// Glue function to deal with the production of the main render tree,
// and will manage handing it off to the renderer.
+ void QueueOnRenderTreeProduced(
+ const browser::WebModule::LayoutResults& layout_results);
void OnRenderTreeProduced(
const browser::WebModule::LayoutResults& layout_results);
@@ -163,6 +166,9 @@
// Destroys the splash screen, if currently displayed.
void DestroySplashScreen();
+ // Called when web module has received window.close.
+ void OnWindowClose();
+
#if defined(ENABLE_DEBUG_CONSOLE)
// Toggles the input fuzzer on/off. Ignores the parameter.
void OnFuzzerToggle(const std::string&);
@@ -173,6 +179,8 @@
// Glue function to deal with the production of the debug console render tree,
// and will manage handing it off to the renderer.
+ void QueueOnDebugConsoleRenderTreeProduced(
+ const browser::WebModule::LayoutResults& layout_results);
void OnDebugConsoleRenderTreeProduced(
const browser::WebModule::LayoutResults& layout_results);
#endif // defined(ENABLE_DEBUG_CONSOLE)
@@ -192,6 +200,9 @@
void OnRendererSubmissionRasterized();
#endif // OS_STARBOARD
+ // Process all messages queued into the |render_tree_submission_queue_|.
+ void ProcessRenderTreeSubmissionQueue();
+
// TODO:
// WeakPtr usage here can be avoided if BrowserModule has a thread to
// own where it can ensure that its tasks are all resolved when it is
@@ -244,6 +255,18 @@
// Manages the two render trees, combines and renders them.
RenderTreeCombiner render_tree_combiner_;
+#if defined(ENABLE_SCREENSHOT)
+ // Helper object to create screen shots of the last layout tree.
+ scoped_ptr<ScreenShotWriter> screen_shot_writer_;
+#endif // defined(ENABLE_SCREENSHOT)
+
+ // Keeps track of all messages containing render tree submissions that will
+ // ultimately reference the |render_tree_combiner_| and the
+ // |renderer_module_|. It is important that this is destroyed before the
+ // above mentioned references are. It must however outlive all WebModules
+ // that may be producing render trees.
+ base::MessageQueue render_tree_submission_queue_;
+
// Sets up everything to do with web page management, from loading and
// parsing the web page and all referenced files to laying it out. The
// web module will ultimately produce a render tree that can be passed
@@ -283,11 +306,6 @@
#endif // defined(ENABLE_SCREENSHOT)
#endif // defined(ENABLE_DEBUG_CONSOLE)
-#if defined(ENABLE_SCREENSHOT)
- // Helper object to create screen shots of the last layout tree.
- scoped_ptr<ScreenShotWriter> screen_shot_writer_;
-#endif // defined(ENABLE_SCREENSHOT)
-
// Handler object for h5vcc URLs.
H5vccURLHandler h5vcc_url_handler_;
diff --git a/src/cobalt/browser/debug_console.cc b/src/cobalt/browser/debug_console.cc
index a293be3..b02557d 100644
--- a/src/cobalt/browser/debug_console.cc
+++ b/src/cobalt/browser/debug_console.cc
@@ -181,9 +181,10 @@
get_debug_server_callback);
web_module_.reset(new WebModule(
GURL(kInitialDebugConsoleUrl), render_tree_produced_callback,
- base::Bind(&DebugConsole::OnError, base::Unretained(this)), media_module,
- network_module, window_dimensions, resource_provider, layout_refresh_rate,
- web_module_options));
+ base::Bind(&DebugConsole::OnError, base::Unretained(this)),
+ base::Closure(), /* window_close_callback */
+ media_module, network_module, window_dimensions, resource_provider,
+ layout_refresh_rate, web_module_options));
}
DebugConsole::~DebugConsole() {}
diff --git a/src/cobalt/browser/global_constructors_idls_idl_files_list.tmp b/src/cobalt/browser/global_constructors_idls_idl_files_list.tmp
deleted file mode 100644
index 7c539ab..0000000
--- a/src/cobalt/browser/global_constructors_idls_idl_files_list.tmp
+++ /dev/null
@@ -1,144 +0,0 @@
-../audio/AudioBuffer.idl
-../audio/AudioBufferSourceNode.idl
-../audio/AudioContext.idl
-../audio/AudioDestinationNode.idl
-../audio/AudioNode.idl
-../cssom/CSSConditionRule.idl
-../cssom/CSSGroupingRule.idl
-../cssom/CSSFontFaceRule.idl
-../cssom/CSSMediaRule.idl
-../cssom/CSSKeyframeRule.idl
-../cssom/CSSKeyframesRule.idl
-../cssom/CSSRule.idl
-../cssom/CSSRuleList.idl
-../cssom/CSSStyleDeclaration.idl
-../cssom/CSSStyleRule.idl
-../cssom/CSSStyleSheet.idl
-../cssom/MediaList.idl
-../cssom/StyleSheet.idl
-../cssom/StyleSheetList.idl
-../debug/DebugHub.idl
-../debug/Debugger.idl
-../debug/DebuggerEventTarget.idl
-../debug/DebugScriptRunner.idl
-../dom/AnimationEvent.idl
-../dom/ArrayBuffer.idl
-../dom/ArrayBufferView.idl
-../dom/Attr.idl
-../dom/Blob.idl
-../dom/CDATASection.idl
-../dom/CharacterData.idl
-../dom/Comment.idl
-../dom/Console.idl
-../dom/Crypto.idl
-../dom/DataView.idl
-../dom/Document.idl
-../dom/DocumentTimeline.idl
-../dom/DocumentType.idl
-../dom/DOMException.idl
-../dom/DOMImplementation.idl
-../dom/DOMParser.idl
-../dom/DOMRect.idl
-../dom/DOMRectList.idl
-../dom/DOMRectReadOnly.idl
-../dom/DOMStringMap.idl
-../dom/DOMTokenList.idl
-../dom/Element.idl
-../dom/Event.idl
-../dom/EventListener.idl
-../dom/EventTarget.idl
-../dom/Float32Array.idl
-../dom/Float64Array.idl
-../dom/FocusEvent.idl
-../dom/History.idl
-../dom/HTMLAnchorElement.idl
-../dom/HTMLBodyElement.idl
-../dom/HTMLBRElement.idl
-../dom/HTMLCollection.idl
-../dom/HTMLDivElement.idl
-../dom/HTMLElement.idl
-../dom/HTMLHeadElement.idl
-../dom/HTMLHeadingElement.idl
-../dom/HTMLHtmlElement.idl
-../dom/HTMLImageElement.idl
-../dom/HTMLLinkElement.idl
-../dom/HTMLMediaElement.idl
-../dom/HTMLMetaElement.idl
-../dom/HTMLParagraphElement.idl
-../dom/HTMLScriptElement.idl
-../dom/HTMLSpanElement.idl
-../dom/HTMLStyleElement.idl
-../dom/HTMLTitleElement.idl
-../dom/HTMLUnknownElement.idl
-../dom/HTMLVideoElement.idl
-../dom/KeyboardEvent.idl
-../dom/Location.idl
-../dom/MediaError.idl
-../dom/MediaKeyCompleteEvent.idl
-../dom/MediaKeyError.idl
-../dom/MediaKeyErrorEvent.idl
-../dom/MediaKeyMessageEvent.idl
-../dom/MediaKeyNeededEvent.idl
-../dom/MediaQueryList.idl
-../dom/MediaSource.idl
-../dom/MimeTypeArray.idl
-../dom/NamedNodeMap.idl
-../dom/Navigator.idl
-../dom/Node.idl
-../dom/NodeList.idl
-../dom/Performance.idl
-../dom/PerformanceTiming.idl
-../dom/PluginArray.idl
-../dom/ProgressEvent.idl
-../dom/Screen.idl
-../dom/SecurityPolicyViolationEvent.idl
-../dom/SourceBuffer.idl
-../dom/SourceBufferList.idl
-../dom/Storage.idl
-../dom/StorageEvent.idl
-../dom/TestRunner.idl
-../dom/Text.idl
-../dom/TimeRanges.idl
-../dom/TransitionEvent.idl
-../dom/UIEvent.idl
-../dom/Uint16Array.idl
-../dom/Uint32Array.idl
-../dom/Uint8Array.idl
-../dom/URL.idl
-../dom/VideoPlaybackQuality.idl
-../dom/Window.idl
-../dom/XMLDocument.idl
-../dom/XMLSerializer.idl
-../h5vcc/dial/DialHttpRequest.idl
-../h5vcc/dial/DialHttpResponse.idl
-../h5vcc/dial/DialServer.idl
-../h5vcc/H5vcc.idl
-../h5vcc/H5vccAccountInfo.idl
-../h5vcc/H5vccAccountManager.idl
-../h5vcc/H5vccAudioConfig.idl
-../h5vcc/H5vccAudioConfigArray.idl
-../h5vcc/H5vccCVal.idl
-../h5vcc/H5vccCValKeyList.idl
-../h5vcc/H5vccDeepLinkEventTarget.idl
-../h5vcc/H5vccRuntime.idl
-../h5vcc/H5vccRuntimeEventTarget.idl
-../h5vcc/H5vccSettings.idl
-../h5vcc/H5vccStorage.idl
-../h5vcc/H5vccSystem.idl
-../speech/SpeechRecognition.idl
-../speech/SpeechRecognitionAlternative.idl
-../speech/SpeechRecognitionError.idl
-../speech/SpeechRecognitionEvent.idl
-../speech/SpeechRecognitionResult.idl
-../speech/SpeechRecognitionResultList.idl
-../web_animations/Animatable.idl
-../web_animations/Animation.idl
-../web_animations/AnimationEffectReadOnly.idl
-../web_animations/AnimationEffectTimingReadOnly.idl
-../web_animations/AnimationTimeline.idl
-../web_animations/Keyframe.idl
-../web_animations/KeyframeEffectReadOnly.idl
-../webdriver/ScriptExecutor.idl
-../xhr/XMLHttpRequest.idl
-../xhr/XMLHttpRequestEventTarget.idl
-../xhr/XMLHttpRequestUpload.idl
diff --git a/src/cobalt/browser/global_objects_idl_files_list.tmp b/src/cobalt/browser/global_objects_idl_files_list.tmp
deleted file mode 100644
index 7c539ab..0000000
--- a/src/cobalt/browser/global_objects_idl_files_list.tmp
+++ /dev/null
@@ -1,144 +0,0 @@
-../audio/AudioBuffer.idl
-../audio/AudioBufferSourceNode.idl
-../audio/AudioContext.idl
-../audio/AudioDestinationNode.idl
-../audio/AudioNode.idl
-../cssom/CSSConditionRule.idl
-../cssom/CSSGroupingRule.idl
-../cssom/CSSFontFaceRule.idl
-../cssom/CSSMediaRule.idl
-../cssom/CSSKeyframeRule.idl
-../cssom/CSSKeyframesRule.idl
-../cssom/CSSRule.idl
-../cssom/CSSRuleList.idl
-../cssom/CSSStyleDeclaration.idl
-../cssom/CSSStyleRule.idl
-../cssom/CSSStyleSheet.idl
-../cssom/MediaList.idl
-../cssom/StyleSheet.idl
-../cssom/StyleSheetList.idl
-../debug/DebugHub.idl
-../debug/Debugger.idl
-../debug/DebuggerEventTarget.idl
-../debug/DebugScriptRunner.idl
-../dom/AnimationEvent.idl
-../dom/ArrayBuffer.idl
-../dom/ArrayBufferView.idl
-../dom/Attr.idl
-../dom/Blob.idl
-../dom/CDATASection.idl
-../dom/CharacterData.idl
-../dom/Comment.idl
-../dom/Console.idl
-../dom/Crypto.idl
-../dom/DataView.idl
-../dom/Document.idl
-../dom/DocumentTimeline.idl
-../dom/DocumentType.idl
-../dom/DOMException.idl
-../dom/DOMImplementation.idl
-../dom/DOMParser.idl
-../dom/DOMRect.idl
-../dom/DOMRectList.idl
-../dom/DOMRectReadOnly.idl
-../dom/DOMStringMap.idl
-../dom/DOMTokenList.idl
-../dom/Element.idl
-../dom/Event.idl
-../dom/EventListener.idl
-../dom/EventTarget.idl
-../dom/Float32Array.idl
-../dom/Float64Array.idl
-../dom/FocusEvent.idl
-../dom/History.idl
-../dom/HTMLAnchorElement.idl
-../dom/HTMLBodyElement.idl
-../dom/HTMLBRElement.idl
-../dom/HTMLCollection.idl
-../dom/HTMLDivElement.idl
-../dom/HTMLElement.idl
-../dom/HTMLHeadElement.idl
-../dom/HTMLHeadingElement.idl
-../dom/HTMLHtmlElement.idl
-../dom/HTMLImageElement.idl
-../dom/HTMLLinkElement.idl
-../dom/HTMLMediaElement.idl
-../dom/HTMLMetaElement.idl
-../dom/HTMLParagraphElement.idl
-../dom/HTMLScriptElement.idl
-../dom/HTMLSpanElement.idl
-../dom/HTMLStyleElement.idl
-../dom/HTMLTitleElement.idl
-../dom/HTMLUnknownElement.idl
-../dom/HTMLVideoElement.idl
-../dom/KeyboardEvent.idl
-../dom/Location.idl
-../dom/MediaError.idl
-../dom/MediaKeyCompleteEvent.idl
-../dom/MediaKeyError.idl
-../dom/MediaKeyErrorEvent.idl
-../dom/MediaKeyMessageEvent.idl
-../dom/MediaKeyNeededEvent.idl
-../dom/MediaQueryList.idl
-../dom/MediaSource.idl
-../dom/MimeTypeArray.idl
-../dom/NamedNodeMap.idl
-../dom/Navigator.idl
-../dom/Node.idl
-../dom/NodeList.idl
-../dom/Performance.idl
-../dom/PerformanceTiming.idl
-../dom/PluginArray.idl
-../dom/ProgressEvent.idl
-../dom/Screen.idl
-../dom/SecurityPolicyViolationEvent.idl
-../dom/SourceBuffer.idl
-../dom/SourceBufferList.idl
-../dom/Storage.idl
-../dom/StorageEvent.idl
-../dom/TestRunner.idl
-../dom/Text.idl
-../dom/TimeRanges.idl
-../dom/TransitionEvent.idl
-../dom/UIEvent.idl
-../dom/Uint16Array.idl
-../dom/Uint32Array.idl
-../dom/Uint8Array.idl
-../dom/URL.idl
-../dom/VideoPlaybackQuality.idl
-../dom/Window.idl
-../dom/XMLDocument.idl
-../dom/XMLSerializer.idl
-../h5vcc/dial/DialHttpRequest.idl
-../h5vcc/dial/DialHttpResponse.idl
-../h5vcc/dial/DialServer.idl
-../h5vcc/H5vcc.idl
-../h5vcc/H5vccAccountInfo.idl
-../h5vcc/H5vccAccountManager.idl
-../h5vcc/H5vccAudioConfig.idl
-../h5vcc/H5vccAudioConfigArray.idl
-../h5vcc/H5vccCVal.idl
-../h5vcc/H5vccCValKeyList.idl
-../h5vcc/H5vccDeepLinkEventTarget.idl
-../h5vcc/H5vccRuntime.idl
-../h5vcc/H5vccRuntimeEventTarget.idl
-../h5vcc/H5vccSettings.idl
-../h5vcc/H5vccStorage.idl
-../h5vcc/H5vccSystem.idl
-../speech/SpeechRecognition.idl
-../speech/SpeechRecognitionAlternative.idl
-../speech/SpeechRecognitionError.idl
-../speech/SpeechRecognitionEvent.idl
-../speech/SpeechRecognitionResult.idl
-../speech/SpeechRecognitionResultList.idl
-../web_animations/Animatable.idl
-../web_animations/Animation.idl
-../web_animations/AnimationEffectReadOnly.idl
-../web_animations/AnimationEffectTimingReadOnly.idl
-../web_animations/AnimationTimeline.idl
-../web_animations/Keyframe.idl
-../web_animations/KeyframeEffectReadOnly.idl
-../webdriver/ScriptExecutor.idl
-../xhr/XMLHttpRequest.idl
-../xhr/XMLHttpRequestEventTarget.idl
-../xhr/XMLHttpRequestUpload.idl
diff --git a/src/cobalt/browser/interfaces_info_individual_static_idl_files_list.tmp b/src/cobalt/browser/interfaces_info_individual_static_idl_files_list.tmp
deleted file mode 100644
index 216f4b4..0000000
--- a/src/cobalt/browser/interfaces_info_individual_static_idl_files_list.tmp
+++ /dev/null
@@ -1,171 +0,0 @@
-../audio/AudioBuffer.idl
-../audio/AudioBufferSourceNode.idl
-../audio/AudioContext.idl
-../audio/AudioDestinationNode.idl
-../audio/AudioNode.idl
-../cssom/CSSConditionRule.idl
-../cssom/CSSGroupingRule.idl
-../cssom/CSSFontFaceRule.idl
-../cssom/CSSMediaRule.idl
-../cssom/CSSKeyframeRule.idl
-../cssom/CSSKeyframesRule.idl
-../cssom/CSSRule.idl
-../cssom/CSSRuleList.idl
-../cssom/CSSStyleDeclaration.idl
-../cssom/CSSStyleRule.idl
-../cssom/CSSStyleSheet.idl
-../cssom/MediaList.idl
-../cssom/StyleSheet.idl
-../cssom/StyleSheetList.idl
-../debug/DebugHub.idl
-../debug/Debugger.idl
-../debug/DebuggerEventTarget.idl
-../debug/DebugScriptRunner.idl
-../dom/AnimationEvent.idl
-../dom/ArrayBuffer.idl
-../dom/ArrayBufferView.idl
-../dom/Attr.idl
-../dom/Blob.idl
-../dom/CDATASection.idl
-../dom/CharacterData.idl
-../dom/Comment.idl
-../dom/Console.idl
-../dom/Crypto.idl
-../dom/DataView.idl
-../dom/Document.idl
-../dom/DocumentTimeline.idl
-../dom/DocumentType.idl
-../dom/DOMException.idl
-../dom/DOMImplementation.idl
-../dom/DOMParser.idl
-../dom/DOMRect.idl
-../dom/DOMRectList.idl
-../dom/DOMRectReadOnly.idl
-../dom/DOMStringMap.idl
-../dom/DOMTokenList.idl
-../dom/Element.idl
-../dom/Event.idl
-../dom/EventListener.idl
-../dom/EventTarget.idl
-../dom/Float32Array.idl
-../dom/Float64Array.idl
-../dom/FocusEvent.idl
-../dom/History.idl
-../dom/HTMLAnchorElement.idl
-../dom/HTMLBodyElement.idl
-../dom/HTMLBRElement.idl
-../dom/HTMLCollection.idl
-../dom/HTMLDivElement.idl
-../dom/HTMLElement.idl
-../dom/HTMLHeadElement.idl
-../dom/HTMLHeadingElement.idl
-../dom/HTMLHtmlElement.idl
-../dom/HTMLImageElement.idl
-../dom/HTMLLinkElement.idl
-../dom/HTMLMediaElement.idl
-../dom/HTMLMetaElement.idl
-../dom/HTMLParagraphElement.idl
-../dom/HTMLScriptElement.idl
-../dom/HTMLSpanElement.idl
-../dom/HTMLStyleElement.idl
-../dom/HTMLTitleElement.idl
-../dom/HTMLUnknownElement.idl
-../dom/HTMLVideoElement.idl
-../dom/KeyboardEvent.idl
-../dom/Location.idl
-../dom/MediaError.idl
-../dom/MediaKeyCompleteEvent.idl
-../dom/MediaKeyError.idl
-../dom/MediaKeyErrorEvent.idl
-../dom/MediaKeyMessageEvent.idl
-../dom/MediaKeyNeededEvent.idl
-../dom/MediaQueryList.idl
-../dom/MediaSource.idl
-../dom/MimeTypeArray.idl
-../dom/NamedNodeMap.idl
-../dom/Navigator.idl
-../dom/Node.idl
-../dom/NodeList.idl
-../dom/Performance.idl
-../dom/PerformanceTiming.idl
-../dom/PluginArray.idl
-../dom/ProgressEvent.idl
-../dom/Screen.idl
-../dom/SecurityPolicyViolationEvent.idl
-../dom/SourceBuffer.idl
-../dom/SourceBufferList.idl
-../dom/Storage.idl
-../dom/StorageEvent.idl
-../dom/TestRunner.idl
-../dom/Text.idl
-../dom/TimeRanges.idl
-../dom/TransitionEvent.idl
-../dom/UIEvent.idl
-../dom/Uint16Array.idl
-../dom/Uint32Array.idl
-../dom/Uint8Array.idl
-../dom/URL.idl
-../dom/VideoPlaybackQuality.idl
-../dom/Window.idl
-../dom/XMLDocument.idl
-../dom/XMLSerializer.idl
-../h5vcc/dial/DialHttpRequest.idl
-../h5vcc/dial/DialHttpResponse.idl
-../h5vcc/dial/DialServer.idl
-../h5vcc/H5vcc.idl
-../h5vcc/H5vccAccountInfo.idl
-../h5vcc/H5vccAccountManager.idl
-../h5vcc/H5vccAudioConfig.idl
-../h5vcc/H5vccAudioConfigArray.idl
-../h5vcc/H5vccCVal.idl
-../h5vcc/H5vccCValKeyList.idl
-../h5vcc/H5vccDeepLinkEventTarget.idl
-../h5vcc/H5vccRuntime.idl
-../h5vcc/H5vccRuntimeEventTarget.idl
-../h5vcc/H5vccSettings.idl
-../h5vcc/H5vccStorage.idl
-../h5vcc/H5vccSystem.idl
-../speech/SpeechRecognition.idl
-../speech/SpeechRecognitionAlternative.idl
-../speech/SpeechRecognitionError.idl
-../speech/SpeechRecognitionEvent.idl
-../speech/SpeechRecognitionResult.idl
-../speech/SpeechRecognitionResultList.idl
-../web_animations/Animatable.idl
-../web_animations/Animation.idl
-../web_animations/AnimationEffectReadOnly.idl
-../web_animations/AnimationEffectTimingReadOnly.idl
-../web_animations/AnimationTimeline.idl
-../web_animations/Keyframe.idl
-../web_animations/KeyframeEffectReadOnly.idl
-../webdriver/ScriptExecutor.idl
-../xhr/XMLHttpRequest.idl
-../xhr/XMLHttpRequestEventTarget.idl
-../xhr/XMLHttpRequestUpload.idl
-../cssom/LinkStyle.idl
-../dom/Document_CSSOM.idl
-../dom/Document_HTML5.idl
-../dom/Document_WebAnimationsAPI.idl
-../dom/Element_CSSOMView.idl
-../dom/Element_DOMParsingAndSerialization.idl
-../dom/ElementCSSInlineStyle.idl
-../dom/GlobalCrypto.idl
-../dom/GlobalEventHandlers.idl
-../dom/HTMLElement_CSSOMView.idl
-../dom/NavigatorID.idl
-../dom/NavigatorLanguage.idl
-../dom/NavigatorPlugins.idl
-../dom/NavigatorStorageUtils.idl
-../dom/NonDocumentTypeChildNode.idl
-../dom/NonElementParentNode.idl
-../dom/ParentNode.idl
-../dom/Performance_HighResolutionTime.idl
-../dom/URLUtils.idl
-../dom/Window_AnimationTiming.idl
-../dom/Window_CSSOM.idl
-../dom/Window_CSSOMView.idl
-../dom/Window_Performance.idl
-../dom/WindowEventHandlers.idl
-../dom/WindowLocalStorage.idl
-../dom/WindowSessionStorage.idl
-../dom/WindowTimers.idl
diff --git a/src/cobalt/browser/splash_screen.cc b/src/cobalt/browser/splash_screen.cc
index 85e55bd..804b92d 100644
--- a/src/cobalt/browser/splash_screen.cc
+++ b/src/cobalt/browser/splash_screen.cc
@@ -37,6 +37,7 @@
web_module_.reset(new WebModule(
options.url, render_tree_produced_callback,
base::Bind(&SplashScreen::OnError, base::Unretained(this)),
+ base::Closure(), /* window_close_callback */
&stub_media_module_, network_module, window_dimensions, resource_provider,
layout_refresh_rate, web_module_options));
}
diff --git a/src/cobalt/browser/switches.cc b/src/cobalt/browser/switches.cc
index b6a41c1..a402253 100644
--- a/src/cobalt/browser/switches.cc
+++ b/src/cobalt/browser/switches.cc
@@ -48,10 +48,6 @@
// Setting this switch causes all certificate errors to be ignored.
const char kIgnoreCertificateErrors[] = "ignore_certificate_errors";
-// Setting this switch defines the startup URL that Cobalt will use. If no
-// value is set, a default URL will be used.
-const char kInitialURL[] = "url";
-
// If this flag is set, input will be continuously generated randomly instead of
// taken from an external input device (like a controller).
const char kInputFuzzer[] = "input_fuzzer";
@@ -105,6 +101,10 @@
// ideally) these images are cached within GPU memory.
const char kImageCacheSizeInBytes[] = "image_cache_size_in_bytes";
+// Setting this switch defines the startup URL that Cobalt will use. If no
+// value is set, a default URL will be used.
+const char kInitialURL[] = "url";
+
// Determines the capacity of the remote typefaces cache which manages all
// typefaces downloaded from a web page.
const char kRemoteTypefaceCacheSizeInBytes[] =
diff --git a/src/cobalt/browser/switches.h b/src/cobalt/browser/switches.h
index 3531931..7d463d0 100644
--- a/src/cobalt/browser/switches.h
+++ b/src/cobalt/browser/switches.h
@@ -30,7 +30,6 @@
extern const char kEnableWebDriver[];
extern const char kExtraWebFileDir[];
extern const char kIgnoreCertificateErrors[];
-extern const char kInitialURL[];
extern const char kInputFuzzer[];
extern const char kNullAudioStreamer[];
extern const char kNullSavegame[];
@@ -46,6 +45,7 @@
#endif // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
extern const char kImageCacheSizeInBytes[];
+extern const char kInitialURL[];
extern const char kRemoteTypefaceCacheSizeInBytes[];
extern const char kScratchSurfaceCacheSizeInBytes[];
extern const char kSkiaCacheSizeInBytes[];
diff --git a/src/cobalt/browser/web_module.cc b/src/cobalt/browser/web_module.cc
index b80a9bd..7932196 100644
--- a/src/cobalt/browser/web_module.cc
+++ b/src/cobalt/browser/web_module.cc
@@ -23,7 +23,6 @@
#include "base/message_loop_proxy.h"
#include "base/optional.h"
#include "base/stringprintf.h"
-#include "cobalt/base/address_sanitizer.h"
#include "cobalt/base/tokens.h"
#include "cobalt/browser/switches.h"
#include "cobalt/browser/web_module_stat_tracker.h"
@@ -321,7 +320,7 @@
data.network_module->cookie_jar(), data.network_module->GetPostSender(),
data.options.location_policy, data.options.csp_enforcement_mode,
base::Bind(&WebModule::Impl::OnCspPolicyChanged, base::Unretained(this)),
- data.options.csp_insecure_allowed_token);
+ data.window_close_callback, data.options.csp_insecure_allowed_token);
DCHECK(window_);
window_weak_ = base::AsWeakPtr(window_.get());
@@ -556,28 +555,22 @@
WebModule::WebModule(
const GURL& initial_url,
const OnRenderTreeProducedCallback& render_tree_produced_callback,
- const OnErrorCallback& error_callback, media::MediaModule* media_module,
- network::NetworkModule* network_module, const math::Size& window_dimensions,
+ const OnErrorCallback& error_callback,
+ const base::Closure& window_close_callback,
+ media::MediaModule* media_module, network::NetworkModule* network_module,
+ const math::Size& window_dimensions,
render_tree::ResourceProvider* resource_provider, float layout_refresh_rate,
const Options& options)
: thread_(options.name.c_str()) {
ConstructionData construction_data(
- initial_url, render_tree_produced_callback, error_callback, media_module,
- network_module, window_dimensions, resource_provider, kDOMMaxElementDepth,
- layout_refresh_rate, options);
-
-#if defined(COBALT_BUILD_TYPE_DEBUG)
- // Non-optimized builds require a bigger stack size.
- const size_t kBaseStackSize = 2 * 1024 * 1024;
-#else
- const size_t kBaseStackSize = 256 * 1024;
-#endif
+ initial_url, render_tree_produced_callback, error_callback,
+ window_close_callback, media_module, network_module, window_dimensions,
+ resource_provider, kDOMMaxElementDepth, layout_refresh_rate, options);
// Start the dedicated thread and create the internal implementation
// object on that thread.
- size_t stack_size = kBaseStackSize + base::kAsanAdditionalStackSize;
thread_.StartWithOptions(
- base::Thread::Options(MessageLoop::TYPE_DEFAULT, stack_size));
+ base::Thread::Options(MessageLoop::TYPE_DEFAULT, kWebModuleStackSize));
DCHECK(message_loop());
message_loop()->PostTask(
diff --git a/src/cobalt/browser/web_module.h b/src/cobalt/browser/web_module.h
index a4742cb..55706e7 100644
--- a/src/cobalt/browser/web_module.h
+++ b/src/cobalt/browser/web_module.h
@@ -27,6 +27,7 @@
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
+#include "cobalt/base/address_sanitizer.h"
#include "cobalt/base/console_commands.h"
#include "cobalt/base/source_location.h"
#include "cobalt/css_parser/parser.h"
@@ -150,6 +151,7 @@
WebModule(const GURL& initial_url,
const OnRenderTreeProducedCallback& render_tree_produced_callback,
const OnErrorCallback& error_callback,
+ const base::Closure& window_close_callback,
media::MediaModule* media_module,
network::NetworkModule* network_module,
const math::Size& window_dimensions,
@@ -180,6 +182,15 @@
debug::DebugServer* GetDebugServer();
#endif // ENABLE_DEBUG_CONSOLE
+#if defined(COBALT_BUILD_TYPE_DEBUG)
+ // Non-optimized builds require a bigger stack size.
+ static const size_t kBaseStackSize = 2 * 1024 * 1024;
+#else
+ static const size_t kBaseStackSize = 256 * 1024;
+#endif
+ static const size_t kWebModuleStackSize =
+ kBaseStackSize + base::kAsanAdditionalStackSize;
+
private:
// Data required to construct a WebModule, initialized in the constructor and
// passed to |Initialize|.
@@ -187,7 +198,9 @@
ConstructionData(
const GURL& initial_url,
const OnRenderTreeProducedCallback& render_tree_produced_callback,
- const OnErrorCallback& error_callback, media::MediaModule* media_module,
+ const OnErrorCallback& error_callback,
+ const base::Closure& window_close_callback,
+ media::MediaModule* media_module,
network::NetworkModule* network_module,
const math::Size& window_dimensions,
render_tree::ResourceProvider* resource_provider,
@@ -196,6 +209,7 @@
: initial_url(initial_url),
render_tree_produced_callback(render_tree_produced_callback),
error_callback(error_callback),
+ window_close_callback(window_close_callback),
media_module(media_module),
network_module(network_module),
window_dimensions(window_dimensions),
@@ -207,6 +221,7 @@
GURL initial_url;
OnRenderTreeProducedCallback render_tree_produced_callback;
OnErrorCallback error_callback;
+ const base::Closure& window_close_callback;
media::MediaModule* media_module;
network::NetworkModule* network_module;
math::Size window_dimensions;
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index f895aef..deb3c7d 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-11333
\ No newline at end of file
+11565
\ No newline at end of file
diff --git a/src/cobalt/build/config/base.gypi b/src/cobalt/build/config/base.gypi
index 3e07aab..7170bcb 100644
--- a/src/cobalt/build/config/base.gypi
+++ b/src/cobalt/build/config/base.gypi
@@ -28,6 +28,12 @@
# Contains the current build configuration.
'cobalt_config%': 'gold',
'cobalt_fastbuild%': 0,
+
+ # Contains the current font package selection. This can be used to trade
+ # font quality, coverage, and latency with smaller font package size.
+ # See content/fonts/README.md for more details.
+ 'cobalt_font_package%': 'unlimited',
+
# Build version number.
'cobalt_version%': 0,
# Contains the name of the hosting OS. The value is defined by gyp_cobalt.
diff --git a/src/cobalt/content/fonts/10megabytes/fonts.xml b/src/cobalt/content/fonts/10megabytes/fonts.xml
new file mode 100644
index 0000000..c0ffb0a
--- /dev/null
+++ b/src/cobalt/content/fonts/10megabytes/fonts.xml
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ NOTE: Families with a "fallback" value of "true" are added to the fallback
+ list, regardless of whether or not they are named. Fallback fonts are chosen
+ based on a match: full BCP-47 language tag including script, then just
+ language, and finally order (the first font containing the glyph). Order of
+ appearance is also the tiebreaker for weight matching.
+
+ The pages attribute indicates which character pages are contained within
+ the font. It is used with character fallback to allow the system to quickly
+ determine that a character cannot appear in a font without requiring the
+ full character map to be loaded into memory. Character pages are zero
+ indexed, and each page contains 256 characters, so character 1000 would be
+ contained within page 3.
+-->
+<familyset version="1">
+ <!-- first font is default -->
+ <family name="sans-serif">
+ <font weight="400" style="normal">Roboto-Regular.ttf</font>
+ </family>
+ <!-- Note that aliases must come after the fonts they reference. -->
+ <alias name="arial" to="sans-serif" />
+ <alias name="helvetica" to="sans-serif" />
+ <alias name="roboto" to="sans-serif" />
+ <alias name="tahoma" to="sans-serif" />
+ <alias name="verdana" to="sans-serif" />
+ <alias name="courier" to="serif-monospace" />
+ <alias name="courier new" to="serif-monospace" />
+ <family name="sans-serif-smallcaps">
+ <font weight="400" style="normal">CarroisGothicSC-Regular.ttf</font>
+ </family>
+ <!-- fallback fonts -->
+ <family name="Noto Naskh Arabic UI" fallback="true" pages="0,6-8,32,37,46,251-254">
+ <font weight="400" style="normal">NotoNaskhArabicUI-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,18-19,45,171,254">
+ <font weight="400" style="normal">NotoSansEthiopic-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,5,32,37,251,254">
+ <font weight="400" style="normal">NotoSansHebrew-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,2-3,14,32,37,254">
+ <font weight="400" style="normal">NotoSansThaiUI-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,5,251,254">
+ <font weight="400" style="normal">NotoSansArmenian-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,5,16,45,254">
+ <font weight="400" style="normal">NotoSansGeorgian-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,2,9,28,32,34,37,168,254">
+ <font weight="400" style="normal">NotoSansDevanagariUI-Regular.ttf</font>
+ </family>
+ <!-- Gujarati should come after Devanagari -->
+ <family fallback="true" pages="0,9-10,32,34,37,168,254">
+ <font weight="400" style="normal">NotoSansGujaratiUI-Regular.ttf</font>
+ </family>
+ <!-- Gurmukhi should come after Devanagari -->
+ <family fallback="true" pages="0,9-10,32,34,37-38,168,254">
+ <font weight="400" style="normal">NotoSansGurmukhiUI-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,9,11,32,34,37,254">
+ <font weight="400" style="normal">NotoSansTamilUI-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,3,9,13,32,34,37,254">
+ <font weight="400" style="normal">NotoSansMalayalamUI-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,9,32,34,37,254">
+ <font weight="400" style="normal">NotoSansBengaliUI-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,9,12,32,34,37,254">
+ <font weight="400" style="normal">NotoSansTeluguUI-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,9,12,32,34,37,254">
+ <font weight="400" style="normal">NotoSansKannadaUI-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,9,11,32,34,37,254">
+ <font weight="400" style="normal">NotoSansOriyaUI-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,9,13,32,34,37,254">
+ <font weight="400" style="normal">NotoSansSinhala-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,23,25,32,37">
+ <font weight="400" style="normal">NotoSansKhmerUI-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,3,14,32,37">
+ <font weight="400" style="normal">NotoSansLaoUI-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,6-7,32,37,253-254">
+ <font weight="400" style="normal">NotoSansThaana-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,3,170">
+ <font weight="400" style="normal">NotoSansCham-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,27,32,37,254">
+ <font weight="400" style="normal">NotoSansBalinese-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,166,254,360-362">
+ <font weight="400" style="normal">NotoSansBamum-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,27,254">
+ <font weight="400" style="normal">NotoSansBatak-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,26,32,169,254">
+ <font weight="400" style="normal">NotoSansBuginese-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,23,254">
+ <font weight="400" style="normal">NotoSansBuhid-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0-3,20-22,24,254">
+ <font weight="400" style="normal">NotoSansCanadianAboriginal-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,19,254">
+ <font weight="400" style="normal">NotoSansCherokee-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0-3,29,44,254">
+ <font weight="400" style="normal">NotoSansCoptic-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,44,254">
+ <font weight="400" style="normal">NotoSansGlagolitic-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,23,254">
+ <font weight="400" style="normal">NotoSansHanunoo-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,32,37,169,254">
+ <font weight="400" style="normal">NotoSansJavanese-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,169,254">
+ <font weight="400" style="normal">NotoSansKayahLi-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,28,37,254">
+ <font weight="400" style="normal">NotoSansLepcha-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,9,25,254">
+ <font weight="400" style="normal">NotoSansLimbu-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,2,164,254">
+ <font weight="400" style="normal">NotoSansLisu-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,6,8,254">
+ <font weight="400" style="normal">NotoSansMandaic-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,170-171,254">
+ <font weight="400" style="normal">NotoSansMeeteiMayek-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,25,254">
+ <font weight="400" style="normal">NotoSansNewTaiLue-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,6-7,32,46,253-254">
+ <font weight="400" style="normal">NotoSansNKo-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,28,254">
+ <font weight="400" style="normal">NotoSansOlChiki-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,169,254">
+ <font weight="400" style="normal">NotoSansRejang-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,32,37,168,254">
+ <font weight="400" style="normal">NotoSansSaurashtra-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,27-28,254">
+ <font weight="400" style="normal">NotoSansSundanese-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,9,32,37,168,254">
+ <font weight="400" style="normal">NotoSansSylotiNagri-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,3,6-7,32,34,37-38,254">
+ <font weight="400" style="normal">NotoSansSyriacEstrangela-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,23,254">
+ <font weight="400" style="normal">NotoSansTagbanwa-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,26,32,34,37,254">
+ <font weight="400" style="normal">NotoSansTaiTham-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,32,37,167,170,254">
+ <font weight="400" style="normal">NotoSansTaiViet-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,15,32,37,254">
+ <font weight="400" style="normal">NotoSansTibetan-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,3,32,45,254">
+ <font weight="400" style="normal">NotoSansTifinagh-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,165-166,254">
+ <font weight="400" style="normal">NotoSansVai-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,160-164,254">
+ <font weight="400" style="normal">NotoSansYi-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="32-43">
+ <font weight="400" style="normal">NotoSansSymbols-Regular-Subsetted.ttf</font>
+ </family>
+ <family fallback="true" lang="ja" pages="0,32,34-35,46-159,249-250,254-255,498,512-523,525-527,530-538,540-543,545-547,550,552,554-559,561,563-568,570,572-573,575-579,582-584,586-594,596-608,610-612,614-618,620,622-625,627-628,630-631,633-638,640,642-646,649-655,658,660-664,666,669-678,681,695-696,760-761">
+ <font weight="400" style="normal">NotoSansJP-Regular.otf</font>
+ </family>
+ <family fallback="true" pages="0,32-33,35-39,41,43,48,50,224,254-255,496-502,4068">
+ <font weight="400" style="normal">NotoEmoji-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,14,17,32,48-51,77-159,172-215,249-250,254-255,260">
+ <font weight="400" style="normal">DroidSansFallback.ttf</font>
+ </family>
+ <!--
+ Tai Le and Mongolian are intentionally kept last, to make sure they don't override
+ the East Asian punctuation for Chinese.
+ -->
+ <family fallback="true" pages="0,16,25,48,254">
+ <font weight="400" style="normal">NotoSansTaiLe-Regular.ttf</font>
+ </family>
+ <family fallback="true" pages="0,24,32,36-37,48,254">
+ <font weight="400" style="normal">NotoSansMongolian-Regular.ttf</font>
+ </family>
+</familyset>
diff --git a/src/cobalt/content/fonts/README.md b/src/cobalt/content/fonts/README.md
index acee96c..5305139 100644
--- a/src/cobalt/content/fonts/README.md
+++ b/src/cobalt/content/fonts/README.md
@@ -1,29 +1,32 @@
-# Generating a minimal font for devices with small space requirements
+## Description
-[GlyphIGo](https://github.com/pettarin/glyphIgo) was used to generate a subset
-of the Roboto font
+This directory contains a few different set of font packages one can select
+to be packaged with cobalt.
-`cobalt/content/fonts` contains a script called `create_minimized_roboto.sh`
-that can help recreate minimized font if needed
+## How to use
-Steps:
+To use this:
-1. `cd src/cobalt/content/fonts`
-1. `./create_minimized_roboto.sh`
-1. Download `fontforge` using apt. `sudo apt install fontforge`
-1. In `fontforge`, navigate the menu: `Encoding`->`Reencode`->`Glyph Order`.
-Scroll to the top, find the first glyph. By spec, this glyph is called
-`.notdef`, and is used when this font is the default font and there glyph for a
-character we're looking for is missing in the file. Often this will be blank
-after the last step, which can be undesired.
-1. Copy `.notdef` glyph from a different font.
- 1. Open a different font.
- 1. Find the `.notdef` glyph.
- 1. Select the glyph without opening it.
- 1. Navigate the menu: `Edit`->`Copy` from the font you want to copy from.
- 1. Switch focus to the minimized font.
- 1. Select `.notdef` glyph.
- 1. Navigate the menu: `Edit`->`Paste`.
-1. Export the font using the menu: `File`->`Generate Fonts...`, make sure that
-the file name is correct.
-1. Fix any errors if found, or if you can.
+1. Select one of the profiles below.
+2. Add a variable named `cobalt_font_package` in your platform's
+`gyp_configuration.gypi` file.
+
+Example:
+
+ 'variables': {
+ 'cobalt_font_package': '10megabytes',
+ }
+
+
+
+## Profiles
+
+1. `10megabytes`: Use this set of fonts if the target space allocated for fonts
+is approximately 10 megabytes. This directory contains DroidSansFallback, which
+will render many Chinese, and Korean characters at lower quality. The benefit
+of using this font is space savings at the cost of reduced quality.
+1. `minimal`: Use this if minimizing space is a goal, and Cobalt should rely
+on web fonts.
+1. `unlimited`: This font set is preferred, and default. This will enable the
+use the fonts with highest quality and coverage, without the network latency of
+fetching fonts from the server.
diff --git a/src/cobalt/content/fonts/CarroisGothicSC-Regular.ttf b/src/cobalt/content/fonts/all_fonts/CarroisGothicSC-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/CarroisGothicSC-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/CarroisGothicSC-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/ComingSoon.ttf b/src/cobalt/content/fonts/all_fonts/ComingSoon.ttf
similarity index 100%
rename from src/cobalt/content/fonts/ComingSoon.ttf
rename to src/cobalt/content/fonts/all_fonts/ComingSoon.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/CutiveMono.ttf b/src/cobalt/content/fonts/all_fonts/CutiveMono.ttf
similarity index 100%
rename from src/cobalt/content/fonts/CutiveMono.ttf
rename to src/cobalt/content/fonts/all_fonts/CutiveMono.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/DancingScript-Bold.ttf b/src/cobalt/content/fonts/all_fonts/DancingScript-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/DancingScript-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/DancingScript-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/DancingScript-Regular.ttf b/src/cobalt/content/fonts/all_fonts/DancingScript-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/DancingScript-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/DancingScript-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/DroidSansFallback.ttf b/src/cobalt/content/fonts/all_fonts/DroidSansFallback.ttf
similarity index 100%
rename from src/cobalt/content/fonts/DroidSansFallback.ttf
rename to src/cobalt/content/fonts/all_fonts/DroidSansFallback.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/DroidSansMono.ttf b/src/cobalt/content/fonts/all_fonts/DroidSansMono.ttf
similarity index 100%
rename from src/cobalt/content/fonts/DroidSansMono.ttf
rename to src/cobalt/content/fonts/all_fonts/DroidSansMono.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/MTLmr3m.ttf b/src/cobalt/content/fonts/all_fonts/MTLmr3m.ttf
similarity index 100%
rename from src/cobalt/content/fonts/MTLmr3m.ttf
rename to src/cobalt/content/fonts/all_fonts/MTLmr3m.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/MinimalRoboto.ttf b/src/cobalt/content/fonts/all_fonts/MinimalRoboto.ttf
similarity index 100%
rename from src/cobalt/content/fonts/MinimalRoboto.ttf
rename to src/cobalt/content/fonts/all_fonts/MinimalRoboto.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NanumGothic.ttf b/src/cobalt/content/fonts/all_fonts/NanumGothic.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NanumGothic.ttf
rename to src/cobalt/content/fonts/all_fonts/NanumGothic.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoEmoji-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoEmoji-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoEmoji-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoEmoji-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoNaskhArabicUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoNaskhArabicUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoNaskhArabicUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoNaskhArabicUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoNaskhArabicUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoNaskhArabicUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoNaskhArabicUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoNaskhArabicUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansArmenian-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansArmenian-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansArmenian-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansArmenian-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansArmenian-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansArmenian-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansArmenian-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansArmenian-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansBalinese-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansBalinese-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansBalinese-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansBalinese-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansBamum-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansBamum-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansBamum-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansBamum-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansBatak-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansBatak-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansBatak-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansBatak-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansBengaliUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansBengaliUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansBengaliUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansBengaliUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansBengaliUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansBengaliUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansBengaliUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansBengaliUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansBuginese-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansBuginese-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansBuginese-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansBuginese-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansBuhid-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansBuhid-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansBuhid-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansBuhid-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansCanadianAboriginal-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansCanadianAboriginal-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansCanadianAboriginal-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansCanadianAboriginal-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansCham-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansCham-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansCham-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansCham-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansCham-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansCham-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansCham-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansCham-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansCherokee-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansCherokee-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansCherokee-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansCherokee-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansCoptic-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansCoptic-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansCoptic-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansCoptic-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansDevanagariUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansDevanagariUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansDevanagariUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansDevanagariUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansDevanagariUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansDevanagariUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansDevanagariUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansDevanagariUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansEthiopic-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansEthiopic-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansEthiopic-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansEthiopic-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansEthiopic-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansEthiopic-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansEthiopic-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansEthiopic-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansGeorgian-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansGeorgian-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansGeorgian-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansGeorgian-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansGeorgian-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansGeorgian-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansGeorgian-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansGeorgian-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansGlagolitic-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansGlagolitic-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansGlagolitic-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansGlagolitic-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansGujaratiUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansGujaratiUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansGujaratiUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansGujaratiUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansGujaratiUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansGujaratiUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansGujaratiUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansGujaratiUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansGurmukhiUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansGurmukhiUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansGurmukhiUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansGurmukhiUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansGurmukhiUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansGurmukhiUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansGurmukhiUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansGurmukhiUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansHanunoo-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansHanunoo-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansHanunoo-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansHanunoo-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansHebrew-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansHebrew-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansHebrew-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansHebrew-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansHebrew-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansHebrew-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansHebrew-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansHebrew-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansJP-Regular.otf b/src/cobalt/content/fonts/all_fonts/NotoSansJP-Regular.otf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansJP-Regular.otf
rename to src/cobalt/content/fonts/all_fonts/NotoSansJP-Regular.otf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansJavanese-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansJavanese-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansJavanese-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansJavanese-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansKR-Regular.otf b/src/cobalt/content/fonts/all_fonts/NotoSansKR-Regular.otf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansKR-Regular.otf
rename to src/cobalt/content/fonts/all_fonts/NotoSansKR-Regular.otf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansKannadaUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansKannadaUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansKannadaUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansKannadaUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansKannadaUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansKannadaUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansKannadaUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansKannadaUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansKayahLi-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansKayahLi-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansKayahLi-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansKayahLi-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansKhmerUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansKhmerUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansKhmerUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansKhmerUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansKhmerUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansKhmerUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansKhmerUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansKhmerUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansLaoUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansLaoUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansLaoUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansLaoUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansLaoUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansLaoUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansLaoUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansLaoUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansLepcha-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansLepcha-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansLepcha-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansLepcha-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansLimbu-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansLimbu-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansLimbu-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansLimbu-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansLisu-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansLisu-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansLisu-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansLisu-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansMalayalamUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansMalayalamUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansMalayalamUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansMalayalamUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansMalayalamUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansMalayalamUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansMalayalamUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansMalayalamUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansMandaic-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansMandaic-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansMandaic-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansMandaic-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansMeeteiMayek-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansMeeteiMayek-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansMeeteiMayek-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansMeeteiMayek-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansMongolian-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansMongolian-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansMongolian-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansMongolian-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansMyanmarUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansMyanmarUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansMyanmarUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansMyanmarUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansMyanmarUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansMyanmarUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansMyanmarUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansMyanmarUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansNKo-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansNKo-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansNKo-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansNKo-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansNewTaiLue-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansNewTaiLue-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansNewTaiLue-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansNewTaiLue-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansOlChiki-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansOlChiki-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansOlChiki-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansOlChiki-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansOriyaUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansOriyaUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansOriyaUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansOriyaUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansOriyaUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansOriyaUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansOriyaUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansOriyaUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansRejang-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansRejang-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansRejang-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansRejang-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansSC-Regular.otf b/src/cobalt/content/fonts/all_fonts/NotoSansSC-Regular.otf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansSC-Regular.otf
rename to src/cobalt/content/fonts/all_fonts/NotoSansSC-Regular.otf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansSaurashtra-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansSaurashtra-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansSaurashtra-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansSaurashtra-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansSinhala-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansSinhala-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansSinhala-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansSinhala-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansSinhala-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansSinhala-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansSinhala-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansSinhala-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansSundanese-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansSundanese-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansSundanese-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansSundanese-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansSylotiNagri-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansSylotiNagri-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansSylotiNagri-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansSylotiNagri-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansSymbols-Regular-Subsetted.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansSymbols-Regular-Subsetted.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansSymbols-Regular-Subsetted.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansSymbols-Regular-Subsetted.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansSyriacEstrangela-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansSyriacEstrangela-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansSyriacEstrangela-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansSyriacEstrangela-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansTC-Regular.otf b/src/cobalt/content/fonts/all_fonts/NotoSansTC-Regular.otf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansTC-Regular.otf
rename to src/cobalt/content/fonts/all_fonts/NotoSansTC-Regular.otf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansTagbanwa-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansTagbanwa-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansTagbanwa-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansTagbanwa-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansTaiLe-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansTaiLe-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansTaiLe-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansTaiLe-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansTaiTham-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansTaiTham-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansTaiTham-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansTaiTham-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansTaiViet-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansTaiViet-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansTaiViet-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansTaiViet-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansTamilUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansTamilUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansTamilUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansTamilUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansTamilUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansTamilUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansTamilUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansTamilUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansTeluguUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansTeluguUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansTeluguUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansTeluguUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansTeluguUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansTeluguUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansTeluguUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansTeluguUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansThaana-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansThaana-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansThaana-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansThaana-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansThaana-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansThaana-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansThaana-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansThaana-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansThaiUI-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansThaiUI-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansThaiUI-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansThaiUI-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansThaiUI-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansThaiUI-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansThaiUI-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansThaiUI-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansTibetan-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansTibetan-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansTibetan-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansTibetan-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansTifinagh-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansTifinagh-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansTifinagh-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansTifinagh-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansVai-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansVai-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansVai-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansVai-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSansYi-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSansYi-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSansYi-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSansYi-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSerif-Bold.ttf b/src/cobalt/content/fonts/all_fonts/NotoSerif-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSerif-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSerif-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSerif-BoldItalic.ttf b/src/cobalt/content/fonts/all_fonts/NotoSerif-BoldItalic.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSerif-BoldItalic.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSerif-BoldItalic.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSerif-Italic.ttf b/src/cobalt/content/fonts/all_fonts/NotoSerif-Italic.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSerif-Italic.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSerif-Italic.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/NotoSerif-Regular.ttf b/src/cobalt/content/fonts/all_fonts/NotoSerif-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/NotoSerif-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/NotoSerif-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/Roboto-Bold.ttf b/src/cobalt/content/fonts/all_fonts/Roboto-Bold.ttf
similarity index 100%
rename from src/cobalt/content/fonts/Roboto-Bold.ttf
rename to src/cobalt/content/fonts/all_fonts/Roboto-Bold.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/Roboto-BoldItalic.ttf b/src/cobalt/content/fonts/all_fonts/Roboto-BoldItalic.ttf
similarity index 100%
rename from src/cobalt/content/fonts/Roboto-BoldItalic.ttf
rename to src/cobalt/content/fonts/all_fonts/Roboto-BoldItalic.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/Roboto-Italic.ttf b/src/cobalt/content/fonts/all_fonts/Roboto-Italic.ttf
similarity index 100%
rename from src/cobalt/content/fonts/Roboto-Italic.ttf
rename to src/cobalt/content/fonts/all_fonts/Roboto-Italic.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/Roboto-Regular.ttf b/src/cobalt/content/fonts/all_fonts/Roboto-Regular.ttf
similarity index 100%
rename from src/cobalt/content/fonts/Roboto-Regular.ttf
rename to src/cobalt/content/fonts/all_fonts/Roboto-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/minimal/fonts.xml b/src/cobalt/content/fonts/minimal/fonts.xml
new file mode 100644
index 0000000..1381b81
--- /dev/null
+++ b/src/cobalt/content/fonts/minimal/fonts.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<familyset version="1">
+ <!-- Ideally, this font should only be used if there are no other fonts in
+ our final image. -->
+ <family name="Minimal Roboto">
+ <font weight="400" style="normal">MinimalRoboto.ttf</font>
+ </family>
+ <family name="sans-serif-smallcaps">
+ <font weight="400" style="normal">CarroisGothicSC-Regular.ttf</font>
+ </family>
+</familyset>
diff --git a/src/cobalt/content/fonts/scripts/README.md b/src/cobalt/content/fonts/scripts/README.md
new file mode 100644
index 0000000..acee96c
--- /dev/null
+++ b/src/cobalt/content/fonts/scripts/README.md
@@ -0,0 +1,29 @@
+# Generating a minimal font for devices with small space requirements
+
+[GlyphIGo](https://github.com/pettarin/glyphIgo) was used to generate a subset
+of the Roboto font
+
+`cobalt/content/fonts` contains a script called `create_minimized_roboto.sh`
+that can help recreate minimized font if needed
+
+Steps:
+
+1. `cd src/cobalt/content/fonts`
+1. `./create_minimized_roboto.sh`
+1. Download `fontforge` using apt. `sudo apt install fontforge`
+1. In `fontforge`, navigate the menu: `Encoding`->`Reencode`->`Glyph Order`.
+Scroll to the top, find the first glyph. By spec, this glyph is called
+`.notdef`, and is used when this font is the default font and there glyph for a
+character we're looking for is missing in the file. Often this will be blank
+after the last step, which can be undesired.
+1. Copy `.notdef` glyph from a different font.
+ 1. Open a different font.
+ 1. Find the `.notdef` glyph.
+ 1. Select the glyph without opening it.
+ 1. Navigate the menu: `Edit`->`Copy` from the font you want to copy from.
+ 1. Switch focus to the minimized font.
+ 1. Select `.notdef` glyph.
+ 1. Navigate the menu: `Edit`->`Paste`.
+1. Export the font using the menu: `File`->`Generate Fonts...`, make sure that
+the file name is correct.
+1. Fix any errors if found, or if you can.
diff --git a/src/cobalt/content/fonts/scripts/Roboto-Regular.ttf b/src/cobalt/content/fonts/scripts/Roboto-Regular.ttf
new file mode 100644
index 0000000..251d6a7
--- /dev/null
+++ b/src/cobalt/content/fonts/scripts/Roboto-Regular.ttf
Binary files differ
diff --git a/src/cobalt/content/fonts/create_minimized_roboto.sh b/src/cobalt/content/fonts/scripts/create_minimized_roboto.sh
similarity index 100%
rename from src/cobalt/content/fonts/create_minimized_roboto.sh
rename to src/cobalt/content/fonts/scripts/create_minimized_roboto.sh
diff --git a/src/cobalt/content/fonts/minimized_roboto_subset_chars.txt b/src/cobalt/content/fonts/scripts/minimized_roboto_subset_chars.txt
similarity index 78%
rename from src/cobalt/content/fonts/minimized_roboto_subset_chars.txt
rename to src/cobalt/content/fonts/scripts/minimized_roboto_subset_chars.txt
index 75498f5..54fdd68 100644
--- a/src/cobalt/content/fonts/minimized_roboto_subset_chars.txt
+++ b/src/cobalt/content/fonts/scripts/minimized_roboto_subset_chars.txt
@@ -1 +1 @@
-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 (),.-/!
\ No newline at end of file
+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ()[]{},.-/!#'"<>:
diff --git a/src/cobalt/content/fonts/fonts.xml b/src/cobalt/content/fonts/unlimited/fonts.xml
similarity index 100%
rename from src/cobalt/content/fonts/fonts.xml
rename to src/cobalt/content/fonts/unlimited/fonts.xml
diff --git a/src/cobalt/debug/debug_web_server.cc b/src/cobalt/debug/debug_web_server.cc
index 0bc80b7..5ec3d06 100644
--- a/src/cobalt/debug/debug_web_server.cc
+++ b/src/cobalt/debug/debug_web_server.cc
@@ -137,10 +137,10 @@
}
DebugWebServer::~DebugWebServer() {
- net::HttpServer* server = server_.get();
- server_->AddRef();
- server_ = NULL;
- http_server_thread_.message_loop()->ReleaseSoon(FROM_HERE, server);
+ // Destroy the server on its own thread then stop the thread.
+ http_server_thread_.message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&DebugWebServer::StopServer, base::Unretained(this)));
http_server_thread_.Stop();
}
@@ -320,5 +320,10 @@
}
}
+void DebugWebServer::StopServer() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ server_ = NULL;
+}
+
} // namespace debug
} // namespace cobalt
diff --git a/src/cobalt/debug/debug_web_server.h b/src/cobalt/debug/debug_web_server.h
index ac2a593..9f55c16 100644
--- a/src/cobalt/debug/debug_web_server.h
+++ b/src/cobalt/debug/debug_web_server.h
@@ -79,11 +79,14 @@
void StartServer(int port);
+ void StopServer();
+
void SendErrorResponseOverWebSocket(int id, const std::string& message);
base::ThreadChecker thread_checker_;
base::Thread http_server_thread_;
scoped_ptr<net::StreamListenSocketFactory> factory_;
+ // net::HttpServer is a ref-counted object, so we have to use scoped_refptr.
scoped_refptr<net::HttpServer> server_;
GetDebugServerCallback get_debug_server_callback_;
diff --git a/src/cobalt/dom/font_cache.h b/src/cobalt/dom/font_cache.h
index 469d8e0..dd74c4e 100644
--- a/src/cobalt/dom/font_cache.h
+++ b/src/cobalt/dom/font_cache.h
@@ -39,20 +39,21 @@
namespace dom {
// The font cache is typically owned by dom::Document and handles the following:
+// - Tracking of font faces, which it uses to determine if a specified
+// font family is local or remote, and for url determination in requesting
+// remote typefaces.
// - Creation and caching of font lists, which it provides to the used
// style provider as requested. Font lists handle most layout-related font
// cache interactions. Layout objects only interact with the font cache
// through their font lists.
-// - Tracking of font faces, which it uses to determine if a specified
-// font family is local or remote, and for url determination in requesting
-// remote typefaces.
// - Retrieval of typefaces, either locally from the resource provider or
-// remotely from the remote typeface cache.
-// - Caching the indices of the glyphs that the typeface provides for specific
-// characters, so that only the first query of a specific font character
-// necessitates the glyph lookup.
-// - Determination of the fallback typeface for a specific character, and
-// caching of that information for subsequent lookups.
+// remotely from the remote typeface cache, and caching of both typefaces
+// and fonts to facilitate sharing of them across font lists.
+// - Determination of the fallback typeface for a specific character using a
+// specific font style, and caching of that information for subsequent
+// lookups.
+// - Creation of glyph buffers, which is accomplished by passing the request
+// to the resource provider.
// NOTE: The font cache is not thread-safe and must only used within a single
// thread.
class FontCache {
diff --git a/src/cobalt/dom/window.cc b/src/cobalt/dom/window.cc
index 3e23ed9..054f995 100644
--- a/src/cobalt/dom/window.cc
+++ b/src/cobalt/dom/window.cc
@@ -39,9 +39,6 @@
#include "cobalt/dom/storage.h"
#include "cobalt/dom/window_timers.h"
#include "cobalt/script/javascript_engine.h"
-#if defined(OS_STARBOARD)
-#include "starboard/system.h"
-#endif
namespace cobalt {
namespace dom {
@@ -85,6 +82,7 @@
const std::string& default_security_policy,
CspEnforcementType csp_enforcement_mode,
const base::Closure& csp_policy_changed_callback,
+ const base::Closure& window_close_callback,
int csp_insecure_allowed_token)
: width_(width),
height_(height),
@@ -123,7 +121,8 @@
new Storage(this, Storage::kLocalStorage, local_storage_database))),
ALLOW_THIS_IN_INITIALIZER_LIST(
session_storage_(new Storage(this, Storage::kSessionStorage, NULL))),
- screen_(new Screen(width, height)) {
+ screen_(new Screen(width, height)),
+ window_close_callback_(window_close_callback) {
#if defined(ENABLE_TEST_RUNNER)
test_runner_ = new TestRunner();
#endif // ENABLE_TEST_RUNNER
@@ -140,11 +139,9 @@
// https://www.w3.org/TR/html5/browsers.html#dom-window-close
void Window::Close() {
-#if defined(OS_STARBOARD)
- SbSystemRequestStop(0);
-#else
- LOG(WARNING) << "window.close is not supported on this platform.";
-#endif
+ if (!window_close_callback_.is_null()) {
+ window_close_callback_.Run();
+ }
}
const scoped_refptr<Navigator>& Window::navigator() const { return navigator_; }
diff --git a/src/cobalt/dom/window.h b/src/cobalt/dom/window.h
index 8240112..7853ada 100644
--- a/src/cobalt/dom/window.h
+++ b/src/cobalt/dom/window.h
@@ -107,6 +107,7 @@
const std::string& default_security_policy,
dom::CspEnforcementType csp_enforcement_mode,
const base::Closure& csp_policy_changed_callback,
+ const base::Closure& window_close_callback,
int csp_insecure_allowed_token = 0);
// Web API: Window
@@ -277,6 +278,8 @@
scoped_refptr<Screen> screen_;
+ base::Closure window_close_callback_;
+
#if defined(ENABLE_TEST_RUNNER)
scoped_refptr<TestRunner> test_runner_;
#endif // ENABLE_TEST_RUNNER
diff --git a/src/cobalt/dom/window_test.cc b/src/cobalt/dom/window_test.cc
index 43650c0..8879146 100644
--- a/src/cobalt/dom/window_test.cc
+++ b/src/cobalt/dom/window_test.cc
@@ -61,7 +61,8 @@
base::Unretained(&mock_error_callback_)),
NULL, network_bridge::PostSender(),
std::string() /* default security policy */, kCspEnforcementEnable,
- base::Closure() /* csp_policy_changed */)) {}
+ base::Closure() /* csp_policy_changed */,
+ base::Closure() /* window_close */)) {}
~WindowTest() OVERRIDE {}
diff --git a/src/cobalt/layout/layout.cc b/src/cobalt/layout/layout.cc
index 46ca1c1..bd61bde 100644
--- a/src/cobalt/layout/layout.cc
+++ b/src/cobalt/layout/layout.cc
@@ -78,7 +78,7 @@
*initial_containing_block = initial_containing_block_creation_results.box;
// Generate boxes.
- {
+ if (document->html()) {
TRACE_EVENT0("cobalt::layout", kBenchmarkStatBoxGeneration);
base::StopWatch stop_watch_box_generation(
LayoutStatTracker::kStopWatchTypeBoxGeneration,
diff --git a/src/cobalt/layout_tests/layout_snapshot.cc b/src/cobalt/layout_tests/layout_snapshot.cc
index 97b7689..5fb8bce 100644
--- a/src/cobalt/layout_tests/layout_snapshot.cc
+++ b/src/cobalt/layout_tests/layout_snapshot.cc
@@ -85,8 +85,9 @@
url, base::Bind(&WebModuleOnRenderTreeProducedCallback, &results,
&run_loop, MessageLoop::current()),
base::Bind(&WebModuleErrorCallback, &run_loop, MessageLoop::current()),
- stub_media_module.get(), &network_module, viewport_size,
- resource_provider, 60.0f, web_module_options);
+ base::Closure() /* window_close_callback */, stub_media_module.get(),
+ &network_module, viewport_size, resource_provider, 60.0f,
+ web_module_options);
run_loop.Run();
diff --git a/src/cobalt/layout_tests/web_platform_tests.cc b/src/cobalt/layout_tests/web_platform_tests.cc
index 14e32ae..d984a55 100644
--- a/src/cobalt/layout_tests/web_platform_tests.cc
+++ b/src/cobalt/layout_tests/web_platform_tests.cc
@@ -176,8 +176,9 @@
url, base::Bind(&WebModuleOnRenderTreeProducedCallback, &results,
&run_loop, MessageLoop::current()),
base::Bind(&WebModuleErrorCallback, &run_loop, MessageLoop::current()),
- media_module.get(), &network_module, kDefaultViewportSize,
- &resource_provider, 60.0f, web_module_options);
+ base::Closure() /* window_close_callback */, media_module.get(),
+ &network_module, kDefaultViewportSize, &resource_provider, 60.0f,
+ web_module_options);
run_loop.Run();
const std::string extract_results =
"document.getElementById(\"__testharness__results__\").textContent;";
diff --git a/src/cobalt/loader/embedded_resources/splash_screen.css b/src/cobalt/loader/embedded_resources/splash_screen.css
index 0af40bf..7602576 100644
--- a/src/cobalt/loader/embedded_resources/splash_screen.css
+++ b/src/cobalt/loader/embedded_resources/splash_screen.css
@@ -4,11 +4,11 @@
}
#splash {
- background-color: #e62d27;
+ background-color: #e62117;
background-image: url("h5vcc-embedded://you_tube_logo.png");
background-position: center center;
background-repeat: no-repeat;
- background-size: 60%;
+ background-size: 100%;
height: 100%;
left: 0;
position: absolute;
diff --git a/src/cobalt/loader/embedded_resources/you_tube_logo.png b/src/cobalt/loader/embedded_resources/you_tube_logo.png
index 0d2082d..a964097 100644
--- a/src/cobalt/loader/embedded_resources/you_tube_logo.png
+++ b/src/cobalt/loader/embedded_resources/you_tube_logo.png
Binary files differ
diff --git a/src/cobalt/media/media_module_starboard.cc b/src/cobalt/media/media_module_starboard.cc
index 4c54544..f4cf154 100644
--- a/src/cobalt/media/media_module_starboard.cc
+++ b/src/cobalt/media/media_module_starboard.cc
@@ -16,21 +16,14 @@
#include "cobalt/media/media_module.h"
-#include "base/bind.h"
#include "base/compiler_specific.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/math/size.h"
#include "cobalt/media/shell_media_platform_starboard.h"
#include "cobalt/system_window/starboard/system_window.h"
-#include "media/audio/null_audio_streamer.h"
-#include "media/audio/shell_audio_sink.h"
#include "media/base/filter_collection.h"
#include "media/base/media_log.h"
#include "media/base/message_loop_factory.h"
-#include "media/filters/shell_audio_decoder_impl.h"
-#include "media/filters/shell_raw_audio_decoder_stub.h"
-#include "media/filters/shell_raw_video_decoder_stub.h"
-#include "media/filters/shell_video_decoder_impl.h"
#include "media/player/web_media_player_impl.h"
#include "starboard/media.h"
#include "starboard/window.h"
@@ -76,14 +69,6 @@
message_loop_factory->GetMessageLoop(MessageLoopFactory::kPipeline);
scoped_ptr<FilterCollection> filter_collection(new FilterCollection);
- ::media::ShellAudioStreamer* streamer = NULL;
- if (options_.use_null_audio_streamer) {
- DLOG(INFO) << "Use Null audio";
- streamer = ::media::NullAudioStreamer::GetInstance();
- } else {
- DLOG(INFO) << "Use Pulse audio";
- streamer = ::media::ShellAudioStreamer::Instance();
- }
SbWindow window = kSbWindowInvalid;
if (system_window_) {
window = polymorphic_downcast<SystemWindowStarboard*>(system_window_)
@@ -91,8 +76,8 @@
}
return make_scoped_ptr<WebMediaPlayer>(new ::media::WebMediaPlayerImpl(
window, client, this, media_platform_.GetVideoFrameProvider(),
- filter_collection.Pass(), new ::media::ShellAudioSink(streamer),
- message_loop_factory.Pass(), new ::media::MediaLog));
+ filter_collection.Pass(), NULL, message_loop_factory.Pass(),
+ new ::media::MediaLog));
}
private:
diff --git a/src/cobalt/render_tree/node_visitor_test.cc b/src/cobalt/render_tree/node_visitor_test.cc
index ad7c3b2..cc6a84f 100644
--- a/src/cobalt/render_tree/node_visitor_test.cc
+++ b/src/cobalt/render_tree/node_visitor_test.cc
@@ -101,7 +101,7 @@
}
};
-void SetBounds(const cobalt::math::Rect&) {}
+bool SetBounds(const cobalt::math::Rect&) { return false; }
} // namespace
diff --git a/src/cobalt/render_tree/punch_through_video_node.h b/src/cobalt/render_tree/punch_through_video_node.h
index 7261ab7..22dd0f9 100644
--- a/src/cobalt/render_tree/punch_through_video_node.h
+++ b/src/cobalt/render_tree/punch_through_video_node.h
@@ -41,7 +41,7 @@
// support punch out video rendering.
class PunchThroughVideoNode : public Node {
public:
- typedef base::Callback<void(const math::Rect&)> SetBoundsCB;
+ typedef base::Callback<bool(const math::Rect&)> SetBoundsCB;
struct Builder {
Builder(const math::RectF& rect, const SetBoundsCB& set_bounds_cb)
diff --git a/src/cobalt/renderer/copy_font_data.gypi b/src/cobalt/renderer/copy_font_data.gypi
index 2ce0512..405ad41 100644
--- a/src/cobalt/renderer/copy_font_data.gypi
+++ b/src/cobalt/renderer/copy_font_data.gypi
@@ -17,15 +17,192 @@
{
'includes': [ '../build/contents_dir.gypi' ],
-
'variables': {
- 'fonts_dir': '<(static_contents_source_dir)/fonts',
+ 'source_all_fonts_dir': '<(static_contents_source_dir)/fonts/all_fonts',
},
'copies': [
{
- 'destination': '<(static_contents_output_data_dir)',
- 'files': [ '<@(fonts_dir)' ],
+ 'destination': '<(static_contents_output_data_dir)/fonts/',
+ 'files': [
+ '<(static_contents_source_dir)/fonts/<(cobalt_font_package)/fonts.xml',
+ ],
+ 'conditions': [
+ [ 'cobalt_font_package == "minimal"', {
+ 'files+': [
+ '<(source_all_fonts_dir)/MinimalRoboto.ttf',
+ '<(source_all_fonts_dir)/CarroisGothicSC-Regular.ttf',
+ ],
+ }], # minimal
+ [ 'cobalt_font_package == "10megabytes"', {
+ 'files+': [
+ '<(source_all_fonts_dir)/NotoSansTagbanwa-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansSinhala-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansNewTaiLue-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansSundanese-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansMandaic-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansGurmukhiUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansDevanagariUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansMongolian-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansBamum-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansBuhid-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansCherokee-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansArmenian-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansJP-Regular.otf',
+ '<(source_all_fonts_dir)/NotoSansEthiopic-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansGlagolitic-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansBatak-Regular.ttf',
+ '<(source_all_fonts_dir)/Roboto-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoNaskhArabicUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansBuginese-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansVai-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTifinagh-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansCham-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansJavanese-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTeluguUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTaiLe-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansMeeteiMayek-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansKannadaUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansSyriacEstrangela-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansBengaliUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansThaiUI-Regular.ttf',
+ '<(source_all_fonts_dir)/CarroisGothicSC-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansNKo-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansGeorgian-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansSymbols-Regular-Subsetted.ttf',
+ '<(source_all_fonts_dir)/NotoSansCoptic-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansYi-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTaiTham-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansOlChiki-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansOriyaUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansSylotiNagri-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansRejang-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansCanadianAboriginal-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansLisu-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTibetan-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansKayahLi-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansLaoUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansHanunoo-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTaiViet-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansHebrew-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansBalinese-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTamilUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansGujaratiUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansMalayalamUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansLepcha-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoEmoji-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansThaana-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansKhmerUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansSaurashtra-Regular.ttf',
+ '<(source_all_fonts_dir)/DroidSansFallback.ttf',
+ '<(source_all_fonts_dir)/NotoSansLimbu-Regular.ttf',
+ ],
+ }], # 10megabytes
+ [ 'cobalt_font_package == "unlimited"', {
+ 'files+': [
+ '<(source_all_fonts_dir)/NotoSansTagbanwa-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansSinhala-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansNewTaiLue-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansSundanese-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansMandaic-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSerif-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansTeluguUI-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansMyanmarUI-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansGurmukhiUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansDevanagariUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansMongolian-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansArmenian-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansBamum-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansBuhid-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansEthiopic-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansDevanagariUI-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansCherokee-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansArmenian-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansJP-Regular.otf',
+ '<(source_all_fonts_dir)/NotoSansOriyaUI-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansEthiopic-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansGlagolitic-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansBatak-Regular.ttf',
+ '<(source_all_fonts_dir)/Roboto-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTC-Regular.otf',
+ '<(source_all_fonts_dir)/NotoSerif-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoNaskhArabicUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansBuginese-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansVai-Regular.ttf',
+ '<(source_all_fonts_dir)/MTLmr3m.ttf',
+ '<(source_all_fonts_dir)/NanumGothic.ttf',
+ '<(source_all_fonts_dir)/ComingSoon.ttf',
+ '<(source_all_fonts_dir)/NotoSansTifinagh-Regular.ttf',
+ '<(source_all_fonts_dir)/DancingScript-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansCham-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansSC-Regular.otf',
+ '<(source_all_fonts_dir)/NotoSansHebrew-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansJavanese-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTeluguUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTaiLe-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansMeeteiMayek-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansKannadaUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansKhmerUI-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansSyriacEstrangela-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSerif-BoldItalic.ttf',
+ '<(source_all_fonts_dir)/NotoSansBengaliUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansThaiUI-Regular.ttf',
+ '<(source_all_fonts_dir)/CutiveMono.ttf',
+ '<(source_all_fonts_dir)/DroidSansMono.ttf',
+ '<(source_all_fonts_dir)/CarroisGothicSC-Regular.ttf',
+ '<(source_all_fonts_dir)/Roboto-Italic.ttf',
+ '<(source_all_fonts_dir)/NotoSansNKo-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansGeorgian-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansSymbols-Regular-Subsetted.ttf',
+ '<(source_all_fonts_dir)/NotoSansCoptic-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansYi-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTaiTham-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansMyanmarUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansMalayalamUI-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansGujaratiUI-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansLaoUI-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansOlChiki-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansOriyaUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansSylotiNagri-Regular.ttf',
+ '<(source_all_fonts_dir)/Roboto-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansRejang-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansThaiUI-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansCanadianAboriginal-Regular.ttf',
+ '<(source_all_fonts_dir)/Roboto-BoldItalic.ttf',
+ '<(source_all_fonts_dir)/NotoSansLisu-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTibetan-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansKayahLi-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansLaoUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansHanunoo-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTaiViet-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansKannadaUI-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansSinhala-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSerif-Italic.ttf',
+ '<(source_all_fonts_dir)/NotoSansGurmukhiUI-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansHebrew-Regular.ttf',
+ '<(source_all_fonts_dir)/DancingScript-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansBalinese-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTamilUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansGujaratiUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansGeorgian-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansMalayalamUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansLepcha-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoEmoji-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansTamilUI-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansThaana-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansKhmerUI-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansSaurashtra-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoSansKR-Regular.otf',
+ '<(source_all_fonts_dir)/NotoSansCham-Bold.ttf',
+ '<(source_all_fonts_dir)/DroidSansFallback.ttf',
+ '<(source_all_fonts_dir)/NotoSansBengaliUI-Bold.ttf',
+ '<(source_all_fonts_dir)/MinimalRoboto.ttf',
+ '<(source_all_fonts_dir)/NotoSansLimbu-Regular.ttf',
+ '<(source_all_fonts_dir)/NotoNaskhArabicUI-Bold.ttf',
+ '<(source_all_fonts_dir)/NotoSansThaana-Bold.ttf',
+ ],
+ }], # unlimited
+ ],
},
],
}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_nv12.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_nv12.glsl
index 6fcae22..0a0d63b 100644
--- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_nv12.glsl
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_nv12.glsl
@@ -11,7 +11,7 @@
// Stage 0: YUV to RGB
output_Stage0 = vec4(
texture2D(uSampler0_Stage0, vMatrixCoord_Stage0).aaaa.r,
- texture2D(uSampler1_Stage0, vMatrixCoord_Stage0).ba,
+ texture2D(uSampler1_Stage0, vMatrixCoord_Stage0).ra,
1.0) * uYUVMatrix_Stage0;
}
gl_FragColor = output_Stage0;
diff --git a/src/cobalt/renderer/rasterizer/blitter/render_tree_node_visitor.cc b/src/cobalt/renderer/rasterizer/blitter/render_tree_node_visitor.cc
index 12475b8..d0f5377 100644
--- a/src/cobalt/renderer/rasterizer/blitter/render_tree_node_visitor.cc
+++ b/src/cobalt/renderer/rasterizer/blitter/render_tree_node_visitor.cc
@@ -240,18 +240,23 @@
void RenderTreeNodeVisitor::Visit(
render_tree::PunchThroughVideoNode* punch_through_video_node) {
- SbBlitterSetColor(context_, SbBlitterColorFromRGBA(0, 0, 0, 0));
- SbBlitterSetBlending(context_, false);
SbBlitterRect blitter_rect =
RectFToBlitterRect(render_state_.transform.TransformRect(
punch_through_video_node->data().rect));
- SbBlitterFillRect(context_, blitter_rect);
- if (!punch_through_video_node->data().set_bounds_cb.is_null()) {
- punch_through_video_node->data().set_bounds_cb.Run(
- math::Rect(blitter_rect.x, blitter_rect.y, blitter_rect.width,
- blitter_rect.height));
+ if (punch_through_video_node->data().set_bounds_cb.is_null()) {
+ return;
}
+ bool render_punch_through =
+ punch_through_video_node->data().set_bounds_cb.Run(
+ math::Rect(blitter_rect.x, blitter_rect.y, blitter_rect.width,
+ blitter_rect.height));
+ if (!render_punch_through) {
+ return;
+ }
+ SbBlitterSetColor(context_, SbBlitterColorFromRGBA(0, 0, 0, 0));
+ SbBlitterSetBlending(context_, false);
+ SbBlitterFillRect(context_, blitter_rect);
}
namespace {
diff --git a/src/cobalt/renderer/rasterizer/pixel_test.cc b/src/cobalt/renderer/rasterizer/pixel_test.cc
index 6dc87b7..6f821ed 100644
--- a/src/cobalt/renderer/rasterizer/pixel_test.cc
+++ b/src/cobalt/renderer/rasterizer/pixel_test.cc
@@ -113,7 +113,7 @@
namespace {
-void SetBounds(const math::Rect&) {}
+bool SetBounds(bool result, const math::Rect&) { return result; }
} // namespace
@@ -2749,14 +2749,30 @@
RoundedCorners(50, 50)));
}
-TEST_F(PixelTest, PunchThroughVideoNodePunchesThrough) {
+// If SetBoundsCB() returns false, the PunchThroughVideoNode should have no
+// effect.
+TEST_F(PixelTest, PunchThroughVideoNodePunchesThroughSetBoundsCBReturnsFalse) {
CompositionNode::Builder builder;
builder.AddChild(new RectNode(RectF(25, 25, 150, 150),
scoped_ptr<Brush>(new SolidColorBrush(
ColorRGBA(0.5f, 0.5f, 1.0f, 1.0f)))));
builder.AddChild(new PunchThroughVideoNode(PunchThroughVideoNode::Builder(
- RectF(50, 50, 100, 100), base::Bind(SetBounds))));
+ RectF(50, 50, 100, 100), base::Bind(SetBounds, false))));
+
+ TestTree(new CompositionNode(builder.Pass()));
+}
+
+// If SetBoundsCB() returns true, the PunchThroughVideoNode should trigger the
+// painting of a solid rectangle with RGBA(0, 0, 0, 0).
+TEST_F(PixelTest, PunchThroughVideoNodePunchesThroughSetBoundsCBReturnsTrue) {
+ CompositionNode::Builder builder;
+ builder.AddChild(new RectNode(RectF(25, 25, 150, 150),
+ scoped_ptr<Brush>(new SolidColorBrush(
+ ColorRGBA(0.5f, 0.5f, 1.0f, 1.0f)))));
+
+ builder.AddChild(new PunchThroughVideoNode(PunchThroughVideoNode::Builder(
+ RectF(50, 50, 100, 100), base::Bind(SetBounds, true))));
TestTree(new CompositionNode(builder.Pass()));
}
diff --git a/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.cc b/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.cc
index b0b493f..ab9fc7d 100644
--- a/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.cc
+++ b/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.cc
@@ -697,9 +697,6 @@
const math::RectF& math_rect = punch_through_video_node->data().rect;
- SkPaint paint;
- paint.setXfermodeMode(SkXfermode::kSrc_Mode);
- paint.setARGB(0, 0, 0, 0);
SkRect sk_rect = SkRect::MakeXYWH(math_rect.x(), math_rect.y(),
math_rect.width(), math_rect.height());
SkMatrix total_matrix = draw_state_.render_target->getTotalMatrix();
@@ -707,13 +704,22 @@
SkRect sk_rect_transformed;
total_matrix.mapRect(&sk_rect_transformed, sk_rect);
- if (!punch_through_video_node->data().set_bounds_cb.is_null()) {
- punch_through_video_node->data().set_bounds_cb.Run(
- math::Rect(static_cast<int>(sk_rect_transformed.x()),
- static_cast<int>(sk_rect_transformed.y()),
- static_cast<int>(sk_rect_transformed.width()),
- static_cast<int>(sk_rect_transformed.height())));
+ if (punch_through_video_node->data().set_bounds_cb.is_null()) {
+ return;
}
+ bool render_punch_through =
+ punch_through_video_node->data().set_bounds_cb.Run(
+ math::Rect(static_cast<int>(sk_rect_transformed.x()),
+ static_cast<int>(sk_rect_transformed.y()),
+ static_cast<int>(sk_rect_transformed.width()),
+ static_cast<int>(sk_rect_transformed.height())));
+ if (!render_punch_through) {
+ return;
+ }
+
+ SkPaint paint;
+ paint.setXfermodeMode(SkXfermode::kSrc_Mode);
+ paint.setARGB(0, 0, 0, 0);
draw_state_.render_target->drawRect(sk_rect, paint);
diff --git a/src/cobalt/renderer/rasterizer/testdata/PunchThroughVideoNodePunchesThroughSetBoundsCBReturnsFalse-expected.png b/src/cobalt/renderer/rasterizer/testdata/PunchThroughVideoNodePunchesThroughSetBoundsCBReturnsFalse-expected.png
new file mode 100644
index 0000000..d26f087
--- /dev/null
+++ b/src/cobalt/renderer/rasterizer/testdata/PunchThroughVideoNodePunchesThroughSetBoundsCBReturnsFalse-expected.png
Binary files differ
diff --git a/src/cobalt/renderer/rasterizer/testdata/PunchThroughVideoNodePunchesThrough-expected.png b/src/cobalt/renderer/rasterizer/testdata/PunchThroughVideoNodePunchesThroughSetBoundsCBReturnsTrue-expected.png
similarity index 100%
rename from src/cobalt/renderer/rasterizer/testdata/PunchThroughVideoNodePunchesThrough-expected.png
rename to src/cobalt/renderer/rasterizer/testdata/PunchThroughVideoNodePunchesThroughSetBoundsCBReturnsTrue-expected.png
Binary files differ
diff --git a/src/cobalt/script/mozjs/conversion_helpers.h b/src/cobalt/script/mozjs/conversion_helpers.h
index 3d54ec6..19a8ec8 100644
--- a/src/cobalt/script/mozjs/conversion_helpers.h
+++ b/src/cobalt/script/mozjs/conversion_helpers.h
@@ -71,7 +71,6 @@
size_t length = in_string.length();
jschar* inflated_buffer =
js::InflateUTF8String(context, in_string.c_str(), &length);
- DCHECK(inflated_buffer);
if (!inflated_buffer) {
LOG(ERROR) << "Failed to inflate UTF8 string.";
diff --git a/src/cobalt/script/mozjs/mozjs.gyp b/src/cobalt/script/mozjs/mozjs.gyp
index b29d99b..6e856f5 100644
--- a/src/cobalt/script/mozjs/mozjs.gyp
+++ b/src/cobalt/script/mozjs/mozjs.gyp
@@ -73,5 +73,30 @@
'<(DEPTH)/third_party/mozjs/mozjs.gyp:mozjs_lib',
],
},
+
+ {
+ 'target_name': 'mozjs_engine_test',
+ 'type': '<(gtest_target_type)',
+ 'sources': [
+ '<(DEPTH)/third_party/mozjs/test/jscustomallocator_test.cc',
+ ],
+ 'dependencies': [
+ '<(DEPTH)/base/base.gyp:run_all_unittests',
+ '<(DEPTH)/testing/gtest.gyp:gtest',
+ '<(DEPTH)/third_party/mozjs/mozjs.gyp:mozjs_lib',
+ ],
+ },
+
+ {
+ 'target_name': 'mozjs_engine_test_deploy',
+ 'type': 'none',
+ 'dependencies': [
+ 'mozjs_engine_test',
+ ],
+ 'variables': {
+ 'executable_name': 'mozjs_engine_test',
+ },
+ 'includes': [ '../../../starboard/build/deploy.gypi' ],
+ },
],
}
diff --git a/src/cobalt/script/mozjs/mozjs_engine.cc b/src/cobalt/script/mozjs/mozjs_engine.cc
index 1b79cf7..39f47bb 100644
--- a/src/cobalt/script/mozjs/mozjs_engine.cc
+++ b/src/cobalt/script/mozjs/mozjs_engine.cc
@@ -19,7 +19,11 @@
#include <algorithm>
#include "base/logging.h"
+#include "cobalt/base/c_val.h"
+#include "cobalt/base/poller.h"
+#include "cobalt/browser/web_module.h"
#include "cobalt/script/mozjs/mozjs_global_environment.h"
+#include "third_party/mozjs/cobalt_config/include/jscustomallocator.h"
#include "third_party/mozjs/js/src/jsapi.h"
namespace cobalt {
@@ -38,6 +42,64 @@
CheckAccessStub,
MozjsGlobalEnvironment::CheckEval
};
+
+#if defined(__LB_SHELL__FOR_RELEASE__)
+const int kPollerPeriodMs = 2000;
+#else // #if defined(__LB_SHELL__FOR_RELEASE__)
+const int kPollerPeriodMs = 20;
+#endif // #if defined(__LB_SHELL__FOR_RELEASE__)
+
+class EngineStats {
+ public:
+ EngineStats();
+
+ static EngineStats* GetInstance() {
+ return Singleton<EngineStats,
+ StaticMemorySingletonTraits<EngineStats> >::get();
+ }
+
+ void EngineCreated() {
+ base::AutoLock auto_lock(lock_);
+ ++engine_count_;
+ }
+
+ void EngineDestroyed() {
+ base::AutoLock auto_lock(lock_);
+ --engine_count_;
+ }
+
+ void Update() {
+ base::AutoLock auto_lock(lock_);
+ allocated_memory_ =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ mapped_memory_ = MemoryAllocatorReporter::Get()->GetCurrentBytesMapped();
+ memory_sum_ = allocated_memory_ + mapped_memory_;
+ }
+
+ private:
+ base::Lock lock_;
+ base::CVal<size_t, base::CValPublic> allocated_memory_;
+ base::CVal<size_t, base::CValPublic> mapped_memory_;
+ base::CVal<size_t, base::CValPublic> memory_sum_;
+ base::CVal<size_t> engine_count_;
+
+ // Repeating timer to query the used bytes.
+ scoped_ptr<base::PollerWithThread> poller_;
+};
+
+EngineStats::EngineStats()
+ : allocated_memory_("Memory.JS.AllocatedMemory", 0,
+ "JS memory occupied by the Mozjs allocator."),
+ mapped_memory_("Memory.JS.MappedMemory", 0, "JS mapped memory."),
+ memory_sum_("Memory.JS", 0,
+ "Total memory occupied by the Mozjs allocator and heap."),
+ engine_count_("Count.JS.Engine", 0,
+ "Total JavaScript engine registered.") {
+ poller_.reset(new base::PollerWithThread(
+ base::Bind(&EngineStats::Update, base::Unretained(this)),
+ base::TimeDelta::FromMilliseconds(kPollerPeriodMs)));
+}
+
} // namespace
MozjsEngine::MozjsEngine() {
@@ -47,6 +109,12 @@
JS_NewRuntime(kGarbageCollectionThresholdBytes, JS_NO_HELPER_THREADS);
CHECK(runtime_);
+ // Sets the size of the native stack that should not be exceeded.
+ // Setting three quarters of the web module stack size to ensure that native
+ // stack won't exceed the stack size.
+ JS_SetNativeStackQuota(runtime_,
+ browser::WebModule::kWebModuleStackSize / 4 * 3);
+
JS_SetRuntimePrivate(runtime_, this);
JS_SetSecurityCallbacks(runtime_, &security_callbacks);
@@ -68,10 +136,13 @@
// Callback to be called during garbage collection during the sweep phase.
JS_SetFinalizeCallback(runtime_, &MozjsEngine::FinalizeCallback);
+
+ EngineStats::GetInstance()->EngineCreated();
}
MozjsEngine::~MozjsEngine() {
DCHECK(thread_checker_.CalledOnValidThread());
+ EngineStats::GetInstance()->EngineDestroyed();
JS_DestroyRuntime(runtime_);
}
diff --git a/src/cobalt/script/mozjs/mozjs_global_environment.cc b/src/cobalt/script/mozjs/mozjs_global_environment.cc
index 25fa34b..9a79991 100644
--- a/src/cobalt/script/mozjs/mozjs_global_environment.cc
+++ b/src/cobalt/script/mozjs/mozjs_global_environment.cc
@@ -195,33 +195,16 @@
const scoped_refptr<SourceCode>& source_code,
std::string* out_result_utf8) {
DCHECK(thread_checker_.CalledOnValidThread());
- MozjsSourceCode* mozjs_source_code =
- base::polymorphic_downcast<MozjsSourceCode*>(source_code.get());
-
- const std::string& script = mozjs_source_code->source_utf8();
- const base::SourceLocation location = mozjs_source_code->location();
JSAutoRequest auto_request(context_);
JSAutoCompartment auto_compartment(context_, global_object_proxy_);
JSExceptionState* previous_exception_state = JS_SaveExceptionState(context_);
JS::RootedValue result_value(context_);
+
std::string error_message;
last_error_message_ = &error_message;
- JS::RootedObject global_object(
- context_, js::GetProxyTargetObject(global_object_proxy_));
- size_t length = script.size();
- jschar* inflated_buffer =
- js::InflateUTF8String(context_, script.c_str(), &length);
- DCHECK(inflated_buffer);
- bool success = false;
- if (inflated_buffer) {
- success = JS_EvaluateUCScript(context_, global_object, inflated_buffer,
- length, location.file_path.c_str(),
- location.line_number, result_value.address());
- js_free(inflated_buffer);
- }
-
+ bool success = EvaluateScriptInternal(source_code, &result_value);
if (out_result_utf8) {
if (success) {
MozjsExceptionState exception_state(context_);
@@ -233,8 +216,61 @@
DLOG(ERROR) << "Script execution failed.";
}
}
- JS_RestoreExceptionState(context_, previous_exception_state);
last_error_message_ = NULL;
+ JS_RestoreExceptionState(context_, previous_exception_state);
+ return success;
+}
+
+bool MozjsGlobalEnvironment::EvaluateScript(
+ const scoped_refptr<SourceCode>& source_code,
+ const scoped_refptr<Wrappable>& owning_object,
+ base::optional<OpaqueHandleHolder::Reference>* out_opaque_handle) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ JSAutoRequest auto_request(context_);
+ JSAutoCompartment auto_compartment(context_, global_object_proxy_);
+ JSExceptionState* previous_exception_state = JS_SaveExceptionState(context_);
+ JS::RootedValue result_value(context_);
+ if (!EvaluateScriptInternal(source_code, &result_value)) {
+ return false;
+ }
+ if (out_opaque_handle) {
+ JS::RootedObject js_object(context_);
+ JS_ValueToObject(context_, result_value, js_object.address());
+ MozjsObjectHandleHolder mozjs_object_holder(js_object, context_,
+ wrapper_factory());
+ out_opaque_handle->emplace(owning_object.get(), mozjs_object_holder);
+ }
+ JS_RestoreExceptionState(context_, previous_exception_state);
+ return true;
+}
+
+bool MozjsGlobalEnvironment::EvaluateScriptInternal(
+ const scoped_refptr<SourceCode>& source_code,
+ JS::MutableHandleValue out_result) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(global_object_proxy_);
+ MozjsSourceCode* mozjs_source_code =
+ base::polymorphic_downcast<MozjsSourceCode*>(source_code.get());
+
+ const std::string& script = mozjs_source_code->source_utf8();
+ const base::SourceLocation location = mozjs_source_code->location();
+
+ JS::RootedObject global_object(
+ context_, js::GetProxyTargetObject(global_object_proxy_));
+
+ size_t length = script.size();
+ jschar* inflated_buffer =
+ js::InflateUTF8String(context_, script.c_str(), &length);
+ bool success = false;
+ if (inflated_buffer) {
+ success = JS_EvaluateUCScript(context_, global_object, inflated_buffer,
+ length, location.file_path.c_str(),
+ location.line_number, out_result.address());
+ js_free(inflated_buffer);
+ } else {
+ DLOG(ERROR) << "Malformed UTF-8 script.";
+ }
+
return success;
}
@@ -321,7 +357,7 @@
if (global_object_proxy_ && garbage_collection_count_ == 1) {
DCHECK(!opaque_root_state_);
JSAutoRequest auto_request(context_);
- JSAutoCompartment auto_comparment(context_, global_object_proxy_);
+ JSAutoCompartment auto_compartment(context_, global_object_proxy_);
// Get the current state of opaque root relationships. Keep this object
// alive for the duration of the GC phase to ensure that reachability
// between roots and reachable objects is maintained.
diff --git a/src/cobalt/script/mozjs/mozjs_global_environment.h b/src/cobalt/script/mozjs/mozjs_global_environment.h
index 54f75de..d13d7f0 100644
--- a/src/cobalt/script/mozjs/mozjs_global_environment.h
+++ b/src/cobalt/script/mozjs/mozjs_global_environment.h
@@ -56,10 +56,7 @@
bool EvaluateScript(const scoped_refptr<SourceCode>& script_utf8,
const scoped_refptr<Wrappable>& owning_object,
base::optional<OpaqueHandleHolder::Reference>*
- out_opaque_handle) OVERRIDE {
- NOTIMPLEMENTED();
- return false;
- }
+ out_opaque_handle) OVERRIDE;
std::vector<StackFrame> GetStackTrace(int max_frames = 0) OVERRIDE;
@@ -133,7 +130,10 @@
// with an error that eval() is disabled.
static JSBool CheckEval(JSContext* context);
- protected:
+ private:
+ bool EvaluateScriptInternal(const scoped_refptr<SourceCode>& source_code,
+ JS::MutableHandleValue out_result);
+
static void ReportErrorHandler(JSContext* context, const char* message,
JSErrorReport* report);
diff --git a/src/glimp/entry_points/gles_2_0.cc b/src/glimp/entry_points/gles_2_0.cc
index 10391ca..884318a 100644
--- a/src/glimp/entry_points/gles_2_0.cc
+++ b/src/glimp/entry_points/gles_2_0.cc
@@ -281,7 +281,12 @@
}
void GL_APIENTRY glCullFace(GLenum mode) {
- SB_NOTIMPLEMENTED();
+ gles::Context* context = GetCurrentContext();
+ if (!context) {
+ return;
+ }
+
+ return context->CullFace(mode);
}
void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers) {
diff --git a/src/glimp/gles/context.cc b/src/glimp/gles/context.cc
index a104230..2057fcb 100644
--- a/src/glimp/gles/context.cc
+++ b/src/glimp/gles/context.cc
@@ -21,6 +21,7 @@
#include "glimp/egl/error.h"
#include "glimp/egl/surface.h"
#include "glimp/gles/blend_state.h"
+#include "glimp/gles/cull_face_state.h"
#include "glimp/gles/draw_mode.h"
#include "glimp/gles/index_data_type.h"
#include "glimp/gles/pixel_format.h"
@@ -299,9 +300,13 @@
draw_state_.scissor.enabled = true;
draw_state_dirty_flags_.scissor_dirty = true;
break;
+ case GL_CULL_FACE:
+ draw_state_.cull_face_state.enabled = true;
+ draw_state_.cull_face_state.mode = CullFaceState::kBack;
+ draw_state_dirty_flags_.cull_face_dirty = true;
+ break;
case GL_DEPTH_TEST:
case GL_DITHER:
- case GL_CULL_FACE:
case GL_STENCIL_TEST:
case GL_POLYGON_OFFSET_FILL:
case GL_SAMPLE_ALPHA_TO_COVERAGE:
@@ -323,9 +328,12 @@
draw_state_.scissor.enabled = false;
draw_state_dirty_flags_.scissor_dirty = true;
break;
+ case GL_CULL_FACE:
+ draw_state_.cull_face_state.enabled = false;
+ draw_state_dirty_flags_.cull_face_dirty = true;
+ break;
case GL_DEPTH_TEST:
case GL_DITHER:
- case GL_CULL_FACE:
case GL_STENCIL_TEST:
case GL_POLYGON_OFFSET_FILL:
case GL_SAMPLE_ALPHA_TO_COVERAGE:
@@ -426,6 +434,31 @@
draw_state_dirty_flags_.blend_state_dirty = true;
}
+namespace {
+CullFaceState::Mode CullFaceModeFromEnum(GLenum mode) {
+ switch (mode) {
+ case GL_FRONT:
+ return CullFaceState::kFront;
+ case GL_BACK:
+ return CullFaceState::kBack;
+ case GL_FRONT_AND_BACK:
+ return CullFaceState::kFrontAndBack;
+ default:
+ return CullFaceState::kModeInvalid;
+ }
+}
+} // namespace
+
+void Context::CullFace(GLenum mode) {
+ CullFaceState::Mode cull_face_mode = CullFaceModeFromEnum(mode);
+ if (cull_face_mode == CullFaceState::kModeInvalid) {
+ SetError(GL_INVALID_ENUM);
+ return;
+ }
+ draw_state_.cull_face_state.mode = cull_face_mode;
+ draw_state_dirty_flags_.cull_face_dirty = true;
+}
+
GLuint Context::CreateProgram() {
GLIMP_TRACE_EVENT0(__FUNCTION__);
nb::scoped_ptr<ProgramImpl> program_impl = impl_->CreateProgram();
diff --git a/src/glimp/gles/context.h b/src/glimp/gles/context.h
index e028ed5..7d2d919 100644
--- a/src/glimp/gles/context.h
+++ b/src/glimp/gles/context.h
@@ -95,6 +95,8 @@
void BlendFunc(GLenum sfactor, GLenum dfactor);
+ void CullFace(GLenum mode);
+
GLuint CreateProgram();
void DeleteProgram(GLuint program);
void AttachShader(GLuint program, GLuint shader);
diff --git a/src/glimp/gles/cull_face_state.h b/src/glimp/gles/cull_face_state.h
new file mode 100644
index 0000000..b68d6b0
--- /dev/null
+++ b/src/glimp/gles/cull_face_state.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GLIMP_GLES_CULL_FACE_STATE_H_
+#define GLIMP_GLES_CULL_FACE_STATE_H_
+
+namespace glimp {
+namespace gles {
+
+// Describes GL cull face state, which can be modified via commands like
+// glCullFace().
+// https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCullFace.xml
+struct CullFaceState {
+ // When enabled, the initial face culling value should be kBack.
+ enum Mode {
+ kFront,
+ kBack,
+ kFrontAndBack,
+ kModeInvalid,
+ };
+
+ // Default state is face culling off.
+ CullFaceState() : enabled(false), mode(kBack) {}
+
+ Mode mode;
+ bool enabled;
+};
+
+} // namespace gles
+} // namespace glimp
+
+#endif // GLIMP_GLES_CULL_FACE_STATE_H_
diff --git a/src/glimp/gles/draw_state.h b/src/glimp/gles/draw_state.h
index 96f5ec1..db9c2d9 100644
--- a/src/glimp/gles/draw_state.h
+++ b/src/glimp/gles/draw_state.h
@@ -24,6 +24,7 @@
#include "glimp/egl/surface.h"
#include "glimp/gles/blend_state.h"
#include "glimp/gles/buffer.h"
+#include "glimp/gles/cull_face_state.h"
#include "glimp/gles/framebuffer.h"
#include "glimp/gles/program.h"
#include "glimp/gles/sampler.h"
@@ -156,6 +157,9 @@
// existing pixels in the output framebuffer.
BlendState blend_state;
+ // Defines whether face culling is enabled, and upon which face if so.
+ CullFaceState cull_face_state;
+
// The currently bound array buffer, set by calling
// glBindBuffer(GL_ARRAY_BUFFER).
nb::scoped_refptr<Buffer> array_buffer;
@@ -190,6 +194,7 @@
scissor_dirty = true;
viewport_dirty = true;
blend_state_dirty = true;
+ cull_face_dirty = true;
array_buffer_dirty = true;
element_array_buffer_dirty = true;
used_program_dirty = true;
@@ -205,6 +210,7 @@
bool scissor_dirty;
bool viewport_dirty;
bool blend_state_dirty;
+ bool cull_face_dirty;
bool array_buffer_dirty;
bool element_array_buffer_dirty;
bool used_program_dirty;
diff --git a/src/glimp/glimp_common.gypi b/src/glimp/glimp_common.gypi
index 4f00bfe..ef1a68c 100644
--- a/src/glimp/glimp_common.gypi
+++ b/src/glimp/glimp_common.gypi
@@ -45,6 +45,7 @@
'gles/context_impl.h',
'gles/convert_pixel_data.cc',
'gles/convert_pixel_data.h',
+ 'gles/cull_face_state.h',
'gles/draw_mode.h',
'gles/draw_state.cc',
'gles/draw_state.h',
diff --git a/src/media/base/pipeline.h b/src/media/base/pipeline.h
index 3f5aaf6..0912c6b 100644
--- a/src/media/base/pipeline.h
+++ b/src/media/base/pipeline.h
@@ -51,7 +51,9 @@
// playing.
class MEDIA_EXPORT Pipeline : public base::RefCountedThreadSafe<Pipeline> {
public:
- typedef base::Callback<void(const gfx::Rect&)> SetBoundsCB;
+ // Return true if the punch through box should be rendered. Return false if
+ // no punch through box should be rendered.
+ typedef base::Callback<bool(const gfx::Rect&)> SetBoundsCB;
// Buffering states the pipeline transitions between during playback.
// kHaveMetadata:
diff --git a/src/media/base/sbplayer_pipeline.cc b/src/media/base/sbplayer_pipeline.cc
index ead7b85..971f574 100644
--- a/src/media/base/sbplayer_pipeline.cc
+++ b/src/media/base/sbplayer_pipeline.cc
@@ -118,12 +118,13 @@
base::Lock lock_;
player_ = player;
}
- void SetBounds(const gfx::Rect& rect) {
+ bool SetBounds(const gfx::Rect& rect) {
base::AutoLock auto_lock(lock_);
- if (SbPlayerIsValid(player_)) {
- SbPlayerSetBounds(player_, rect.x(), rect.y(), rect.width(),
- rect.height());
+ if (!SbPlayerIsValid(player_)) {
+ return false;
}
+ SbPlayerSetBounds(player_, rect.x(), rect.y(), rect.width(), rect.height());
+ return true;
}
private:
@@ -725,7 +726,7 @@
video_read_in_progress_ = false;
if (buffer->IsEndOfStream()) {
- SbPlayerWriteEndOfStream(player_, kSbMediaTypeAudio);
+ SbPlayerWriteEndOfStream(player_, kSbMediaTypeVideo);
return;
}
SbMediaVideoSampleInfo video_info;
diff --git a/src/media/player/web_media_player.h b/src/media/player/web_media_player.h
index 77a9c0c..ef6b89a 100644
--- a/src/media/player/web_media_player.h
+++ b/src/media/player/web_media_player.h
@@ -32,7 +32,9 @@
class WebMediaPlayer {
public:
- typedef base::Callback<void(const gfx::Rect&)> SetBoundsCB;
+ // Return true if the punch through box should be rendered. Return false if
+ // no punch through box should be rendered.
+ typedef base::Callback<bool(const gfx::Rect&)> SetBoundsCB;
enum NetworkState {
kNetworkStateEmpty,
diff --git a/src/nb/allocator.h b/src/nb/allocator.h
index c5ddf7c..75ac4ed 100644
--- a/src/nb/allocator.h
+++ b/src/nb/allocator.h
@@ -42,14 +42,21 @@
// Will return NULL if the allocation fails.
virtual void* Allocate(std::size_t size, std::size_t alignment) = 0;
- // Allocates a range of memory of the given size for the given alignment.
- // Returns a pointer that may not be aligned but points to a memory area that
- // is still large enough when the pointer is subsequently aligned to the given
- // alignment. It can allocate up to size + alignment - 1 bytes. This allows a
- // reuse allocator to use the padding area as a free block. Will return NULL
- // if the allocation fails.
- virtual void* AllocateForAlignment(std::size_t size,
- std::size_t alignment) = 0;
+ // When supported, allocates a range of memory of the given size for the given
+ // alignment. Returns a pointer that may not be aligned but points to a memory
+ // area that is still large enough when the pointer is subsequently aligned to
+ // the given alignment. This allows a reuse allocator to use the padding area
+ // as a free block. |size| will be set to the actual size allocated on
+ // successful allocations. Will return NULL if the allocation fails. In the
+ // case that the underlying block size is inconvenient or impossible to be
+ // retreived, the |size| can remain unchanged for a successful allocation. The
+ // user may lose the ability to combine two adjacent allocations in this case.
+ // Note that the coding style recommends that in/out parameters to be placed
+ // after input parameters but |size| is kept in the left for consistency.
+ virtual void* AllocateForAlignment(std::size_t* /*size*/,
+ std::size_t /*alignment*/) {
+ return 0;
+ }
// Frees memory previously allocated via any call to Allocate().
virtual void Free(void* memory) = 0;
diff --git a/src/nb/allocator_decorator.cc b/src/nb/allocator_decorator.cc
index daa5320..18578b1 100644
--- a/src/nb/allocator_decorator.cc
+++ b/src/nb/allocator_decorator.cc
@@ -68,7 +68,7 @@
return impl_->Allocate(size, alignment);
}
-void* AllocatorDecorator::AllocateForAlignment(std::size_t size,
+void* AllocatorDecorator::AllocateForAlignment(std::size_t* size,
std::size_t alignment) {
ScopedLock scoped_lock(lock_);
return impl_->AllocateForAlignment(size, alignment);
diff --git a/src/nb/allocator_decorator.h b/src/nb/allocator_decorator.h
index 13969ad..78a8407 100644
--- a/src/nb/allocator_decorator.h
+++ b/src/nb/allocator_decorator.h
@@ -34,7 +34,7 @@
void* Allocate(std::size_t size);
void* Allocate(std::size_t size, std::size_t alignment);
- void* AllocateForAlignment(std::size_t size, std::size_t alignment);
+ void* AllocateForAlignment(std::size_t* size, std::size_t alignment);
void Free(void* memory);
std::size_t GetCapacity() const;
std::size_t GetAllocated() const;
diff --git a/src/nb/fixed_no_free_allocator.cc b/src/nb/fixed_no_free_allocator.cc
index 3722da6..53a615f 100644
--- a/src/nb/fixed_no_free_allocator.cc
+++ b/src/nb/fixed_no_free_allocator.cc
@@ -27,28 +27,6 @@
next_memory_ = memory_start_;
}
-void* FixedNoFreeAllocator::Allocate(std::size_t size,
- std::size_t alignment,
- bool align_pointer) {
- // Find the next aligned memory available.
- uint8_t* aligned_next_memory =
- AsPointer(AlignUp(AsInteger(next_memory_), alignment));
-
- if (aligned_next_memory + size < aligned_next_memory) {
- // "aligned_next_memory + size" overflows.
- return NULL;
- }
-
- if (aligned_next_memory + size > memory_end_) {
- // We don't have enough memory available to make this allocation.
- return NULL;
- }
-
- void* memory_pointer = align_pointer ? aligned_next_memory : next_memory_;
- next_memory_ = aligned_next_memory + size;
- return memory_pointer;
-}
-
void FixedNoFreeAllocator::Free(void* memory) {
// Nothing to do here besides ensure that the freed memory belongs to us.
SB_DCHECK(memory >= memory_start_);
@@ -67,4 +45,30 @@
SB_NOTIMPLEMENTED();
}
+void* FixedNoFreeAllocator::Allocate(std::size_t* size,
+ std::size_t alignment,
+ bool align_pointer) {
+ // Find the next aligned memory available.
+ uint8_t* aligned_next_memory =
+ AsPointer(AlignUp(AsInteger(next_memory_), alignment));
+
+ if (aligned_next_memory + *size < aligned_next_memory) {
+ // "aligned_next_memory + size" overflows.
+ return NULL;
+ }
+
+ if (aligned_next_memory + *size > memory_end_) {
+ // We don't have enough memory available to make this allocation.
+ return NULL;
+ }
+
+ if (!align_pointer) {
+ *size += AsInteger(aligned_next_memory) - AsInteger(next_memory_);
+ }
+
+ void* memory_pointer = align_pointer ? aligned_next_memory : next_memory_;
+ next_memory_ = aligned_next_memory + *size;
+ return memory_pointer;
+}
+
} // namespace nb
diff --git a/src/nb/fixed_no_free_allocator.h b/src/nb/fixed_no_free_allocator.h
index 696a7c0..31bfc60 100644
--- a/src/nb/fixed_no_free_allocator.h
+++ b/src/nb/fixed_no_free_allocator.h
@@ -37,22 +37,23 @@
class FixedNoFreeAllocator : public Allocator {
public:
FixedNoFreeAllocator(void* memory_start, std::size_t memory_size);
- void* Allocate(std::size_t size) { return Allocate(size, 1, true); }
+ void* Allocate(std::size_t size) { return Allocate(&size, 1, true); }
void* Allocate(std::size_t size, std::size_t alignment) {
- return Allocate(size, alignment, true);
+ return Allocate(&size, alignment, true);
}
- void* AllocateForAlignment(std::size_t size, std::size_t alignment) {
+ void* AllocateForAlignment(std::size_t* size, std::size_t alignment) {
return Allocate(size, alignment, false);
}
- void* Allocate(std::size_t size, std::size_t alignment, bool align_pointer);
void Free(void* memory);
std::size_t GetCapacity() const;
std::size_t GetAllocated() const;
void PrintAllocations() const;
private:
+ void* Allocate(std::size_t* size, std::size_t alignment, bool align_pointer);
+
// The start of our memory range, as passed in to the constructor.
void* const memory_start_;
diff --git a/src/nb/memory_pool.cc b/src/nb/memory_pool.cc
index 840042c..4ae9a7e 100644
--- a/src/nb/memory_pool.cc
+++ b/src/nb/memory_pool.cc
@@ -23,15 +23,21 @@
MemoryPool::MemoryPool(void* buffer,
std::size_t size,
bool thread_safe,
- bool verify_full_capacity)
+ bool verify_full_capacity,
+ std::size_t small_allocation_threshold)
: no_free_allocator_(buffer, size),
reuse_allocator_(
- scoped_ptr<Allocator>(new ReuseAllocator(&no_free_allocator_)),
+ scoped_ptr<Allocator>(new ReuseAllocator(&no_free_allocator_,
+ size,
+ small_allocation_threshold)),
thread_safe) {
SB_DCHECK(buffer);
SB_DCHECK(size != 0U);
- if (verify_full_capacity) {
+ // This is redundant if ReuseAllocator::Allcator() can allocate the difference
+ // between the requested size and the last free block from the fallback
+ // allocator and combine the blocks.
+ if (verify_full_capacity && small_allocation_threshold == 0) {
void* p = Allocate(size);
SB_DCHECK(p);
Free(p);
diff --git a/src/nb/memory_pool.h b/src/nb/memory_pool.h
index cef03db..b81e893 100644
--- a/src/nb/memory_pool.h
+++ b/src/nb/memory_pool.h
@@ -29,30 +29,16 @@
// as necessary.
class MemoryPool : public Allocator {
public:
- // When |verify_full_capacity| is true, the ctor tries to allocate the whole
- // budget and free it immediately. This can:
- // 1. Ensure the |size| is accurate after accounting for all implicit
- // alignment enforced by the underlying allocators.
- // 2. The |reuse_allocator_| contains a free block of the whole budget. As
- // the |reuse_allocator_| doesn't support extending of free block, an
- // allocation that is larger than the both biggest free block in the
- // |reuse_allocator_| and the remaining memory inside the
- // |no_free_allocator_| will fail even if the combination of both can
- // fulfill the allocation.
- // Note that when |verify_full_capacity| is true, GetHighWaterMark() always
- // return the budget, which makes memory usage tracking useless.
MemoryPool(void* buffer,
std::size_t size,
bool thread_safe,
- bool verify_full_capacity = false);
+ bool verify_full_capacity = false,
+ std::size_t small_allocation_threshold = 0);
void* Allocate(std::size_t size) { return reuse_allocator_.Allocate(size); }
void* Allocate(std::size_t size, std::size_t alignment) {
return reuse_allocator_.Allocate(size, alignment);
}
- void* AllocateForAlignment(std::size_t size, std::size_t alignment) {
- return reuse_allocator_.AllocateForAlignment(size, alignment);
- }
void Free(void* memory) { reuse_allocator_.Free(memory); }
std::size_t GetCapacity() const { return reuse_allocator_.GetCapacity(); }
std::size_t GetAllocated() const { return reuse_allocator_.GetAllocated(); }
diff --git a/src/nb/pointer_arithmetic.h b/src/nb/pointer_arithmetic.h
index 411308c..cb1539a 100644
--- a/src/nb/pointer_arithmetic.h
+++ b/src/nb/pointer_arithmetic.h
@@ -31,7 +31,7 @@
return reinterpret_cast<uint8_t*>(integer_value);
}
-// Helper method for subclasses to align addresses up to a specified value.
+// Helper method to align addresses up to a specified value.
// Returns the the smallest value that is greater than or equal to value, but
// aligned to alignment.
template <typename T>
@@ -42,9 +42,20 @@
template <typename T>
T* AlignUp(T* value, uintptr_t alignment) {
- uintptr_t decremented_value = AsInteger(value) - 1;
- return reinterpret_cast<T*>(decremented_value + alignment -
- (decremented_value % alignment));
+ return reinterpret_cast<T*>(AlignUp(AsInteger(value), alignment));
+}
+
+// Helper method to align addresses down to a specified value.
+// Returns the the largest value that is less than or equal to value, but
+// aligned to alignment.
+template <typename T>
+T AlignDown(T value, T alignment) {
+ return value / alignment * alignment;
+}
+
+template <typename T>
+T* AlignDown(T* value, uintptr_t alignment) {
+ return reinterpret_cast<T*>(AlignDown(AsInteger(value), alignment));
}
// Helper method for subclasses to determine if a given address or value
diff --git a/src/nb/reuse_allocator.cc b/src/nb/reuse_allocator.cc
index 61a40a6..70898ae 100644
--- a/src/nb/reuse_allocator.cc
+++ b/src/nb/reuse_allocator.cc
@@ -24,10 +24,104 @@
namespace nb {
-ReuseAllocator::ReuseAllocator(Allocator* fallback_allocator) {
- fallback_allocator_ = fallback_allocator;
- capacity_ = 0;
- total_allocated_ = 0;
+// Minimum block size to avoid extremely small blocks inside the block list and
+// to ensure that a zero sized allocation will return a non-zero sized block.
+const std::size_t kMinBlockSizeBytes = 16;
+
+bool ReuseAllocator::MemoryBlock::Merge(const MemoryBlock& other) {
+ if (AsInteger(address_) + size_ == AsInteger(other.address_)) {
+ size_ += other.size_;
+ return true;
+ }
+ if (AsInteger(other.address_) + other.size_ == AsInteger(address_)) {
+ address_ = other.address_;
+ size_ += other.size_;
+ return true;
+ }
+ return false;
+}
+
+bool ReuseAllocator::MemoryBlock::CanFullfill(std::size_t request_size,
+ std::size_t alignment) const {
+ const std::size_t extra_bytes_for_alignment =
+ AlignUp(AsInteger(address_), alignment) - AsInteger(address_);
+ const std::size_t aligned_size = request_size + extra_bytes_for_alignment;
+ return size_ >= aligned_size;
+}
+
+void ReuseAllocator::MemoryBlock::Allocate(std::size_t request_size,
+ std::size_t alignment,
+ bool allocate_from_front,
+ MemoryBlock* allocated,
+ MemoryBlock* free) const {
+ SB_DCHECK(allocated);
+ SB_DCHECK(free);
+ SB_DCHECK(CanFullfill(request_size, alignment));
+
+ // First we assume that the block is just enough to fulfill the allocation and
+ // leaves no free block.
+ allocated->address_ = address_;
+ allocated->size_ = size_;
+ free->address_ = NULL;
+ free->size_ = 0;
+
+ if (allocate_from_front) {
+ // |address_|
+ // | <- allocated_size -> | <- remaining_size -> |
+ // -------------------------------------------------------
+ // | <- request_size -> | |
+ // |aligned_address| |end_of_allocation| |address_ + size_|
+ std::size_t aligned_address = AlignUp(AsInteger(address_), alignment);
+ std::size_t end_of_allocation = aligned_address + request_size;
+ std::size_t allocated_size = end_of_allocation - AsInteger(address_);
+ std::size_t remaining_size = size_ - allocated_size;
+ if (remaining_size < kMinBlockSizeBytes) {
+ return;
+ }
+ allocated->size_ = allocated_size;
+ free->address_ = AsPointer(end_of_allocation);
+ free->size_ = remaining_size;
+ } else {
+ // |address_|
+ // | <- remaining_size -> | <- allocated_size -> |
+ // -------------------------------------------------------
+ // | <- request_size -> | |
+ // |aligned_address| |address_ + size_|
+ std::size_t aligned_address =
+ AlignDown(AsInteger(address_) + size_ - request_size, alignment);
+ std::size_t allocated_size = AsInteger(address_) + size_ - aligned_address;
+ std::size_t remaining_size = size_ - allocated_size;
+ if (remaining_size < kMinBlockSizeBytes) {
+ return;
+ }
+ allocated->address_ = AsPointer(aligned_address);
+ allocated->size_ = allocated_size;
+ free->address_ = address_;
+ free->size_ = remaining_size;
+ }
+}
+
+ReuseAllocator::ReuseAllocator(Allocator* fallback_allocator)
+ : fallback_allocator_(fallback_allocator),
+ small_allocation_threshold_(0),
+ capacity_(0),
+ total_allocated_(0) {}
+
+ReuseAllocator::ReuseAllocator(Allocator* fallback_allocator,
+ std::size_t capacity,
+ std::size_t small_allocation_threshold)
+ : fallback_allocator_(fallback_allocator),
+ small_allocation_threshold_(small_allocation_threshold),
+ capacity_(0),
+ total_allocated_(0) {
+ // If |small_allocation_threshold_| is non-zero, this class will use last-fit
+ // strategy to fulfill small allocations. Pre-allocator full capacity so
+ // last-fit makes sense.
+ if (small_allocation_threshold_ > 0) {
+ void* p = Allocate(capacity, 1);
+ SB_DCHECK(p);
+ Free(p);
+ }
}
ReuseAllocator::~ReuseAllocator() {
@@ -44,18 +138,14 @@
}
}
-void ReuseAllocator::AddFreeBlock(void* address, std::size_t size) {
- MemoryBlock new_block;
- new_block.address = address;
- new_block.size = size;
-
+ReuseAllocator::FreeBlockSet::iterator ReuseAllocator::AddFreeBlock(
+ MemoryBlock block_to_add) {
if (free_blocks_.size() == 0) {
- free_blocks_.insert(new_block);
- return;
+ return free_blocks_.insert(block_to_add).first;
}
// See if we can merge this block with one on the right or left.
- FreeBlockSet::iterator it = free_blocks_.lower_bound(new_block);
+ FreeBlockSet::iterator it = free_blocks_.lower_bound(block_to_add);
// lower_bound will return an iterator to our neighbor on the right,
// if one exists.
FreeBlockSet::iterator right_to_erase = free_blocks_.end();
@@ -63,9 +153,7 @@
if (it != free_blocks_.end()) {
MemoryBlock right_block = *it;
- if (AsInteger(new_block.address) + new_block.size ==
- AsInteger(right_block.address)) {
- new_block.size += right_block.size;
+ if (block_to_add.Merge(right_block)) {
right_to_erase = it;
}
}
@@ -75,10 +163,7 @@
it--;
MemoryBlock left_block = *it;
// Are we contiguous with the block to our left?
- if (AsInteger(left_block.address) + left_block.size ==
- AsInteger(new_block.address)) {
- new_block.address = left_block.address;
- new_block.size += left_block.size;
+ if (block_to_add.Merge(left_block)) {
left_to_erase = it;
}
}
@@ -90,7 +175,7 @@
free_blocks_.erase(left_to_erase);
}
- free_blocks_.insert(new_block);
+ return free_blocks_.insert(block_to_add).first;
}
void ReuseAllocator::RemoveFreeBlock(FreeBlockSet::iterator it) {
@@ -101,11 +186,6 @@
return Allocate(size, 1);
}
-void* ReuseAllocator::AllocateForAlignment(std::size_t size,
- std::size_t alignment) {
- return Allocate(size, alignment);
-}
-
void* ReuseAllocator::Allocate(std::size_t size, std::size_t alignment) {
if (alignment == 0) {
alignment = 1;
@@ -113,15 +193,14 @@
// Try to satisfy request from free list.
// First look for a block that is appropriately aligned.
- // If we can't, look for a block that is big enough that we can
- // carve out an aligned block.
+ // If we can't, look for a block that is big enough that we can carve out an
+ // aligned block.
// If there is no such block, allocate more from our fallback allocator.
void* user_address = 0;
- // Keeping things rounded and aligned will help us
- // avoid creating tiny and/or badly misaligned free blocks.
- // Also ensure even for a 0-byte request we return a unique block.
- const std::size_t kMinBlockSizeBytes = 16;
+ // Keeping things rounded and aligned will help us avoid creating tiny and/or
+ // badly misaligned free blocks. Also ensure even for a 0-byte request we
+ // return a unique block.
const std::size_t kMinAlignment = 16;
size = std::max(size, kMinBlockSizeBytes);
size = AlignUp(size, kMinBlockSizeBytes);
@@ -130,68 +209,59 @@
// Worst case how much memory we need.
MemoryBlock allocated_block;
- // Start looking through the free list.
- // If this is slow, we can store another map sorted by size.
- for (FreeBlockSet::iterator it = free_blocks_.begin();
- it != free_blocks_.end(); ++it) {
- MemoryBlock block = *it;
- const std::size_t extra_bytes_for_alignment =
- (alignment - AsInteger(block.address) % alignment) % alignment;
- const std::size_t aligned_size = size + extra_bytes_for_alignment;
- if (block.size >= aligned_size) {
- // The block is big enough. We may waste some space due to alignment.
- RemoveFreeBlock(it);
- const std::size_t remaining_bytes = block.size - aligned_size;
- if (remaining_bytes >= kMinBlockSizeBytes) {
- AddFreeBlock(AsPointer(AsInteger(block.address) + aligned_size),
- remaining_bytes);
- allocated_block.size = aligned_size;
- } else {
- allocated_block.size = block.size;
+ bool scan_from_front = size > small_allocation_threshold_;
+ FreeBlockSet::iterator free_block_iter = free_blocks_.end();
+
+ if (scan_from_front) {
+ // Start looking through the free list from the front.
+ for (FreeBlockSet::iterator it = free_blocks_.begin();
+ it != free_blocks_.end(); ++it) {
+ if (it->CanFullfill(size, alignment)) {
+ free_block_iter = it;
+ break;
}
- user_address = AlignUp(block.address, alignment);
- allocated_block.address = block.address;
- SB_DCHECK(allocated_block.size <= block.size);
- break;
+ }
+ } else {
+ // Start looking through the free list from the back.
+ for (FreeBlockSet::reverse_iterator it = free_blocks_.rbegin();
+ it != free_blocks_.rend(); ++it) {
+ if (it->CanFullfill(size, alignment)) {
+ free_block_iter = it.base();
+ --free_block_iter;
+ break;
+ }
}
}
- if (user_address == 0) {
- // No free blocks found.
- // Allocate one from the fallback allocator.
- size = AlignUp(size, alignment);
- void* ptr = fallback_allocator_->AllocateForAlignment(size, alignment);
+ if (free_block_iter == free_blocks_.end()) {
+ // No free blocks found, allocate one from the fallback allocator.
+ std::size_t block_size = size;
+ void* ptr =
+ fallback_allocator_->AllocateForAlignment(&block_size, alignment);
if (ptr == NULL) {
return NULL;
}
- uint8_t* memory_address = reinterpret_cast<uint8_t*>(ptr);
- user_address = AlignUp(memory_address, alignment);
- allocated_block.size = size;
- allocated_block.address = user_address;
-
- if (memory_address != user_address) {
- std::size_t alignment_padding_size =
- AsInteger(user_address) - AsInteger(memory_address);
- if (alignment_padding_size >= kMinBlockSizeBytes) {
- // Register the memory range skipped for alignment as a free block for
- // later use.
- AddFreeBlock(memory_address, alignment_padding_size);
- capacity_ += alignment_padding_size;
- } else {
- // The memory range skipped for alignment is too small for a free block.
- // Adjust the allocated block to include the alignment padding.
- allocated_block.size += alignment_padding_size;
- allocated_block.address = AsPointer(AsInteger(allocated_block.address) -
- alignment_padding_size);
- }
- }
-
- capacity_ += allocated_block.size;
+ free_block_iter = AddFreeBlock(MemoryBlock(ptr, block_size));
+ capacity_ += block_size;
fallback_allocations_.push_back(ptr);
}
+
+ MemoryBlock block = *free_block_iter;
+ // The block is big enough. We may waste some space due to alignment.
+ RemoveFreeBlock(free_block_iter);
+
+ MemoryBlock free_block;
+ block.Allocate(size, alignment, scan_from_front, &allocated_block,
+ &free_block);
+ if (free_block.size() > 0) {
+ SB_DCHECK(free_block.address());
+ AddFreeBlock(free_block);
+ }
+ user_address = AlignUp(allocated_block.address(), alignment);
+
SB_DCHECK(allocated_blocks_.find(user_address) == allocated_blocks_.end());
allocated_blocks_[user_address] = allocated_block;
- total_allocated_ += allocated_block.size;
+ total_allocated_ += allocated_block.size();
return user_address;
}
@@ -205,10 +275,10 @@
// Mark this block as free and remove it from the allocated set.
const MemoryBlock& block = (*it).second;
- AddFreeBlock(block.address, block.size);
+ AddFreeBlock(block);
- SB_DCHECK(block.size <= total_allocated_);
- total_allocated_ -= block.size;
+ SB_DCHECK(block.size() <= total_allocated_);
+ total_allocated_ -= block.size();
allocated_blocks_.erase(it);
}
@@ -218,7 +288,7 @@
SizesHistogram sizes_histogram;
for (AllocatedBlockMap::const_iterator iter = allocated_blocks_.begin();
iter != allocated_blocks_.end(); ++iter) {
- std::size_t block_size = iter->second.size;
+ std::size_t block_size = iter->second.size();
if (sizes_histogram.find(block_size) == sizes_histogram.end()) {
sizes_histogram[block_size] = 0;
}
diff --git a/src/nb/reuse_allocator.h b/src/nb/reuse_allocator.h
index 6f4f16a..7686930 100644
--- a/src/nb/reuse_allocator.h
+++ b/src/nb/reuse_allocator.h
@@ -30,16 +30,32 @@
// maintaining all allocation meta data is outside of the allocated memory.
// It is passed a fallback allocator that it can request additional memory
// from as needed.
+// The default allocation strategy for the allocator is first-fit, i.e. it will
+// scan for free blocks sorted by addresses and allocate from the first free
+// block that can fulfill the allocation. However, in some situations the
+// majority of the allocations can be small ones with some large allocations.
+// This may cause serious fragmentations and the failure of large allocations.
+// If |small_allocation_threshold| in the ctor is set to a non-zero value, the
+// class will allocate small allocations whose sizes are less than or equal to
+// the threshold using last-fit, i.e. it will scan from the back to the front
+// for free blocks. This way the allocation for large blocks and small blocks
+// are separated thus cause much less fragmentations.
class ReuseAllocator : public Allocator {
public:
explicit ReuseAllocator(Allocator* fallback_allocator);
+ // When |small_allocation_threshold| is non-zero, this class will allocate
+ // its full capacity from the |fallback_allocator| in the ctor so it is
+ // possible for the class to use the last-fit allocation strategy. See the
+ // class comment above for more details.
+ ReuseAllocator(Allocator* fallback_allocator,
+ std::size_t capacity,
+ std::size_t small_allocation_threshold);
virtual ~ReuseAllocator();
// Search free memory blocks for an existing one, and if none are large
// enough, allocate a new one from no-free memory and return that.
void* Allocate(std::size_t size);
void* Allocate(std::size_t size, std::size_t alignment);
- void* AllocateForAlignment(std::size_t size, std::size_t alignment);
// Marks the memory block as being free and it will then become recyclable
void Free(void* memory);
@@ -50,29 +66,67 @@
void PrintAllocations() const;
private:
- // We will allocate from the given allocator whenever we can't find
- // pre-used memory to allocate.
- Allocator* fallback_allocator_;
+ class MemoryBlock {
+ public:
+ MemoryBlock() : address_(0), size_(0) {}
+ MemoryBlock(void* address, std::size_t size)
+ : address_(address), size_(size) {}
- struct MemoryBlock {
- void* address;
- std::size_t size;
+ void* address() const { return address_; }
+ std::size_t size() const { return size_; }
+
+ void set_address(void* address) { address_ = address; }
+ void set_size(std::size_t size) { size_ = size; }
+
bool operator<(const MemoryBlock& other) const {
- return address < other.address;
+ return address_ < other.address_;
}
+ // If the current block and |other| can be combined into a continuous memory
+ // block, store the conmbined block in the current block and return true.
+ // Otherwise return false.
+ bool Merge(const MemoryBlock& other);
+ // Return true if the current block can be used to fulfill an allocation
+ // with the given size and alignment.
+ bool CanFullfill(std::size_t request_size, std::size_t alignment) const;
+ // Allocate a block from this block with the given size and alignment.
+ // Store the allocated block in |allocated|. If the rest space is large
+ // enough to form a block, it will be stored into |free|. Otherwise the
+ // whole block is stored into |allocated|.
+ // Note that the call of this function has to ensure that CanFulfill() is
+ // already called on this block and returns true.
+ void Allocate(std::size_t request_size,
+ std::size_t alignment,
+ bool allocate_from_front,
+ MemoryBlock* allocated,
+ MemoryBlock* free) const;
+
+ private:
+ void* address_;
+ std::size_t size_;
};
+
// Freelist sorted by address.
typedef std::set<MemoryBlock> FreeBlockSet;
// Map from pointers we returned to the user, back to memory blocks.
typedef std::map<void*, MemoryBlock> AllocatedBlockMap;
- void AddFreeBlock(void* address, std::size_t size);
- void RemoveFreeBlock(FreeBlockSet::iterator);
+
+ FreeBlockSet::iterator AddFreeBlock(MemoryBlock block_to_add);
+ void RemoveFreeBlock(FreeBlockSet::iterator it);
FreeBlockSet free_blocks_;
AllocatedBlockMap allocated_blocks_;
- // A list of allocations made from the fallback allocator. We keep track
- // of this so that we can free them all upon our destruction.
+ // We will allocate from the given allocator whenever we can't find pre-used
+ // memory to allocate.
+ Allocator* fallback_allocator_;
+
+ // Any allocations with size less than or equal to the following threshold
+ // will be allocated from the back of the pool. See the comment of the class
+ // for more details.
+ std::size_t small_allocation_threshold_;
+
+ // A list of allocations made from the fallback allocator. We keep track of
+ // this so that we can free them all upon our destruction.
std::vector<void*> fallback_allocations_;
// How much we have allocated from the fallback allocator.
diff --git a/src/nb/reuse_allocator_benchmark.cc b/src/nb/reuse_allocator_benchmark.cc
index 4117d5c..5e48ba7 100644
--- a/src/nb/reuse_allocator_benchmark.cc
+++ b/src/nb/reuse_allocator_benchmark.cc
@@ -177,17 +177,14 @@
class DefaultAllocator : public nb::Allocator {
public:
- void* Allocate(std::size_t size) { return Allocate(size, 0); }
- void* Allocate(std::size_t size, std::size_t alignment) {
+ void* Allocate(std::size_t size) SB_OVERRIDE { return Allocate(size, 0); }
+ void* Allocate(std::size_t size, std::size_t alignment) SB_OVERRIDE {
return SbMemoryAllocateAligned(alignment, size);
}
- void* AllocateForAlignment(std::size_t size, std::size_t alignment) {
- return SbMemoryAllocateAligned(alignment, size);
- }
- void Free(void* memory) { SbMemoryFree(memory); }
- std::size_t GetCapacity() const { return 0; }
- std::size_t GetAllocated() const { return 0; }
- void PrintAllocations() const {}
+ void Free(void* memory) SB_OVERRIDE { SbMemoryFree(memory); }
+ std::size_t GetCapacity() const SB_OVERRIDE { return 0; }
+ std::size_t GetAllocated() const SB_OVERRIDE { return 0; }
+ void PrintAllocations() const SB_OVERRIDE {}
};
void MemoryPlaybackTest(const std::string& filename) {
diff --git a/src/nb/reuse_allocator_test.cc b/src/nb/reuse_allocator_test.cc
index 658c81a..4d42361 100644
--- a/src/nb/reuse_allocator_test.cc
+++ b/src/nb/reuse_allocator_test.cc
@@ -18,6 +18,7 @@
#include "nb/fixed_no_free_allocator.h"
#include "nb/scoped_ptr.h"
+#include "starboard/configuration.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -32,14 +33,21 @@
public:
static const int kBufferSize = 1 * 1024 * 1024;
- ReuseAllocatorTest() {
+ ReuseAllocatorTest() { ResetAllocator(0); }
+
+ protected:
+ void ResetAllocator(size_t small_allocation_threshold) {
buffer_.reset(new uint8_t[kBufferSize]);
fallback_allocator_.reset(
new nb::FixedNoFreeAllocator(buffer_.get(), kBufferSize));
- allocator_.reset(new nb::ReuseAllocator(fallback_allocator_.get()));
+ if (small_allocation_threshold == 0) {
+ allocator_.reset(new nb::ReuseAllocator(fallback_allocator_.get()));
+ } else {
+ allocator_.reset(new nb::ReuseAllocator(
+ fallback_allocator_.get(), kBufferSize, small_allocation_threshold));
+ }
}
- protected:
nb::scoped_array<uint8_t> buffer_;
nb::scoped_ptr<nb::FixedNoFreeAllocator> fallback_allocator_;
nb::scoped_ptr<nb::ReuseAllocator> allocator_;
@@ -99,3 +107,32 @@
allocator_->Free(test_p);
allocator_->Free(blocks[0]);
}
+
+TEST_F(ReuseAllocatorTest, SmallAlloc) {
+ // Recreate allocator with small allocation threshold to 256.
+ ResetAllocator(256);
+
+ const std::size_t kBlockSizes[] = {117, 193, 509, 1111};
+ const std::size_t kAlignment = 16;
+ void* blocks[] = {NULL, NULL, NULL, NULL};
+ for (int i = 0; i < SB_ARRAY_SIZE(kBlockSizes); ++i) {
+ blocks[i] = allocator_->Allocate(kBlockSizes[i], kAlignment);
+ }
+ // The two small allocs should be in the back in reverse order.
+ EXPECT_GT(reinterpret_cast<uintptr_t>(blocks[0]),
+ reinterpret_cast<uintptr_t>(blocks[1]));
+ // Small allocs should has higher address than other allocs.
+ EXPECT_GT(reinterpret_cast<uintptr_t>(blocks[1]),
+ reinterpret_cast<uintptr_t>(blocks[3]));
+ // Non-small allocs are allocated from the front and the first one has the
+ // lowest address.
+ EXPECT_LT(reinterpret_cast<uintptr_t>(blocks[2]),
+ reinterpret_cast<uintptr_t>(blocks[3]));
+ for (int i = 0; i < SB_ARRAY_SIZE(kBlockSizes); ++i) {
+ allocator_->Free(blocks[i]);
+ }
+ // Should have one single free block equals to the capacity.
+ void* test_p = allocator_->Allocate(allocator_->GetCapacity());
+ EXPECT_TRUE(test_p != NULL);
+ allocator_->Free(test_p);
+}
diff --git a/src/starboard/event.h b/src/starboard/event.h
index c602259..cec1884 100644
--- a/src/starboard/event.h
+++ b/src/starboard/event.h
@@ -26,6 +26,43 @@
extern "C" {
#endif
+// The Starboard Application life cycle
+// ------------------------------------
+//
+// *
+// | _________________________
+// Start | |
+// | | Resume
+// V V |
+// [ STARTED ] --Pause--> [ PAUSED ] --Suspend--> [ SUSPENDED ]
+// ^ | |
+// | Unpause Stop
+// |_____________________| |
+// V
+// [ STOPPED ]
+//
+// The first event that a Starboard application will receive is Start
+// (kSbEventTypeStart). This puts the application in the STARTED state; it is in
+// the foreground and can expect to do all the normal things it might want to
+// do. Once in the STARTED state, it may receive a Pause event, putting the
+// application into the PAUSED state.
+//
+// In the PAUSED state, the application is still visible, but has lost focus, or
+// it is partially obscured by a modal dialog, or it is on its way to being shut
+// down. The application should pause activity in this state. In this state, it
+// can receive Unpause to be brought back to the foreground state, STARTED, or
+// Suspend to be pushed further in the background to the SUSPENDED state.
+//
+// In the SUSPENDED state, the application is generally not visible. It should
+// immediately release all graphics and video resources, and shut down all
+// background activity (timers, rendering, etc). Additionally, the application
+// should flush storage to ensure that if the application is killed, the storage
+// will be up-to-date. The application may be killed at this point, but will
+// ideally receive a Stop event for a more graceful shutdown.
+//
+// Note that the application is always expected to transition through PAUSED to
+// SUSPENDED before receiving Stop or being killed.
+
// An enumeration of all possible event types dispatched directly by the
// system. Each event is accompanied by a void* data argument, and each event
// must define the type of the value pointed to by that data argument, if any.
@@ -33,28 +70,43 @@
// The first event that an application receives on startup. Applications
// should perform initialization and prepare to react to subsequent events.
// Applications that wish to run and then exit must call SbSystemRequestStop()
- // to terminate. SbEventStartData is passed as the data argument.
+ // to terminate. This event will only be sent once for a given process launch.
+ // SbEventStartData is passed as the data argument.
kSbEventTypeStart,
- // The operating system will put the application into a suspended state after
- // this event is handled. This is an opportunity for the application to
- // partially tear down and release some resources. Some platforms will
- // terminate the application if work is done while suspended. Can only be
+ // A dialog will be raised or the application will otherwise be put into a
+ // background-but-visible or partially-obscured state (PAUSED). Graphics and
+ // video resources will still be available, but the application should pause
+ // foreground activity like animations and video playback. Can only be
// received after a Start event. The only events that should be dispatched
- // after a Suspend event are Resume or Stop. No data argument.
+ // after a Pause event are Unpause or Suspend. No data argument.
+ kSbEventTypePause,
+
+ // The application is returning to the foreground (STARTED) after having been
+ // put in the PAUSED (e.g. partially-obscured) state. The application should
+ // unpause foreground activity like animations and video playback. Can only be
+ // received after a Pause or Resume event. No data argument.
+ kSbEventTypeUnpause,
+
+ // The operating system will put the application into a Suspended state after
+ // this event is handled. The application is expected to stop periodic
+ // background work, release ALL graphics and video resources, and flush any
+ // pending SbStorage writes. Some platforms will terminate the application if
+ // work is done or resources are retained after suspension. Can only be
+ // received after a Pause event. The only events that should be dispatched
+ // after a Suspend event are Resume or Stop. On some platforms, the process
+ // may also be killed after Suspend without a Stop event. No data argument.
kSbEventTypeSuspend,
- // The operating system has restored the application to normal execution after
- // a Pause event. This is the first even the application will receive coming
- // out of Pause, and it will only be received immediately after a Pause event.
- // No data argument.
+ // The operating system has restored the application to the PAUSED state from
+ // the SUSPENDED state. This is the first event the application will receive
+ // coming out of SUSPENDED, and it will only be received after a Suspend
+ // event. The application will now be in the PAUSED state. No data argument.
kSbEventTypeResume,
// The operating system will shut the application down entirely after this
- // event is handled. This is an opportunity for the application to save any
- // state that it wishes to before its process space is revoked. Can only be
- // recieved after a Start event. May be received after a Pause event. No data
- // argument.
+ // event is handled. Can only be recieved after a Suspend event, in the
+ // SUSPENDED state. No data argument.
kSbEventTypeStop,
// A user input event, including keyboard, mouse, gesture, or something else.
diff --git a/src/starboard/linux/x64directfb/main.cc b/src/starboard/linux/x64directfb/main.cc
index f6d023a..2a7616c 100644
--- a/src/starboard/linux/x64directfb/main.cc
+++ b/src/starboard/linux/x64directfb/main.cc
@@ -17,11 +17,15 @@
#include "starboard/configuration.h"
#include "starboard/shared/directfb/application_directfb.h"
#include "starboard/shared/signal/crash_signals.h"
+#include "starboard/shared/signal/suspend_signals.h"
int main(int argc, char** argv) {
tzset();
starboard::shared::signal::InstallCrashSignalHandlers();
+ starboard::shared::signal::InstallSuspendSignalHandlers();
starboard::ApplicationDirectFB application;
int result = application.Run(argc, argv);
+ starboard::shared::signal::UninstallSuspendSignalHandlers();
+ starboard::shared::signal::UninstallCrashSignalHandlers();
return result;
}
diff --git a/src/starboard/linux/x64directfb/starboard_platform.gyp b/src/starboard/linux/x64directfb/starboard_platform.gyp
index 25c0476..cca05bb 100644
--- a/src/starboard/linux/x64directfb/starboard_platform.gyp
+++ b/src/starboard/linux/x64directfb/starboard_platform.gyp
@@ -236,6 +236,8 @@
'<(DEPTH)/starboard/shared/pthread/thread_yield.cc',
'<(DEPTH)/starboard/shared/signal/crash_signals_sigaction.cc',
'<(DEPTH)/starboard/shared/signal/crash_signals.h',
+ '<(DEPTH)/starboard/shared/signal/suspend_signals.cc',
+ '<(DEPTH)/starboard/shared/signal/suspend_signals.h',
'<(DEPTH)/starboard/shared/starboard/application.cc',
'<(DEPTH)/starboard/shared/starboard/audio_sink/audio_sink_create.cc',
'<(DEPTH)/starboard/shared/starboard/audio_sink/audio_sink_destroy.cc',
diff --git a/src/starboard/linux/x64x11/main.cc b/src/starboard/linux/x64x11/main.cc
index 1331c05..7feb245 100644
--- a/src/starboard/linux/x64x11/main.cc
+++ b/src/starboard/linux/x64x11/main.cc
@@ -16,12 +16,16 @@
#include "starboard/configuration.h"
#include "starboard/shared/signal/crash_signals.h"
+#include "starboard/shared/signal/suspend_signals.h"
#include "starboard/shared/x11/application_x11.h"
int main(int argc, char** argv) {
tzset();
starboard::shared::signal::InstallCrashSignalHandlers();
+ starboard::shared::signal::InstallSuspendSignalHandlers();
starboard::shared::x11::ApplicationX11 application;
int result = application.Run(argc, argv);
+ starboard::shared::signal::UninstallSuspendSignalHandlers();
+ starboard::shared::signal::UninstallCrashSignalHandlers();
return result;
}
diff --git a/src/starboard/linux/x64x11/starboard_platform.gyp b/src/starboard/linux/x64x11/starboard_platform.gyp
index 65712a4..6276a96 100644
--- a/src/starboard/linux/x64x11/starboard_platform.gyp
+++ b/src/starboard/linux/x64x11/starboard_platform.gyp
@@ -199,6 +199,8 @@
'<(DEPTH)/starboard/shared/pthread/thread_yield.cc',
'<(DEPTH)/starboard/shared/signal/crash_signals.h',
'<(DEPTH)/starboard/shared/signal/crash_signals_sigaction.cc',
+ '<(DEPTH)/starboard/shared/signal/suspend_signals.cc',
+ '<(DEPTH)/starboard/shared/signal/suspend_signals.h',
'<(DEPTH)/starboard/shared/starboard/application.cc',
'<(DEPTH)/starboard/shared/starboard/audio_sink/audio_sink_create.cc',
'<(DEPTH)/starboard/shared/starboard/audio_sink/audio_sink_destroy.cc',
diff --git a/src/starboard/nplb/memory_set_test.cc b/src/starboard/nplb/memory_set_test.cc
index 2a647b4..0874104 100644
--- a/src/starboard/nplb/memory_set_test.cc
+++ b/src/starboard/nplb/memory_set_test.cc
@@ -31,7 +31,7 @@
void* result = SbMemorySet(memory, 0xCD, kSize);
EXPECT_EQ(memory, result);
for (int i = 0; i < kSize; ++i) {
- EXPECT_EQ(data[i], '\xCD');
+ ASSERT_EQ('\xCD', data[i]);
}
SbMemoryFree(memory);
@@ -47,7 +47,7 @@
void* result = SbMemorySet(memory, 0xCD, 0);
EXPECT_EQ(memory, result);
for (int i = 0; i < kSize; ++i) {
- EXPECT_EQ(data[i], static_cast<char>(i));
+ ASSERT_EQ(static_cast<char>(i), data[i]);
}
SbMemoryFree(memory);
@@ -63,7 +63,7 @@
void* result = SbMemorySet(memory, 0x6789ABCD, kSize);
EXPECT_EQ(memory, result);
for (int i = 0; i < kSize; ++i) {
- EXPECT_EQ(data[i], '\xCD');
+ ASSERT_EQ('\xCD', data[i]);
}
SbMemoryFree(memory);
diff --git a/src/starboard/nplb/system_get_property_test.cc b/src/starboard/nplb/system_get_property_test.cc
index 52c348b..de94895 100644
--- a/src/starboard/nplb/system_get_property_test.cc
+++ b/src/starboard/nplb/system_get_property_test.cc
@@ -74,7 +74,7 @@
if (IsCEDevice(SbSystemGetDeviceType())) {
BasicTest(kSbSystemPropertyBrandName, true, true, __LINE__);
BasicTest(kSbSystemPropertyModelName, true, true, __LINE__);
- BasicTest(kSbSystemPropertyModelYear, true, true, __LINE__);
+ BasicTest(kSbSystemPropertyModelYear, false, true, __LINE__);
} else {
BasicTest(kSbSystemPropertyBrandName, false, true, __LINE__);
BasicTest(kSbSystemPropertyModelName, false, true, __LINE__);
diff --git a/src/starboard/nplb/thread_yield_test.cc b/src/starboard/nplb/thread_yield_test.cc
index c6a07d1..17a4ed5 100644
--- a/src/starboard/nplb/thread_yield_test.cc
+++ b/src/starboard/nplb/thread_yield_test.cc
@@ -65,11 +65,11 @@
// thread gets started first, I hope to make this inherently flaky test not
// flaky.
//
-// Note: This test ended up EVER so slightly flaky, but within most
-// tolerances. If it fails on you randomly and inconsistently, it was probably
-// just a flake.
-TEST(SbThreadYieldTest, FLAKY_SunnyDayRace) {
- const int kTrials = 30;
+// Note: This test may still be flaky, but it should be a lot less flaky than
+// before. If this test starts flaking again, tag it with FLAKY_ again.
+TEST(SbThreadYieldTest, SunnyDayRace) {
+ const int kTrials = 20;
+ int passes = 0;
for (int trial = 0; trial < kTrials; ++trial) {
// Pin to CPU 0 to make sure the threads don't get distributed onto other
// cores.
@@ -106,8 +106,15 @@
}
}
- EXPECT_LT(average_unyielder, average_yielder) << "Trial " << trial;
+ // If unyielders took less time then yielders, on average, then we consider
+ // the trial a pass.
+ if (average_unyielder < average_yielder) {
+ ++passes;
+ }
}
+
+ // We expect at least 2/3 of the trials to pass.
+ EXPECT_LT(kTrials * 2 / 3, passes);
}
} // namespace
diff --git a/src/starboard/raspi/1/starboard_platform.gyp b/src/starboard/raspi/1/starboard_platform.gyp
index d5b6b23..f22110b 100644
--- a/src/starboard/raspi/1/starboard_platform.gyp
+++ b/src/starboard/raspi/1/starboard_platform.gyp
@@ -206,6 +206,8 @@
'<(DEPTH)/starboard/shared/pthread/thread_yield.cc',
'<(DEPTH)/starboard/shared/signal/crash_signals.cc',
'<(DEPTH)/starboard/shared/signal/crash_signals.h',
+ '<(DEPTH)/starboard/shared/signal/suspend_signals.cc',
+ '<(DEPTH)/starboard/shared/signal/suspend_signals.h',
'<(DEPTH)/starboard/shared/starboard/application.cc',
'<(DEPTH)/starboard/shared/starboard/audio_sink/audio_sink_create.cc',
'<(DEPTH)/starboard/shared/starboard/audio_sink/audio_sink_destroy.cc',
diff --git a/src/starboard/raspi/shared/main.cc b/src/starboard/raspi/shared/main.cc
index 1745d23..737c678 100644
--- a/src/starboard/raspi/shared/main.cc
+++ b/src/starboard/raspi/shared/main.cc
@@ -17,11 +17,15 @@
#include "starboard/configuration.h"
#include "starboard/raspi/shared/application_dispmanx.h"
#include "starboard/shared/signal/crash_signals.h"
+#include "starboard/shared/signal/suspend_signals.h"
int main(int argc, char** argv) {
tzset();
starboard::shared::signal::InstallCrashSignalHandlers();
+ starboard::shared::signal::InstallSuspendSignalHandlers();
starboard::raspi::shared::ApplicationDispmanx application;
int result = application.Run(argc, argv);
+ starboard::shared::signal::UninstallSuspendSignalHandlers();
+ starboard::shared::signal::UninstallCrashSignalHandlers();
return result;
}
diff --git a/src/starboard/shared/signal/crash_signals.cc b/src/starboard/shared/signal/crash_signals.cc
index 5c20870..a3e9b2e 100644
--- a/src/starboard/shared/signal/crash_signals.cc
+++ b/src/starboard/shared/signal/crash_signals.cc
@@ -18,6 +18,7 @@
#include "starboard/configuration.h"
#include "starboard/log.h"
+#include "starboard/shared/signal/signal_internal.h"
#include "starboard/system.h"
namespace starboard {
@@ -26,48 +27,44 @@
namespace {
-const int kSignalsToTrap[] = {
- SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV,
+const int kCrashSignalsToTrap[] = {
+ SIGABRT, SIGFPE, SIGILL, SIGSEGV,
};
-const char* GetSignalName(int signal_id) {
- switch (signal_id) {
- case SIGABRT:
- return "SIGABRT";
- case SIGFPE:
- return "SIGFPE";
- case SIGILL:
- return "SIGILL";
- case SIGINT:
- return "SIGINT";
- case SIGSEGV:
- return "SIGSEGV";
- default:
- return "UNKNOWN SIGNAL";
- }
-}
+const int kStopSignalsToTrap[] = {
+ SIGTERM, SIGINT,
+};
void DumpStackSignalSafe(int signal_id) {
- const char* signal_name = GetSignalName(signal_id);
- SbLogRawFormatF("\nCaught signal: %s (%d)\n", signal_name, signal_id);
- SbLogFlush();
+ LogSignalCaught(signal_id);
SbLogRawDumpStack(1);
UninstallCrashSignalHandlers();
SbSystemBreakIntoDebugger();
}
+void Stop(int signal_id) {
+ LogSignalCaught(signal_id);
+ SbSystemRequestStop(0);
+}
+
} // namespace
void InstallCrashSignalHandlers() {
- for (int i = 0; i < SB_ARRAY_SIZE_INT(kSignalsToTrap); ++i) {
- ::signal(kSignalsToTrap[i], &DumpStackSignalSafe);
+ for (int i = 0; i < SB_ARRAY_SIZE_INT(kCrashSignalsToTrap); ++i) {
+ ::signal(kCrashSignalsToTrap[i], &DumpStackSignalSafe);
+ }
+ for (int i = 0; i < SB_ARRAY_SIZE_INT(kStopSignalsToTrap); ++i) {
+ ::signal(kStopSignalsToTrap[i], &Stop);
}
}
void UninstallCrashSignalHandlers() {
- for (int i = 0; i < SB_ARRAY_SIZE_INT(kSignalsToTrap); ++i) {
- ::signal(kSignalsToTrap[i], SIG_DFL);
+ for (int i = 0; i < SB_ARRAY_SIZE_INT(kCrashSignalsToTrap); ++i) {
+ ::signal(kCrashSignalsToTrap[i], SIG_DFL);
+ }
+ for (int i = 0; i < SB_ARRAY_SIZE_INT(kStopSignalsToTrap); ++i) {
+ ::signal(kStopSignalsToTrap[i], SIG_DFL);
}
}
diff --git a/src/starboard/shared/signal/crash_signals_sigaction.cc b/src/starboard/shared/signal/crash_signals_sigaction.cc
index 735e506..4bf5b59 100644
--- a/src/starboard/shared/signal/crash_signals_sigaction.cc
+++ b/src/starboard/shared/signal/crash_signals_sigaction.cc
@@ -18,7 +18,7 @@
#include "starboard/configuration.h"
#include "starboard/log.h"
-#include "starboard/memory.h"
+#include "starboard/shared/signal/signal_internal.h"
#include "starboard/system.h"
namespace starboard {
@@ -27,42 +27,26 @@
namespace {
-const int kSignalsToTrap[] = {
- SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV,
+const int kCrashSignalsToTrap[] = {
+ SIGABRT, SIGFPE, SIGILL, SIGSEGV,
};
-const char* GetSignalName(int signal_id) {
- switch (signal_id) {
- case SIGABRT:
- return "SIGABRT";
- case SIGFPE:
- return "SIGFPE";
- case SIGILL:
- return "SIGILL";
- case SIGINT:
- return "SIGINT";
- case SIGSEGV:
- return "SIGSEGV";
- default:
- return "UNKNOWN SIGNAL";
- }
-}
-
-typedef void (*SignalHandlerFunction)(int);
+const int kStopSignalsToTrap[] = {
+ SIGTERM, SIGINT,
+};
void SetSignalHandler(int signal_id, SignalHandlerFunction handler) {
- struct sigaction action = {0};
+ struct sigaction action = {0};
- action.sa_handler = handler;
- action.sa_flags = 0;
- ::sigemptyset(&action.sa_mask);
+ action.sa_handler = handler;
+ action.sa_flags = 0;
+ ::sigemptyset(&action.sa_mask);
- ::sigaction(signal_id, &action, NULL);
+ ::sigaction(signal_id, &action, NULL);
}
void DumpStackSignalSafe(int signal_id) {
- const char* signal_name = GetSignalName(signal_id);
- SbLogRawFormatF("\nCaught signal: %s (%d)\n", signal_name, signal_id);
+ LogSignalCaught(signal_id);
SbLogFlush();
SbLogRawDumpStack(1);
@@ -70,17 +54,28 @@
SbSystemBreakIntoDebugger();
}
+void Stop(int signal_id) {
+ LogSignalCaught(signal_id);
+ SbSystemRequestStop(0);
+}
+
} // namespace
void InstallCrashSignalHandlers() {
- for (int i = 0; i < SB_ARRAY_SIZE_INT(kSignalsToTrap); ++i) {
- SetSignalHandler(kSignalsToTrap[i], &DumpStackSignalSafe);
+ for (int i = 0; i < SB_ARRAY_SIZE_INT(kCrashSignalsToTrap); ++i) {
+ SetSignalHandler(kCrashSignalsToTrap[i], &DumpStackSignalSafe);
+ }
+ for (int i = 0; i < SB_ARRAY_SIZE_INT(kStopSignalsToTrap); ++i) {
+ SetSignalHandler(kStopSignalsToTrap[i], &Stop);
}
}
void UninstallCrashSignalHandlers() {
- for (int i = 0; i < SB_ARRAY_SIZE_INT(kSignalsToTrap); ++i) {
- SetSignalHandler(kSignalsToTrap[i], SIG_DFL);
+ for (int i = 0; i < SB_ARRAY_SIZE_INT(kCrashSignalsToTrap); ++i) {
+ SetSignalHandler(kCrashSignalsToTrap[i], SIG_DFL);
+ }
+ for (int i = 0; i < SB_ARRAY_SIZE_INT(kStopSignalsToTrap); ++i) {
+ SetSignalHandler(kStopSignalsToTrap[i], SIG_DFL);
}
}
diff --git a/src/starboard/shared/signal/signal_internal.h b/src/starboard/shared/signal/signal_internal.h
new file mode 100644
index 0000000..f511ab0
--- /dev/null
+++ b/src/starboard/shared/signal/signal_internal.h
@@ -0,0 +1,62 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef STARBOARD_SHARED_SIGNAL_SIGNAL_INTERNAL_H_
+#define STARBOARD_SHARED_SIGNAL_SIGNAL_INTERNAL_H_
+
+#include <signal.h>
+
+#include "starboard/log.h"
+#include "starboard/shared/internal_only.h"
+
+namespace starboard {
+namespace shared {
+namespace signal {
+
+inline const char* GetSignalName(int signal_id) {
+ switch (signal_id) {
+ case SIGABRT:
+ return "SIGABRT";
+ case SIGCONT:
+ return "SIGCONT";
+ case SIGFPE:
+ return "SIGFPE";
+ case SIGILL:
+ return "SIGILL";
+ case SIGINT:
+ return "SIGINT";
+ case SIGSEGV:
+ return "SIGSEGV";
+ case SIGTSTP:
+ return "SIGTSTP";
+ case SIGTERM:
+ return "SIGTERM";
+ default:
+ return "UNKNOWN SIGNAL";
+ }
+}
+
+inline void LogSignalCaught(int signal_id) {
+ const char* signal_name = GetSignalName(signal_id);
+ SbLogRawFormatF("\nCaught signal: %s (%d)\n", signal_name, signal_id);
+ SbLogFlush();
+}
+
+typedef void (*SignalHandlerFunction)(int);
+
+} // namespace signal
+} // namespace shared
+} // namespace starboard
+
+#endif // STARBOARD_SHARED_SIGNAL_SIGNAL_INTERNAL_H_
diff --git a/src/starboard/shared/signal/suspend_signals.cc b/src/starboard/shared/signal/suspend_signals.cc
new file mode 100644
index 0000000..0ea0f09
--- /dev/null
+++ b/src/starboard/shared/signal/suspend_signals.cc
@@ -0,0 +1,73 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "starboard/shared/signal/suspend_signals.h"
+
+#include <signal.h>
+
+#include "starboard/configuration.h"
+#include "starboard/log.h"
+#include "starboard/memory.h"
+#include "starboard/shared/signal/signal_internal.h"
+#include "starboard/shared/starboard/application.h"
+#include "starboard/system.h"
+
+namespace starboard {
+namespace shared {
+namespace signal {
+
+namespace {
+
+void SetSignalHandler(int signal_id, SignalHandlerFunction handler) {
+ struct sigaction action = {0};
+
+ action.sa_handler = handler;
+ action.sa_flags = 0;
+ ::sigemptyset(&action.sa_mask);
+
+ ::sigaction(signal_id, &action, NULL);
+}
+
+void SuspendDone(void* /*context*/) {
+ SetSignalHandler(SIGTSTP, SIG_DFL);
+ raise(SIGTSTP);
+}
+
+void Suspend(int signal_id) {
+ LogSignalCaught(signal_id);
+ starboard::Application::Get()->Suspend(NULL, &SuspendDone);
+}
+
+void Resume(int signal_id) {
+ LogSignalCaught(signal_id);
+ SetSignalHandler(SIGTSTP, &Suspend);
+ // TODO: Resume or Unpause based on state.
+ starboard::Application::Get()->Unpause(NULL, NULL);
+}
+
+} // namespace
+
+void InstallSuspendSignalHandlers() {
+ SetSignalHandler(SIGTSTP, &Suspend);
+ SetSignalHandler(SIGCONT, &Resume);
+}
+
+void UninstallSuspendSignalHandlers() {
+ SetSignalHandler(SIGTSTP, SIG_DFL);
+ SetSignalHandler(SIGCONT, SIG_DFL);
+}
+
+} // namespace signal
+} // namespace shared
+} // namespace starboard
diff --git a/src/starboard/shared/signal/suspend_signals.h b/src/starboard/shared/signal/suspend_signals.h
new file mode 100644
index 0000000..730f8ad
--- /dev/null
+++ b/src/starboard/shared/signal/suspend_signals.h
@@ -0,0 +1,31 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef STARBOARD_SHARED_SIGNAL_SUSPEND_SIGNALS_H_
+#define STARBOARD_SHARED_SIGNAL_SUSPEND_SIGNALS_H_
+
+#include "starboard/shared/internal_only.h"
+
+namespace starboard {
+namespace shared {
+namespace signal {
+
+void InstallSuspendSignalHandlers();
+void UninstallSuspendSignalHandlers();
+
+} // namespace signal
+} // namespace shared
+} // namespace starboard
+
+#endif // STARBOARD_SHARED_SIGNAL_SUSPEND_SIGNALS_H_
diff --git a/src/starboard/shared/starboard/application.cc b/src/starboard/shared/starboard/application.cc
index b7ca314..26e08db 100644
--- a/src/starboard/shared/starboard/application.cc
+++ b/src/starboard/shared/starboard/application.cc
@@ -35,7 +35,7 @@
event.type = type;
event.data = data;
SbEventHandle(&event);
- if (destructor && event.data) {
+ if (destructor) {
destructor(event.data);
}
}
@@ -57,7 +57,10 @@
Application* Application::g_instance = NULL;
Application::Application()
- : error_level_(0), thread_(SbThreadGetCurrent()), start_link_(NULL) {
+ : error_level_(0),
+ thread_(SbThreadGetCurrent()),
+ start_link_(NULL),
+ state_(kStateUnstarted) {
Application* old_instance =
reinterpret_cast<Application*>(SbAtomicAcquire_CompareAndSwapPtr(
reinterpret_cast<SbAtomicPtr*>(&g_instance),
@@ -80,6 +83,7 @@
int Application::Run(int argc, char** argv) {
Initialize();
DispatchStart(argc, argv, start_link_);
+ state_ = kStateStarted;
for (;;) {
if (!DispatchAndDelete(GetNextEvent())) {
@@ -91,6 +95,22 @@
return error_level_;
}
+void Application::Pause(void* context, EventHandledCallback callback) {
+ Inject(new Event(kSbEventTypePause, context, callback));
+}
+
+void Application::Unpause(void* context, EventHandledCallback callback) {
+ Inject(new Event(kSbEventTypeUnpause, context, callback));
+}
+
+void Application::Suspend(void* context, EventHandledCallback callback) {
+ Inject(new Event(kSbEventTypeSuspend, context, callback));
+}
+
+void Application::Resume(void* context, EventHandledCallback callback) {
+ Inject(new Event(kSbEventTypeResume, context, callback));
+}
+
void Application::Stop(int error_level) {
Event* event = new Event(kSbEventTypeStop, NULL, NULL);
event->error_level = error_level;
@@ -134,18 +154,100 @@
return true;
}
- bool should_continue = true;
- if (event->event->type == kSbEventTypeStop) {
- should_continue = false;
- error_level_ = event->error_level;
+ // Ensure that we go through the the appropriate lifecycle events based on the
+ // current state.
+ switch (event->event->type) {
+ case kSbEventTypePause:
+ if (state() != kStateStarted) {
+ delete event;
+ return true;
+ }
+ break;
+ case kSbEventTypeUnpause:
+ if (state() == kStateStarted) {
+ delete event;
+ return true;
+ }
+
+ if (state() == kStateSuspended) {
+ Inject(new Event(kSbEventTypeResume, NULL, NULL));
+ Inject(event);
+ return true;
+ }
+ break;
+ case kSbEventTypeSuspend:
+ if (state() == kStateSuspended) {
+ delete event;
+ return true;
+ }
+
+ if (state() == kStateStarted) {
+ Inject(new Event(kSbEventTypePause, NULL, NULL));
+ Inject(event);
+ return true;
+ }
+ break;
+ case kSbEventTypeResume:
+ if (state() == kStateStarted || state() == kStatePaused) {
+ delete event;
+ return true;
+ }
+ break;
+ case kSbEventTypeStop:
+ if (state() == kStateStarted) {
+ Inject(new Event(kSbEventTypePause, NULL, NULL));
+ Inject(new Event(kSbEventTypeSuspend, NULL, NULL));
+ Inject(event);
+ return true;
+ }
+
+ if (state() == kStatePaused) {
+ Inject(new Event(kSbEventTypeSuspend, NULL, NULL));
+ Inject(event);
+ return true;
+ }
+ error_level_ = event->error_level;
+ break;
+ case kSbEventTypeScheduled: {
+ TimedEvent* timed_event =
+ reinterpret_cast<TimedEvent*>(event->event->data);
+ timed_event->callback(timed_event->context);
+ delete event;
+ return true;
+ }
+ default:
+ break;
}
- if (event->event->type == kSbEventTypeScheduled) {
- TimedEvent* timed_event = reinterpret_cast<TimedEvent*>(event->event->data);
- timed_event->callback(timed_event->context);
- } else {
- SbEventHandle(event->event);
+ SbEventHandle(event->event);
+
+ bool should_continue = true;
+ switch (event->event->type) {
+ case kSbEventTypePause:
+ SB_DCHECK(state() == kStateStarted);
+ state_ = kStatePaused;
+ break;
+ case kSbEventTypeUnpause:
+ SB_DCHECK(state() == kStatePaused);
+ state_ = kStateStarted;
+ break;
+ case kSbEventTypeSuspend:
+ SB_DCHECK(state() == kStatePaused);
+ state_ = kStateSuspended;
+ break;
+ case kSbEventTypeResume:
+ SB_DCHECK(state() == kStateSuspended);
+ state_ = kStatePaused;
+ break;
+ case kSbEventTypeStop:
+ SB_DCHECK(state() == kStateSuspended);
+ state_ = kStateStopped;
+ should_continue = false;
+ break;
+ default:
+ break;
}
+
delete event;
return should_continue;
}
diff --git a/src/starboard/shared/starboard/application.h b/src/starboard/shared/starboard/application.h
index 2c990a0..7328f2e 100644
--- a/src/starboard/shared/starboard/application.h
+++ b/src/starboard/shared/starboard/application.h
@@ -38,6 +38,32 @@
// dispatching events to the Starboard event handler, SbEventHandle.
class Application {
public:
+ // You can use a void(void *) function to signal that a state-transition event
+ // has completed.
+ typedef SbEventDataDestructor EventHandledCallback;
+
+ // Enumeration of states that the application can be in.
+ enum State {
+ // The initial Unstarted state.
+ kStateUnstarted,
+
+ // The normal foreground, fully-visible state after receiving the initial
+ // START event or after UNPAUSE from Paused.
+ kStateStarted,
+
+ // The background-but-visible or partially-obscured state after receiving an
+ // PAUSE event from Started or RESUME event from Suspended.
+ kStatePaused,
+
+ // The fully-obscured or about-to-be-terminated state after receiving a
+ // SUSPEND event in Paused.
+ kStateSuspended,
+
+ // The completely terminated state after receiving the STOP event in the
+ // Suspended state.
+ kStateStopped,
+ };
+
// Structure to keep track of scheduled events, also used as the data argument
// for kSbEventTypeScheduled Events.
struct TimedEvent {
@@ -75,8 +101,6 @@
// deleting the event and calling the destructor on its data when it is
// deleted.
struct Event {
- Event(SbEvent* event, SbEventDataDestructor destructor)
- : event(event), destructor(destructor), error_level(0) {}
Event(SbEventType type, void* data, SbEventDataDestructor destructor)
: event(new SbEvent()), destructor(destructor), error_level(0) {
event->type = type;
@@ -90,7 +114,7 @@
event->data = data;
}
~Event() {
- if (destructor && event->data) {
+ if (destructor) {
destructor(event->data);
}
if (event) {
@@ -120,8 +144,45 @@
// initialization and teardown events. Returns the resulting error level.
int Run(int argc, char** argv);
+ // Signals that the application should transition from STARTED to PAUSED as
+ // soon as possible. Does nothing if already PAUSED or SUSPENDED. May be
+ // called from an external thread.
+ //
+ // |context|: A context value to pass to |callback| on event completion. Must
+ // not be NULL if callback is not NULL.
+ // |callback|: A function to call on event completion, from the main thread.
+ void Pause(void* context, EventHandledCallback callback);
+
+ // Signals that the application should transition to STARTED as soon as
+ // possible, moving through all required state transitions to get there. Does
+ // nothing if already STARTED. May be called from an external thread.
+ //
+ // |context|: A context value to pass to |callback| on event completion. Must
+ // not be NULL if callback is not NULL.
+ // |callback|: A function to call on event completion, from the main thread.
+ void Unpause(void* context, EventHandledCallback callback);
+
+ // Signals that the application should transition to SUSPENDED as soon as
+ // possible, moving through all required state transitions to get there. Does
+ // nothing if already SUSPENDED. May be called from an external thread.
+ //
+ // |context|: A context value to pass to |callback| on event completion. Must
+ // not be NULL if callback is not NULL.
+ // |callback|: A function to call on event completion, from the main thread.
+ void Suspend(void* context, EventHandledCallback callback);
+
+ // Signals that the application should transition to PAUSED from SUSPENDED as
+ // soon as possible. Does nothing if already PAUSED or STARTED. May be called
+ // from an external thread.
+ //
+ // |context|: A context value to pass to |callback| on event completion. Must
+ // not be NULL if callback is not NULL.
+ // |callback|: A function to call on event completion, from the main thread.
+ void Resume(void* context, EventHandledCallback callback);
+
// Signals that the application should gracefully terminate as soon as
- // possible. May be called from an external thread.
+ // possible. Will transition through PAUSED and SUSPENDED to STOPPED as
+ // appropriate for the current state. May be called from an external thread.
void Stop(int error_level);
// Schedules an event into the event queue. May be called from an external
@@ -199,10 +260,14 @@
// event that initializes and starts Cobalt.
void SetStartLink(const char* start_link);
+ // Returns whether the current thread is the Application thread.
bool IsCurrentThread() const {
return SbThreadIsEqual(thread_, SbThreadGetCurrent());
}
+ // Returns the current application state.
+ State state() const { return state_; }
+
private:
// Dispatches |event| to the system event handler, taking ownership of the
// event. Returns whether to keep servicing the event queue, i.e. false means
@@ -222,6 +287,10 @@
// The deep link included in the Start event sent to Cobalt. Initially NULL,
// derived classes may set it during initialization using |SetStartLink|.
char* start_link_;
+
+ // The current state that the application is in based on what events it has
+ // actually processed. Should only be accessed on the main thread.
+ State state_;
};
} // namespace starboard
diff --git a/src/starboard/shared/starboard/audio_sink/stub_audio_sink_type.cc b/src/starboard/shared/starboard/audio_sink/stub_audio_sink_type.cc
index 09b2402..cd88dd8 100644
--- a/src/starboard/shared/starboard/audio_sink/stub_audio_sink_type.cc
+++ b/src/starboard/shared/starboard/audio_sink/stub_audio_sink_type.cc
@@ -106,7 +106,7 @@
&is_playing, &is_eos_reached, context_);
if (is_playing) {
int frames_to_consume =
- std::min(kMaxFramesToConsumePerRequest, frames_in_buffer / 2);
+ std::min(kMaxFramesToConsumePerRequest, frames_in_buffer);
SbThreadSleep(frames_to_consume * kSbTimeSecond / sampling_frequency_hz_);
consume_frame_func_(frames_to_consume, context_);
diff --git a/src/starboard/shared/starboard/queue_application.h b/src/starboard/shared/starboard/queue_application.h
index fa5ac0e..b48d8a7 100644
--- a/src/starboard/shared/starboard/queue_application.h
+++ b/src/starboard/shared/starboard/queue_application.h
@@ -54,10 +54,13 @@
virtual bool MayHaveSystemEvents() = 0;
// Returns an event if one exists, otherwise returns NULL.
- virtual Event* PollNextSystemEvent() = 0;
+ virtual Event* PollNextSystemEvent() {
+ return WaitForSystemEventWithTimeout(SbTime());
+ }
// Waits for an event until the timeout |time| runs out. If an event occurs
- // in this time, it is returned, otherwise NULL is returned.
+ // in this time, it is returned, otherwise NULL is returned. If |time| is zero
+ // or negative, then this should function effectively like a no-wait poll.
virtual Event* WaitForSystemEventWithTimeout(SbTime time) = 0;
// Wakes up any thread waiting within a call to
@@ -65,6 +68,20 @@
virtual void WakeSystemEventWait() = 0;
private:
+ // Specialization of Queue for starboard events. It differs in that it has
+ // the responsibility of deleting heap allocated starboard events in its
+ // destructor. Note the non-virtual destructor, which is intentional and
+ // safe, as Queue has no virtual functions and EventQueue is never used
+ // polymorphically.
+ class EventQueue : public Queue<Event*> {
+ public:
+ ~EventQueue() {
+ while (Event* event = Poll()) {
+ delete event;
+ }
+ }
+ };
+
class TimedEventQueue {
public:
TimedEventQueue();
@@ -99,7 +116,7 @@
TimedEventQueue timed_event_queue_;
// The queue of events that have not yet been dispatched.
- Queue<Event*> event_queue_;
+ EventQueue event_queue_;
};
} // namespace starboard
diff --git a/src/starboard/shared/stub/player_set_volume.cc b/src/starboard/shared/stub/player_set_volume.cc
new file mode 100644
index 0000000..5a45e91
--- /dev/null
+++ b/src/starboard/shared/stub/player_set_volume.cc
@@ -0,0 +1,17 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "starboard/player.h"
+
+void SbPlayerSetVolume(SbPlayer /*player*/, double /*volume*/) {}
diff --git a/src/starboard/shared/x11/application_x11.cc b/src/starboard/shared/x11/application_x11.cc
index bfde70b..1457e73 100644
--- a/src/starboard/shared/x11/application_x11.cc
+++ b/src/starboard/shared/x11/application_x11.cc
@@ -556,23 +556,18 @@
return key_modifiers;
}
-bool XNextEventPoll(Display* display, XEvent* out_event) {
- if (XPending(display) == 0) {
- return false;
- }
-
- XNextEvent(display, out_event);
- return true;
-}
-
bool XNextEventTimed(Display* display, XEvent* out_event, SbTime duration) {
if (XPending(display) == 0) {
+ if (duration <= SbTime()) {
+ return false;
+ }
+
int fd = ConnectionNumber(display);
fd_set read_set;
FD_ZERO(&read_set);
FD_SET(fd, &read_set);
struct timeval tv;
- SbTime clamped_duration = std::max(duration, (SbTime)0);
+ SbTime clamped_duration = std::max(duration, SbTime());
ToTimevalDuration(clamped_duration, &tv);
if (select(fd + 1, &read_set, NULL, NULL, &tv) == 0) {
return false;
@@ -762,20 +757,10 @@
return display_;
}
-shared::starboard::Application::Event* ApplicationX11::PollNextSystemEvent() {
- SB_DCHECK(display_);
-
- XEvent x_event;
-
- if (XNextEventPoll(display_, &x_event)) {
- return XEventToEvent(&x_event);
- }
-
- return NULL;
-}
-
shared::starboard::Application::Event*
ApplicationX11::WaitForSystemEventWithTimeout(SbTime time) {
+ SB_DCHECK(display_);
+
XEvent x_event;
if (XNextEventTimed(display_, &x_event, time)) {
@@ -878,6 +863,18 @@
data->key_location = XKeyEventToSbKeyLocation(x_key_event);
data->key_modifiers = XKeyEventToSbKeyModifiers(x_key_event);
return new Event(kSbEventTypeInput, data, &DeleteDestructor<SbInputData>);
+ } else if (x_event->type == FocusIn) {
+ Unpause(NULL, NULL);
+ return NULL;
+ } else if (x_event->type == FocusOut) {
+ Pause(NULL, NULL);
+ return NULL;
+ } else if (x_event->type == MapNotify) {
+ Resume(NULL, NULL);
+ return NULL;
+ } else if (x_event->type == UnmapNotify) {
+ Suspend(NULL, NULL);
+ return NULL;
}
SB_DLOG(INFO) << "Unrecognized event type = " << x_event->type;
diff --git a/src/starboard/shared/x11/application_x11.h b/src/starboard/shared/x11/application_x11.h
index 11b4aca..8bd9940 100644
--- a/src/starboard/shared/x11/application_x11.h
+++ b/src/starboard/shared/x11/application_x11.h
@@ -63,7 +63,6 @@
// --- QueueApplication overrides ---
bool MayHaveSystemEvents() SB_OVERRIDE;
- Event* PollNextSystemEvent() SB_OVERRIDE;
Event* WaitForSystemEventWithTimeout(SbTime time) SB_OVERRIDE;
void WakeSystemEventWait() SB_OVERRIDE;
diff --git a/src/starboard/shared/x11/window_internal.cc b/src/starboard/shared/x11/window_internal.cc
index 3885bf6..b17082a 100644
--- a/src/starboard/shared/x11/window_internal.cc
+++ b/src/starboard/shared/x11/window_internal.cc
@@ -78,7 +78,8 @@
}
XSetWindowAttributes swa = {0};
- swa.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask;
+ swa.event_mask =
+ KeyPressMask | KeyReleaseMask | StructureNotifyMask | FocusChangeMask;
swa.colormap =
XCreateColormap(display, root_window, x_visual_info.visual, AllocNone);
// Setting border_pixel to 0 is required if the requested window depth (e.g.
diff --git a/src/starboard/stub/starboard_platform.gyp b/src/starboard/stub/starboard_platform.gyp
index 1ac0c82..707fecd 100644
--- a/src/starboard/stub/starboard_platform.gyp
+++ b/src/starboard/stub/starboard_platform.gyp
@@ -109,6 +109,7 @@
'<(DEPTH)/starboard/shared/stub/player_seek.cc',
'<(DEPTH)/starboard/shared/stub/player_set_bounds.cc',
'<(DEPTH)/starboard/shared/stub/player_set_pause.cc',
+ '<(DEPTH)/starboard/shared/stub/player_set_volume.cc',
'<(DEPTH)/starboard/shared/stub/player_write_end_of_stream.cc',
'<(DEPTH)/starboard/shared/stub/player_write_sample.cc',
'<(DEPTH)/starboard/shared/stub/socket_accept.cc',
diff --git a/src/third_party/mozjs/cobalt_config/include/jscustomallocator.h b/src/third_party/mozjs/cobalt_config/include/jscustomallocator.h
index b8d70d1..4dcd88e 100644
--- a/src/third_party/mozjs/cobalt_config/include/jscustomallocator.h
+++ b/src/third_party/mozjs/cobalt_config/include/jscustomallocator.h
@@ -12,7 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#ifndef gc_JSCUSTOMALLOCATOR_H
+#define gc_JSCUSTOMALLOCATOR_H
+
+#include <algorithm>
+
#include "jstypes.h"
+#include "memory_allocator_reporter.h"
#include "starboard/memory.h"
#include "starboard/string.h"
@@ -20,25 +26,58 @@
#define JS_OOM_POSSIBLY_FAIL_REPORT(cx) do {} while(0)
static JS_INLINE void* js_malloc(size_t bytes) {
- return SbMemoryAllocate(bytes);
-}
-
-static JS_INLINE void* js_calloc(size_t bytes) {
- return SbMemoryCalloc(bytes, 1);
+ size_t reservation_bytes = AllocationMetadata::GetReservationBytes(bytes);
+ MemoryAllocatorReporter::Get()->UpdateAllocatedBytes(reservation_bytes);
+ void* metadata = SbMemoryAllocate(reservation_bytes);
+ AllocationMetadata::SetSizeToBaseAddress(metadata, reservation_bytes);
+ return AllocationMetadata::GetUserAddressFromBaseAddress(metadata);
}
static JS_INLINE void* js_calloc(size_t nmemb, size_t size) {
- return SbMemoryCalloc(nmemb, size);
+ size_t total_size = nmemb * size;
+ void* memory = js_malloc(total_size);
+ if (memory) {
+ SbMemorySet(memory, 0, total_size);
+ }
+ return memory;
}
-static JS_INLINE void* js_realloc(void* p, size_t bytes) {
- return SbMemoryReallocate(p, bytes);
+static JS_INLINE void* js_calloc(size_t bytes) {
+ return js_calloc(bytes, 1);
}
static JS_INLINE void js_free(void* p) {
- SbMemoryFree(p);
+ if (p == NULL) {
+ return;
+ }
+
+ AllocationMetadata* metadata =
+ AllocationMetadata::GetMetadataFromUserAddress(p);
+ MemoryAllocatorReporter::Get()->UpdateAllocatedBytes(-static_cast<ssize_t>(
+ AllocationMetadata::GetSizeOfAllocationFromMetadata(metadata)));
+ SbMemoryFree(metadata);
+}
+
+static JS_INLINE void* js_realloc(void* p, size_t bytes) {
+ AllocationMetadata* metadata =
+ AllocationMetadata::GetMetadataFromUserAddress(p);
+ size_t current_size =
+ AllocationMetadata::GetSizeOfAllocationFromMetadata(metadata);
+ size_t adjusted_size = AllocationMetadata::GetReservationBytes(bytes);
+
+ MemoryAllocatorReporter::Get()->UpdateAllocatedBytes(
+ static_cast<ssize_t>(adjusted_size - current_size));
+ void* new_ptr = SbMemoryReallocate(metadata, adjusted_size);
+ AllocationMetadata::SetSizeToBaseAddress(new_ptr, adjusted_size);
+ return AllocationMetadata::GetUserAddressFromBaseAddress(new_ptr);
}
static JS_INLINE char* js_strdup(char* s) {
- return SbStringDuplicate(s);
+ size_t length = SbStringGetLength(s) + 1;
+
+ char* new_ptr = reinterpret_cast<char*>(js_malloc(length));
+ SbStringCopy(new_ptr, s, length);
+ return new_ptr;
}
+
+#endif /* gc_JSCUSTOMALLOCATOR_H */
diff --git a/src/third_party/mozjs/js/src/gc/Memory.cpp b/src/third_party/mozjs/js/src/gc/Memory.cpp
index b9e5199..9c55ba1 100644
--- a/src/third_party/mozjs/js/src/gc/Memory.cpp
+++ b/src/third_party/mozjs/js/src/gc/Memory.cpp
@@ -7,6 +7,7 @@
#include "gc/Memory.h"
#include "jscntxt.h"
+#include "memory_allocator_reporter.h"
#include "js/HeapAPI.h"
@@ -324,13 +325,23 @@
JS_ASSERT(flags == 0);
JS_ASSERT(fd == -1);
JS_ASSERT(offset == 0);
- return SbMemoryMap(length, prot, "mozjs::gc::MapMemory");
+
+ void* result = SbMemoryMap(length, prot, "mozjs::gc::MapMemory");
+ if (result != SB_MEMORY_MAP_FAILED) {
+ MemoryAllocatorReporter::Get()->UpdateMappedBytes(length);
+ }
+ return result;
}
static inline bool
UnmapMemory(void* region, size_t length)
{
- return SbMemoryUnmap(region, length);
+ bool success = SbMemoryUnmap(region, length);
+ if (success) {
+ MemoryAllocatorReporter::Get()->UpdateMappedBytes(
+ -static_cast<ssize_t>(length));
+ }
+ return success;
}
#else
diff --git a/src/third_party/mozjs/js/src/jsstarboard-time.cpp b/src/third_party/mozjs/js/src/jsstarboard-time.cpp
index d5049e2..92d309b 100644
--- a/src/third_party/mozjs/js/src/jsstarboard-time.cpp
+++ b/src/third_party/mozjs/js/src/jsstarboard-time.cpp
@@ -15,8 +15,11 @@
#include "jsstarboard-time.h"
#include "mozilla/Assertions.h"
+#include "starboard/configuration.h"
#include "unicode/timezone.h"
+// If the Starboard platform has this quirk, do not use these functions.
+#if !SB_HAS_QUIRK(NO_TIMEZONE_NAME_SUPPORT)
SbTime getDSTOffset(int64_t utc_time_us) {
// UDate is in milliseconds from the epoch.
UDate udate = utc_time_us / kSbTimeMillisecond;
@@ -41,4 +44,4 @@
delete current_zone;
return raw_offset_ms * kSbTimeMillisecond;
}
-
+#endif
diff --git a/src/third_party/mozjs/js/src/jsutil.cpp b/src/third_party/mozjs/js/src/jsutil.cpp
index bd3e182..142f724 100644
--- a/src/third_party/mozjs/js/src/jsutil.cpp
+++ b/src/third_party/mozjs/js/src/jsutil.cpp
@@ -41,32 +41,6 @@
js_free(addr);
}
-class Compressor
-{
- /* Number of bytes we should hand to zlib each compressMore() call. */
- static const size_t CHUNKSIZE = 2048;
- z_stream zs;
- const unsigned char *inp;
- size_t inplen;
- size_t outbytes;
-
- public:
- enum Status {
- MOREOUTPUT,
- DONE,
- CONTINUE,
- OOM
- };
-
- Compressor(const unsigned char *inp, size_t inplen);
- ~Compressor();
- bool init();
- void setOutput(unsigned char *out, size_t outlen);
- size_t outWritten() const { return outbytes; }
- /* Compress some of the input. Return true if it should be called again. */
- Status compressMore();
-};
-
Compressor::Compressor(const unsigned char *inp, size_t inplen)
: inp(inp),
inplen(inplen),
diff --git a/src/third_party/mozjs/js/src/jsutil.h b/src/third_party/mozjs/js/src/jsutil.h
index 9306a26..9dcfa8f 100644
--- a/src/third_party/mozjs/js/src/jsutil.h
+++ b/src/third_party/mozjs/js/src/jsutil.h
@@ -17,6 +17,10 @@
#include "js/Utility.h"
+#ifdef USE_ZLIB
+#include "zlib.h"
+#endif
+
/* Forward declarations. */
struct JSContext;
@@ -262,6 +266,32 @@
#ifdef USE_ZLIB
+class Compressor
+{
+ /* Number of bytes we should hand to zlib each compressMore() call. */
+ static const size_t CHUNKSIZE = 2048;
+ z_stream zs;
+ const unsigned char *inp;
+ size_t inplen;
+ size_t outbytes;
+
+ public:
+ enum Status {
+ MOREOUTPUT,
+ DONE,
+ CONTINUE,
+ OOM
+ };
+
+ Compressor(const unsigned char *inp, size_t inplen);
+ ~Compressor();
+ bool init();
+ void setOutput(unsigned char *out, size_t outlen);
+ size_t outWritten() const { return outbytes; }
+ /* Compress some of the input. Return true if it should be called again. */
+ Status compressMore();
+};
+
/*
* Decompress a string. The caller must know the length of the output and
* allocate |out| to a string of that length.
diff --git a/src/third_party/mozjs/js/src/memory_allocator_reporter.cpp b/src/third_party/mozjs/js/src/memory_allocator_reporter.cpp
new file mode 100644
index 0000000..93d42df
--- /dev/null
+++ b/src/third_party/mozjs/js/src/memory_allocator_reporter.cpp
@@ -0,0 +1,83 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "memory_allocator_reporter.h"
+
+#include "starboard/once.h"
+
+namespace {
+// Control to initialize s_instance.
+SbOnceControl s_instance_control = SB_ONCE_INITIALIZER;
+MemoryAllocatorReporter* s_instance = NULL;
+
+void Initialize() {
+ s_instance = new MemoryAllocatorReporter();
+}
+
+void* OffsetPointer(void* base, ssize_t offset) {
+ uintptr_t base_as_int = reinterpret_cast<uintptr_t>(base);
+ return reinterpret_cast<void*>(base_as_int + offset);
+}
+} // namespace
+
+AllocationMetadata* AllocationMetadata::GetMetadataFromUserAddress(void* ptr) {
+ if (ptr == NULL) {
+ return NULL;
+ }
+
+ // The metadata lives just in front of the data.
+ void* meta_addr =
+ OffsetPointer(ptr, -static_cast<ssize_t>(sizeof(AllocationMetadata)));
+ return reinterpret_cast<AllocationMetadata*>(meta_addr);
+}
+
+void* AllocationMetadata::GetUserAddressFromBaseAddress(void* base_ptr) {
+ void* adjusted_base =
+ OffsetPointer(base_ptr, static_cast<ssize_t>(sizeof(AllocationMetadata)));
+ return adjusted_base;
+}
+
+void AllocationMetadata::SetSizeToBaseAddress(void* base_ptr, size_t size) {
+ if (base_ptr) {
+ AllocationMetadata* metadata =
+ reinterpret_cast<AllocationMetadata*>(base_ptr);
+ metadata->set_size_requested(size);
+ }
+}
+
+void MemoryAllocatorReporter::UpdateAllocatedBytes(ssize_t bytes) {
+ starboard::ScopedLock lock(mutex_);
+ current_bytes_allocated_ += bytes;
+}
+
+ssize_t MemoryAllocatorReporter::GetCurrentBytesAllocated() {
+ starboard::ScopedLock lock(mutex_);
+ return current_bytes_allocated_;
+}
+
+void MemoryAllocatorReporter::UpdateMappedBytes(ssize_t bytes) {
+ starboard::ScopedLock lock(mutex_);
+ current_bytes_mapped_ += bytes;
+}
+
+ssize_t MemoryAllocatorReporter::GetCurrentBytesMapped() {
+ starboard::ScopedLock lock(mutex_);
+ return current_bytes_mapped_;
+}
+
+// static
+MemoryAllocatorReporter* MemoryAllocatorReporter::Get() {
+ SbOnce(&s_instance_control, &Initialize);
+ return s_instance;
+}
diff --git a/src/third_party/mozjs/js/src/memory_allocator_reporter.h b/src/third_party/mozjs/js/src/memory_allocator_reporter.h
new file mode 100644
index 0000000..e0d679f
--- /dev/null
+++ b/src/third_party/mozjs/js/src/memory_allocator_reporter.h
@@ -0,0 +1,62 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef MemoryAllocatorReporter_h
+#define MemoryAllocatorReporter_h
+
+#include <sys/types.h>
+
+#include "starboard/mutex.h"
+
+class AllocationMetadata {
+ public:
+ static AllocationMetadata* GetMetadataFromUserAddress(void* ptr);
+ static void* GetUserAddressFromBaseAddress(void* base_ptr);
+ static size_t GetReservationBytes(size_t bytes_requested) {
+ return sizeof(AllocationMetadata) + bytes_requested;
+ }
+ static size_t GetSizeOfAllocationFromMetadata(AllocationMetadata* metadata) {
+ return metadata ? metadata->size_requested() : 0;
+ }
+ static void SetSizeToBaseAddress(void* base_ptr, size_t size);
+
+ size_t size_requested() { return size_requested_; }
+ void set_size_requested(size_t size) { size_requested_ = size; }
+
+ private:
+ // Bytes requested by the underlying allocator.
+ size_t size_requested_;
+};
+
+// Reporter that is used to report memory allocation.
+class MemoryAllocatorReporter {
+ public:
+ static MemoryAllocatorReporter* Get();
+
+ MemoryAllocatorReporter()
+ : current_bytes_allocated_(0), current_bytes_mapped_(0) {}
+
+ void UpdateAllocatedBytes(ssize_t bytes);
+ ssize_t GetCurrentBytesAllocated();
+
+ void UpdateMappedBytes(ssize_t bytes);
+ ssize_t GetCurrentBytesMapped();
+
+ private:
+ starboard::Mutex mutex_;
+ ssize_t current_bytes_allocated_;
+ ssize_t current_bytes_mapped_;
+};
+
+#endif /* MemoryAllocatorReporter_h */
diff --git a/src/third_party/mozjs/js/src/vm/DateTime.cpp b/src/third_party/mozjs/js/src/vm/DateTime.cpp
index cfca247..a78a121 100644
--- a/src/third_party/mozjs/js/src/vm/DateTime.cpp
+++ b/src/third_party/mozjs/js/src/vm/DateTime.cpp
@@ -8,8 +8,16 @@
#if defined(STARBOARD)
#include "jsstarboard-time.h"
+#include "starboard/configuration.h"
#include "starboard/time_zone.h"
-#else
+// For Starboard platforms that don't have support for getting the timezone
+// name, fall back to using localtime for conversion between UTC<->localtime.
+#if !SB_HAS_QUIRK(NO_TIMEZONE_NAME_SUPPORT)
+#define USE_STARBOARD_TIME
+#endif // !SB_HAS_QUIRK(NO_TIMEZONE_NAME_SUPPORT)
+#endif // defined(STARBOARD)
+
+#if !defined(USE_STARBOARD_TIME)
#include <time.h>
#endif
@@ -17,7 +25,7 @@
using mozilla::UnspecifiedNaN;
-#if !defined(STARBOARD)
+#if !defined(USE_STARBOARD_TIME)
static bool
ComputeLocalTime(time_t local, struct tm *ptm)
{
@@ -131,7 +139,7 @@
// local seconds' frame of reference and then subtract.
return local_secs - (utc_secs + SecondsPerDay);
}
-#endif // defined(STARBOARD)
+#endif // defined(USE_STARBOARD_TIME)
void
js::DateTimeInfo::updateTimeZoneAdjustment()
@@ -140,7 +148,7 @@
* The difference between local standard time and UTC will never change for
* a given time zone.
*/
-#if defined(STARBOARD)
+#if defined(USE_STARBOARD_TIME)
utcToLocalStandardOffsetSeconds = getTZOffset() / kSbTimeSecond;
#else
utcToLocalStandardOffsetSeconds = UTCToLocalStandardOffsetSeconds();
@@ -179,7 +187,7 @@
updateTimeZoneAdjustment();
}
-#if defined(STARBOARD)
+#if defined(USE_STARBOARD_TIME)
int64_t
js::DateTimeInfo::computeDSTOffsetMilliseconds(int64_t utcSeconds)
{
@@ -219,7 +227,7 @@
return diff * msPerSecond;
}
-#endif // defined(STARBOARD)
+#endif // defined(USE_STARBOARD_TIME)
int64_t
js::DateTimeInfo::getDSTOffsetMilliseconds(int64_t utcMilliseconds)
diff --git a/src/third_party/mozjs/mozjs.gypi b/src/third_party/mozjs/mozjs.gypi
index 9fb9822..6b85ee0 100644
--- a/src/third_party/mozjs/mozjs.gypi
+++ b/src/third_party/mozjs/mozjs.gypi
@@ -82,6 +82,7 @@
'js/src/jsweakmap.cpp',
'js/src/jsworkers.cpp',
'js/src/jswrapper.cpp',
+ 'js/src/memory_allocator_reporter.cpp',
'js/src/perf/jsperf.cpp',
'js/src/perf/pm_stub.cpp',
'js/src/prmjtime.cpp',
diff --git a/src/third_party/mozjs/test/jscustomallocator_test.cc b/src/third_party/mozjs/test/jscustomallocator_test.cc
new file mode 100644
index 0000000..e6702e1
--- /dev/null
+++ b/src/third_party/mozjs/test/jscustomallocator_test.cc
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jscustomallocator.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const size_t kSize = 1024 * 128;
+
+TEST(JSCustomallocator, JSMalloc) {
+ void* memory = js_malloc(kSize);
+ EXPECT_NE(static_cast<void*>(NULL), memory);
+ ssize_t current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated,
+ AllocationMetadata::GetReservationBytes(kSize));
+ js_free(memory);
+ current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated, 0);
+}
+
+TEST(JSCustomallocator, JSCallocWithNumber) {
+ void* memory = js_calloc(5, kSize);
+ EXPECT_NE(static_cast<void*>(NULL), memory);
+ ssize_t current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated,
+ AllocationMetadata::GetReservationBytes(5 * kSize));
+ js_free(memory);
+ current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated, 0);
+}
+
+TEST(JSCustomallocator, JSCalloc) {
+ void* memory = js_calloc(kSize);
+ EXPECT_NE(static_cast<void*>(NULL), memory);
+ ssize_t current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated,
+ AllocationMetadata::GetReservationBytes(kSize));
+ js_free(memory);
+ current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated, 0);
+}
+
+TEST(JSCustomallocator, JSReallocSmaller) {
+ void* memory = js_malloc(kSize);
+ ASSERT_NE(static_cast<void*>(NULL), memory);
+ char* data = static_cast<char*>(memory);
+ for (int i = 0; i < kSize; ++i) {
+ data[i] = i;
+ }
+
+ for (int i = 0; i < kSize; ++i) {
+ EXPECT_EQ(data[i], static_cast<char>(i));
+ }
+
+ ssize_t current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated,
+ AllocationMetadata::GetReservationBytes(kSize));
+
+ memory = js_realloc(memory, kSize / 2);
+ data = static_cast<char*>(memory);
+ ASSERT_NE(static_cast<void*>(NULL), memory);
+ for (int i = 0; i < kSize / 2; ++i) {
+ EXPECT_EQ(data[i], static_cast<char>(i));
+ }
+
+ current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated,
+ AllocationMetadata::GetReservationBytes(kSize / 2));
+
+ js_free(memory);
+
+ current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated, 0);
+}
+
+TEST(JSCustomallocator, JSReallocBigger) {
+ void* memory = js_malloc(kSize);
+ ASSERT_NE(static_cast<void*>(NULL), memory);
+ char* data = static_cast<char*>(memory);
+ for (int i = 0; i < kSize; ++i) {
+ data[i] = i;
+ }
+
+ for (int i = 0; i < kSize; ++i) {
+ EXPECT_EQ(data[i], static_cast<char>(i));
+ }
+
+ ssize_t current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated,
+ AllocationMetadata::GetReservationBytes(kSize));
+
+ memory = js_realloc(memory, kSize * 2);
+ ASSERT_NE(static_cast<void*>(NULL), memory);
+ data = static_cast<char*>(memory);
+ for (int i = 0; i < kSize; ++i) {
+ EXPECT_EQ(data[i], static_cast<char>(i));
+ }
+
+ for (int i = kSize; i < kSize * 2; ++i) {
+ data[i] = i;
+ }
+
+ for (int i = kSize; i < kSize * 2; ++i) {
+ EXPECT_EQ(data[i], static_cast<char>(i));
+ }
+
+ current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated,
+ AllocationMetadata::GetReservationBytes(kSize * 2));
+
+ js_free(memory);
+
+ current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated, 0);
+}
+
+TEST(JSCustomallocator, JSReallocNULL) {
+ void* memory = js_realloc(NULL, kSize);
+ EXPECT_NE(static_cast<void*>(NULL), memory);
+ ssize_t current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated,
+ AllocationMetadata::GetReservationBytes(kSize));
+
+ js_free(memory);
+
+ current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated, 0);
+}
+
+TEST(JSCustomallocator, JSStrdup) {
+ const char* input = "abcedfg123456";
+ char* dupe = js_strdup(const_cast<char*>(input));
+ const char* kNull = NULL;
+ EXPECT_NE(kNull, dupe);
+ EXPECT_EQ(0, SbStringCompareNoCase(input, dupe));
+ EXPECT_EQ(SbStringGetLength(input), SbStringGetLength(dupe));
+
+ ssize_t current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated, AllocationMetadata::GetReservationBytes(
+ SbStringGetLength(dupe) + 1));
+
+ js_free(dupe);
+
+ current_bytes_allocated =
+ MemoryAllocatorReporter::Get()->GetCurrentBytesAllocated();
+ EXPECT_EQ(current_bytes_allocated, 0);
+}
+
+} // namespace
diff --git a/src/third_party/skia/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/third_party/skia/src/gpu/effects/GrYUVtoRGBEffect.cpp
index 526e3be..77a5de6 100644
--- a/src/third_party/skia/src/gpu/effects/GrYUVtoRGBEffect.cpp
+++ b/src/third_party/skia/src/gpu/effects/GrYUVtoRGBEffect.cpp
@@ -88,7 +88,7 @@
fsBuilder->codeAppend(".r,\n\t\t");
fsBuilder->appendTextureLookup(samplers[1], coords[0].c_str(), coords[0].getType());
if (yuvEffect.fNV12) {
- fsBuilder->codeAppend(".ba,\n\t\t");
+ fsBuilder->codeAppend(".ra,\n\t\t");
} else {
fsBuilder->codeAppend(".r,\n\t\t");
fsBuilder->appendTextureLookup(samplers[2], coords[0].c_str(), coords[0].getType());