Import Cobalt 19.lts.3.194115
Signed-off-by: Andrew Top <aabtop@google.com>
diff --git a/src/base/bind_unittest.cc b/src/base/bind_unittest.cc
index 0d24dcb..fee9d45 100644
--- a/src/base/bind_unittest.cc
+++ b/src/base/bind_unittest.cc
@@ -16,7 +16,6 @@
using ::testing::StrictMock;
namespace base {
-namespace {
class IncompleteType;
@@ -810,5 +809,4 @@
#endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) &&
// GTEST_HAS_DEATH_TEST
-} // namespace
} // namespace base
diff --git a/src/base/threading/post_task_and_reply_impl.cc b/src/base/threading/post_task_and_reply_impl.cc
index 192198b..855364f 100644
--- a/src/base/threading/post_task_and_reply_impl.cc
+++ b/src/base/threading/post_task_and_reply_impl.cc
@@ -5,6 +5,7 @@
#include "base/threading/post_task_and_reply_impl.h"
#include "base/bind.h"
+#include "base/debug/leak_annotations.h"
#include "base/location.h"
#include "base/message_loop_proxy.h"
@@ -74,6 +75,11 @@
const tracked_objects::Location& from_here,
const Closure& task,
const Closure& reply) {
+ // As mentioned in a comment above, this code is prepared to leak in the case
+ // that the original calling message loop goes away while the task is being
+ // processed. Therefore, explicitly recognize this possibility by allowing
+ // memory leaks here.
+ ANNOTATE_SCOPED_MEMORY_LEAK;
PostTaskAndReplyRelay* relay =
new PostTaskAndReplyRelay(from_here, task, reply);
if (!PostTask(from_here, Bind(&PostTaskAndReplyRelay::Run,
diff --git a/src/cobalt/black_box_tests/black_box_tests.py b/src/cobalt/black_box_tests/black_box_tests.py
index a5c9897..a4000e0 100644
--- a/src/cobalt/black_box_tests/black_box_tests.py
+++ b/src/cobalt/black_box_tests/black_box_tests.py
@@ -26,8 +26,7 @@
]
# These tests only need app launchers with webdriver.
_TESTS_NO_SIGNAL = [
- # TODO: Re-enable cookie test after its flakiness is resovled.
- # 'persistent_cookie',
+ 'persistent_cookie',
'allow_eval',
'disable_eval_with_csp',
]
@@ -58,9 +57,12 @@
def tearDownClass(cls):
print('Done ' + cls.__name__)
- def CreateCobaltRunner(self, url, target_params=None):
+ def CreateCobaltRunner(self, url, target_params=[]):
+ all_target_params = target_params
+ if _device_params.target_params is not None:
+ all_target_params += _device_params.target_params
new_runner = black_box_cobalt_runner.BlackBoxCobaltRunner(
- device_params=_device_params, url=url, target_params=target_params)
+ device_params=_device_params, url=url, target_params=all_target_params)
return new_runner
@@ -97,11 +99,13 @@
def Run(self):
logging.basicConfig(level=logging.DEBUG)
GetDeviceParams()
+
if self.test_name:
suite = unittest.TestLoader().loadTestsFromModule(
importlib.import_module(_TEST_DIR_PATH + self.test_name))
else:
- suite = LoadTests(_device_params.platform, _device_params.config, _device_params.device_id)
+ suite = LoadTests(_device_params.platform, _device_params.config,
+ _device_params.device_id)
return_code = not unittest.TextTestRunner(
verbosity=0, stream=sys.stdout).run(suite).wasSuccessful()
return return_code
diff --git a/src/cobalt/black_box_tests/testdata/persistent_cookie.html b/src/cobalt/black_box_tests/testdata/persistent_cookie.html
index dd4c75f..d7e838f 100644
--- a/src/cobalt/black_box_tests/testdata/persistent_cookie.html
+++ b/src/cobalt/black_box_tests/testdata/persistent_cookie.html
@@ -67,8 +67,6 @@
} else if (event.keyCode === 99) {
thirdRun();
}
- // Flush local storage to ensure cookie is written before closing.
- h5vcc.storage.flush();
onEndTest();
}
setupFinished();
diff --git a/src/cobalt/browser/application.cc b/src/cobalt/browser/application.cc
index e0eb6b0..17fa2c9 100644
--- a/src/cobalt/browser/application.cc
+++ b/src/cobalt/browser/application.cc
@@ -681,10 +681,11 @@
#endif // SB_HAS(ON_SCREEN_KEYBOARD)
#if SB_HAS(CAPTIONS)
+ on_caption_settings_changed_event_callback_ = base::Bind(
+ &Application::OnCaptionSettingsChangedEvent, base::Unretained(this));
event_dispatcher_.AddEventCallback(
base::AccessibilityCaptionSettingsChangedEvent::TypeId(),
- base::Bind(&Application::OnCaptionSettingsChangedEvent,
- base::Unretained(this)));
+ on_caption_settings_changed_event_callback_);
#endif // SB_HAS(CAPTIONS)
#if defined(ENABLE_WEBDRIVER)
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
@@ -748,6 +749,26 @@
event_dispatcher_.RemoveEventCallback(base::WindowSizeChangedEvent::TypeId(),
window_size_change_event_callback_);
#endif // SB_API_VERSION >= 8
+#if SB_HAS(ON_SCREEN_KEYBOARD)
+ event_dispatcher_.RemoveEventCallback(
+ base::OnScreenKeyboardShownEvent::TypeId(),
+ on_screen_keyboard_shown_event_callback_);
+ event_dispatcher_.RemoveEventCallback(
+ base::OnScreenKeyboardHiddenEvent::TypeId(),
+ on_screen_keyboard_hidden_event_callback_);
+ event_dispatcher_.RemoveEventCallback(
+ base::OnScreenKeyboardFocusedEvent::TypeId(),
+ on_screen_keyboard_focused_event_callback_);
+ event_dispatcher_.RemoveEventCallback(
+ base::OnScreenKeyboardBlurredEvent::TypeId(),
+ on_screen_keyboard_blurred_event_callback_);
+#endif // SB_HAS(ON_SCREEN_KEYBOARD)
+#if SB_HAS(CAPTIONS)
+ event_dispatcher_.RemoveEventCallback(
+ base::AccessibilityCaptionSettingsChangedEvent::TypeId(),
+ on_caption_settings_changed_event_callback_);
+#endif // SB_HAS(CAPTIONS)
+
app_status_ = kShutDownAppStatus;
}
diff --git a/src/cobalt/browser/application.h b/src/cobalt/browser/application.h
index 6417e32..c0d0d62 100644
--- a/src/cobalt/browser/application.h
+++ b/src/cobalt/browser/application.h
@@ -110,6 +110,9 @@
base::EventCallback on_screen_keyboard_focused_event_callback_;
base::EventCallback on_screen_keyboard_blurred_event_callback_;
#endif // SB_HAS(ON_SCREEN_KEYBOARD)
+#if SB_HAS(CAPTIONS)
+ base::EventCallback on_caption_settings_changed_event_callback_;
+#endif // SB_HAS(CAPTIONS)
// Thread checkers to ensure that callbacks for network and application events
// always occur on the same thread.
diff --git a/src/cobalt/browser/web_module.cc b/src/cobalt/browser/web_module.cc
index cb9a1ae..4a777dd 100644
--- a/src/cobalt/browser/web_module.cc
+++ b/src/cobalt/browser/web_module.cc
@@ -1040,8 +1040,13 @@
void WebModule::Impl::SetSize(math::Size window_dimensions,
float video_pixel_ratio) {
+ // A value of 0.0 for the video pixel ratio means that the ratio could not be
+ // determined. In that case it should be assumed to be the same as the
+ // graphics resolution, which corresponds to a device pixel ratio of 1.0.
+ float device_pixel_ratio =
+ video_pixel_ratio == 0.0f ? 1.0f : video_pixel_ratio;
window_->SetSize(window_dimensions.width(), window_dimensions.height(),
- video_pixel_ratio);
+ device_pixel_ratio);
}
void WebModule::Impl::SetCamera3D(
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index ac2138c..7c34122 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-188191
\ No newline at end of file
+194115
\ No newline at end of file
diff --git a/src/cobalt/build/cobalt_configuration.gypi b/src/cobalt/build/cobalt_configuration.gypi
index 73074d5..f84dfc0 100644
--- a/src/cobalt/build/cobalt_configuration.gypi
+++ b/src/cobalt/build/cobalt_configuration.gypi
@@ -35,6 +35,7 @@
'cobalt_webapi_extension_source_idl_files%': [],
'cobalt_webapi_extension_generated_header_idl_files%': [],
'cobalt_media_source_2016%': 1,
+ 'cobalt_v8_buildtime_snapshot%': "false",
},
# Whether Cobalt is being built.
@@ -228,6 +229,9 @@
# Some platforms have difficulty linking snapshot_app_stats
'build_snapshot_app_stats%': 1,
+ # Set to "true" to enable v8 snapshot generation at Cobalt build time.
+ 'cobalt_v8_buildtime_snapshot%': '<(cobalt_v8_buildtime_snapshot)',
+
# Cache parameters
# The following set of parameters define how much memory is reserved for
@@ -574,6 +578,11 @@
'COBALT_DISABLE_SPDY',
],
}],
+ ['cobalt_v8_buildtime_snapshot == "true"', {
+ 'defines': [
+ 'COBALT_V8_BUILDTIME_SNAPSHOT=1',
+ ],
+ }]
],
}, # end of target_defaults
diff --git a/src/cobalt/build/cobalt_configuration.py b/src/cobalt/build/cobalt_configuration.py
index 6d0a316..30f4222 100644
--- a/src/cobalt/build/cobalt_configuration.py
+++ b/src/cobalt/build/cobalt_configuration.py
@@ -44,13 +44,6 @@
# Cobalt uses OpenSSL on all platforms.
'use_openssl': 1,
-
- # Set environmental variable to enable_vr: 'USE_VR'
- # Terminal: `export {varname}={value}`
- # Note: must also edit gyp_configuration.gypi per internal instructions.
-
- # Whether to enable VR.
- 'enable_vr': int(os.environ.get('USE_VR', 0)),
}
logging.info('Build Number: {}'.format(variables['cobalt_version']))
return variables
diff --git a/src/cobalt/content/ssl/certs/0a775a30.0 b/src/cobalt/content/ssl/certs/0a775a30.0
new file mode 100644
index 0000000..7d540a4
--- /dev/null
+++ b/src/cobalt/content/ssl/certs/0a775a30.0
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
+MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout
+736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A
+DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
+DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk
+fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA
+njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd
+-----END CERTIFICATE-----
diff --git a/src/cobalt/content/ssl/certs/1001acf7.0 b/src/cobalt/content/ssl/certs/1001acf7.0
new file mode 100644
index 0000000..5496703
--- /dev/null
+++ b/src/cobalt/content/ssl/certs/1001acf7.0
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH
+MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
+QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy
+MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl
+cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM
+f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX
+mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7
+zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P
+fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc
+vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4
+Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp
+zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO
+Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW
+k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+
+DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF
+lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW
+Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1
+d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z
+XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR
+gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3
+d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv
+J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg
+DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM
++SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy
+F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9
+SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws
+E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl
+-----END CERTIFICATE-----
diff --git a/src/cobalt/content/ssl/certs/2c11d503.0 b/src/cobalt/content/ssl/certs/2c11d503.0
deleted file mode 100644
index acedb11..0000000
--- a/src/cobalt/content/ssl/certs/2c11d503.0
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAxCzAJBgNVBAYT
-AkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEczMB4X
-DTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9w
-ZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQA
-IgNiAARK7liuTcpm3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5B
-ta1doYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4GA1UdDwEB
-/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAf
-BgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAKBggqhkjOPQQDAwNpADBmAjEAj6jcnboM
-BBf6Fek9LykBl7+BFjNAk2z8+e2AcG+qj9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta
-3U1fJAuwACEl74+nBCZx4nxp5V2a+EEfOzmTk51V6s2N8fvB
------END CERTIFICATE-----
diff --git a/src/cobalt/content/ssl/certs/451b5485.0 b/src/cobalt/content/ssl/certs/451b5485.0
deleted file mode 100644
index bf864ae..0000000
--- a/src/cobalt/content/ssl/certs/451b5485.0
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4xCzAJBgNVBAYT
-AkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjAeFw0x
-NDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0
-cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IA
-BM0PW1aC3/BFGtat93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uN
-Am8xIk0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0PAQH/BAQD
-AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMB8GA1Ud
-IwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqGSM49BAMDA2gAMGUCMHD+sAvZ94OX7PNV
-HdTcswYO/jOYnYs5kGuUIe22113WTNchp+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjl
-vPl5adytRSv3tjFzzAalU5ORGpOucGpnutee5WEaXw==
------END CERTIFICATE-----
diff --git a/src/cobalt/content/ssl/certs/608a55ad.0 b/src/cobalt/content/ssl/certs/608a55ad.0
deleted file mode 100644
index eb2e84f..0000000
--- a/src/cobalt/content/ssl/certs/608a55ad.0
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUAMEAxCzAJBgNV
-BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcy
-MB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM
-CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEB
-AQUAA4ICDwAwggIKAoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+
-Ntmh/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78eCbY2albz
-4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/61UWY0jUJ9gNDlP7ZvyCV
-eYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fEFY8ElggGQgT4hNYdvJGmQr5J1WqIP7wt
-UdGejeBSzFfdNTVY27SPJIjki9/ca1TSgSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz
-3GIZ38i1MH/1PCZ1Eb3XG7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj
-3CzMpSZyYhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaHvGOz
-9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4t/bQWVyJ98LVtZR0
-0dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/gh7PU3+06yzbXfZqfUAkBXKJOAGT
-y3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
-/zAdBgNVHQ4EFgQUajn6QiL35okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59
-M4PLuG53hq8wDQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz
-Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0nXGEL8pZ0keI
-mUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qTRmTFAHneIWv2V6CG1wZy7HBG
-S4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpTwm+bREx50B1ws9efAvSyB7DH5fitIw6mVskp
-EndI2S9G/Tvw/HRwkqWOOAgfZDC2t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ
-6e18CL13zSdkzJTaTkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97kr
-gCf2o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU3jg9CcCo
-SmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eAiN1nE28daCSLT7d0geX0
-YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14fWKGVyasvc0rQLW6aWQ9VGHgtPFGml4vm
-u7JwqkwR3v98KzfUetF3NI/n+UL3PIEMS1IK
------END CERTIFICATE-----
diff --git a/src/cobalt/content/ssl/certs/626dceaf.0 b/src/cobalt/content/ssl/certs/626dceaf.0
new file mode 100644
index 0000000..984f1d1
--- /dev/null
+++ b/src/cobalt/content/ssl/certs/626dceaf.0
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH
+MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
+QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy
+MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl
+cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv
+CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg
+GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu
+XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd
+re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu
+PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1
+mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K
+8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj
+x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR
+nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0
+kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok
+twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp
+8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT
+vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT
+z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA
+pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb
+pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB
+R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R
+RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk
+0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC
+5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF
+izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn
+yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC
+-----END CERTIFICATE-----
diff --git a/src/cobalt/content/ssl/certs/773e07ad.0 b/src/cobalt/content/ssl/certs/773e07ad.0
new file mode 100644
index 0000000..4e0d8e9
--- /dev/null
+++ b/src/cobalt/content/ssl/certs/773e07ad.0
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQswCQYDVQQGEwJD
+SDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEo
+MCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRa
+Fw00MjA1MDkwOTU4MzNaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQL
+ExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh
+bCBSb290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4nieUqjFqdr
+VCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4Wp2OQ0jnUsYd4XxiWD1Ab
+NTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
+BgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7TrYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0E
+AwMDaAAwZQIwJsdpW9zV57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtk
+AjEA2zQgMgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
+-----END CERTIFICATE-----
diff --git a/src/cobalt/content/ssl/certs/87229d21.0 b/src/cobalt/content/ssl/certs/87229d21.0
deleted file mode 100644
index 90c8eb7..0000000
--- a/src/cobalt/content/ssl/certs/87229d21.0
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV
-BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcx
-MB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM
-CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEB
-AQUAA4ICDwAwggIKAoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7fa
-Yp6bwiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX/uMftk87
-ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR077F9jAHiOH3BX2pfJLKO
-YheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGPuY4zbGneWK2gDqdkVBFpRGZPTBKnjix9
-xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLxp2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO
-9z0M+Yo0FMT7MzUj8czxKselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq
-3ywgsNw2TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+WG+Oi
-n6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPwvFEVVJSmdz7QdFG9
-URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYYEQRVzXR7z2FwefR7LFxckvzluFqr
-TJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
-/zAdBgNVHQ4EFgQUl0YhVyE12jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/Px
-N3DlCPaTKbYwDQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E
-PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kfgLMtMrpkZ2Cv
-uVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbSFXJfLkur1J1juONI5f6ELlgK
-n0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLh
-X4SPgPL0DTatdrOjteFkdjpY3H1PXlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80
-nR14SohWZ25g/4/Ii+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcm
-GS3tTAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L9109S5zvE/
-bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/KyPu1svf0OnWZzsD2097+o
-4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJAwSQiumPv+i2tCqjI40cHLI5kqiPAlxA
-OXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj1oxx
------END CERTIFICATE-----
diff --git a/src/cobalt/content/ssl/certs/9168f543.0 b/src/cobalt/content/ssl/certs/9168f543.0
deleted file mode 100644
index c037748..0000000
--- a/src/cobalt/content/ssl/certs/9168f543.0
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUAMD4xCzAJBgNV
-BAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTAe
-Fw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhD
-ZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQAD
-ggIPADCCAgoCggIBANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHN
-r49aiZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt6kuJPKNx
-Qv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP0FG7Yn2ksYyy/yARujVj
-BYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTv
-LRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDEEW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2
-z4QTd28n6v+WZxcIbekN1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc
-4nBvCGrch2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCTmehd
-4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV4EJQeIQEQWGw9CEj
-jy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPOWftwenMGE9nTdDckQQoRb5fc5+R+
-ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0G
-A1UdDgQWBBSowcCbkahDFXxdBie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHY
-lwuBsTANBgkqhkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh
-66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7/SMNkPX0XtPG
-YX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BSS7CTKtQ+FjPlnsZlFT5kOwQ/
-2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F
-6ALEUz65noe8zDUa3qHpimOHZR4RKttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilX
-CNQ314cnrUlZp5GrRHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWe
-tUNy6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEVV/xuZDDC
-VRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5g4VCXA9DO2pJNdWY9BW/
-+mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl++O/QmueD6i9a5jc2NvLi6Td11n0bt3+
-qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo=
------END CERTIFICATE-----
diff --git a/src/cobalt/content/ssl/certs/9ffb46dd.0 b/src/cobalt/content/ssl/certs/9ffb46dd.0
new file mode 100644
index 0000000..a041a76
--- /dev/null
+++ b/src/cobalt/content/ssl/certs/9ffb46dd.0
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICMzCCAbmgAwIBAgIOSBtqCfT5YHE6/oHMht0wCgYIKoZIzj0EAwMwXDELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExIDAeBgNVBAMTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFI4MB4XDTE2MDYx
+NTAwMDAwMFoXDTM2MDYxNTAwMDAwMFowXDELMAkGA1UEBhMCQkUxGTAXBgNVBAoT
+EEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExIDAeBgNVBAMTF0ds
+b2JhbFNpZ24gUm9vdCBDQSAtIFI4MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEuO58
+MIfYlB9Ua22Ynfx1+1uIq0K6jX05ft1EPTk84QWhSmRgrDemc7D5yUVLCwbQOuDx
+bV/6XltaUrV240bb1R6MdHpCyUE1T8bU4ihgqzSKzrFAI0alrhkkUnyQVUTOo0Iw
+QDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQULzoS
+JoDoisJQeG0GxDR+4kk5V3YwCgYIKoZIzj0EAwMDaAAwZQIxAMehPbKSkPrKXeAn
+hII7Icz0jfiUVvIgXxHArLxfFaULyBZDp/jFf40goH9e/BYcJwIwHoz1Vr8425zm
+pteEKebfDVMu6CsBt30JPLEyahqauArq6K0I8nQ51SsiNtzvRmbY
+-----END CERTIFICATE-----
diff --git a/src/cobalt/content/ssl/certs/a3418fda.0 b/src/cobalt/content/ssl/certs/a3418fda.0
new file mode 100644
index 0000000..07372d3
--- /dev/null
+++ b/src/cobalt/content/ssl/certs/a3418fda.0
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
+MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu
+hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l
+xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
+DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0
+CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx
+sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w==
+-----END CERTIFICATE-----
diff --git a/src/cobalt/content/ssl/certs/dc4d6a89.0 b/src/cobalt/content/ssl/certs/dc4d6a89.0
new file mode 100644
index 0000000..097abc0
--- /dev/null
+++ b/src/cobalt/content/ssl/certs/dc4d6a89.0
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEgMB4GA1UECxMX
+R2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds
+b2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQxMjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9i
+YWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFs
+U2lnbjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQss
+grRIxutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1kZguSgMpE
+3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxDaNc9PIrFsmbVkJq3MQbF
+vuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJwLnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqM
+PKq0pPbzlUoSB239jLKJz9CgYXfIWHSw1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+
+azayOeSsJDa38O+2HBNXk7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05O
+WgtH8wY2SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/hbguy
+CLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4nWUx2OVvq+aWh2IMP
+0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpYrZxCRXluDocZXFSxZba/jJvcE+kN
+b7gu3GduyYsRtYQUigAZcIN5kZeR1BonvzceMgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNV
+HSMEGDAWgBSubAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN
+nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGtIxg93eFyRJa0
+lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr6155wsTLxDKZmOMNOsIeDjHfrY
+BzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLjvUYAGm0CuiVdjaExUd1URhxN25mW7xocBFym
+Fe944Hn+Xds+qkxV/ZoVqW/hpvvfcDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr
+3TsTjxKM4kEaSHpzoHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB1
+0jZpnOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfspA9MRf/T
+uTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+vJJUEeKgDu+6B5dpffItK
+oZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+t
+JDfLRVpOoERIyNiwmcUVhAn21klJwGW45hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA=
+-----END CERTIFICATE-----
diff --git a/src/cobalt/dom/dom.gyp b/src/cobalt/dom/dom.gyp
index dbc0a88..28de740 100644
--- a/src/cobalt/dom/dom.gyp
+++ b/src/cobalt/dom/dom.gyp
@@ -240,8 +240,6 @@
'screenshot.h',
'screenshot_manager.cc',
'screenshot_manager.h',
- 'script_event_log.cc',
- 'script_event_log.h',
'security_policy_violation_event.cc',
'security_policy_violation_event.h',
'serializer.cc',
diff --git a/src/cobalt/dom/eme/media_keys.h b/src/cobalt/dom/eme/media_keys.h
index fcd5566..56c122c 100644
--- a/src/cobalt/dom/eme/media_keys.h
+++ b/src/cobalt/dom/eme/media_keys.h
@@ -45,7 +45,7 @@
MediaKeys(const std::string& key_system,
script::ScriptValueFactory* script_value_factory);
- media::DrmSystem* drm_system() const { return drm_system_.get(); }
+ scoped_refptr<media::DrmSystem> drm_system() const { return drm_system_; }
// Web API: MediaKeys.
diff --git a/src/cobalt/dom/generic_event_handler_reference.cc b/src/cobalt/dom/generic_event_handler_reference.cc
index 65ca43f..6f89eb9 100644
--- a/src/cobalt/dom/generic_event_handler_reference.cc
+++ b/src/cobalt/dom/generic_event_handler_reference.cc
@@ -17,7 +17,6 @@
#include "base/debug/trace_event.h"
#include "cobalt/dom/event.h"
#include "cobalt/dom/event_target.h"
-#include "cobalt/dom/script_event_log.h"
namespace cobalt {
namespace dom {
@@ -59,8 +58,6 @@
bool unpack_error_event) {
TRACE_EVENT1("cobalt::dom", "GenericEventHandlerReference::HandleEvent",
"Event Name", TRACE_STR_COPY(event->type().c_str()));
- script_event_log.Get().PushEvent(event);
-
bool had_exception;
base::optional<bool> result;
@@ -77,8 +74,6 @@
had_exception = true;
}
- script_event_log.Get().PopEvent();
-
if (had_exception) {
return;
}
diff --git a/src/cobalt/dom/html_media_element.cc b/src/cobalt/dom/html_media_element.cc
index ba28f7b..f05da17 100644
--- a/src/cobalt/dom/html_media_element.cc
+++ b/src/cobalt/dom/html_media_element.cc
@@ -278,20 +278,13 @@
DLOG_IF(ERROR, !key_system.empty())
<< "CanPlayType() only accepts one parameter but (" << key_system
<< ") is passed as a second parameter.";
+#endif // defined(COBALT_MEDIA_SOURCE_2016)
std::string result =
- html_element_context()->can_play_type_handler()->CanPlayType(mime_type,
- "");
- MLOG() << "(" << mime_type << ") => " << result;
- LOG(INFO) << "HTMLMediaElement::canPlayType(" << mime_type << ") -> "
- << result;
-#else // defined(COBALT_MEDIA_SOURCE_2016)
- std::string result =
- html_element_context()->can_play_type_handler()->CanPlayType(mime_type,
- key_system);
+ html_element_context()->can_play_type_handler()->CanPlayType(
+ true, mime_type, key_system);
MLOG() << "(" << mime_type << ", " << key_system << ") => " << result;
LOG(INFO) << "HTMLMediaElement::canPlayType(" << mime_type << ", "
<< key_system << ") -> " << result;
-#endif // defined(COBALT_MEDIA_SOURCE_2016)
return result;
}
diff --git a/src/cobalt/dom/media_source.cc b/src/cobalt/dom/media_source.cc
index ffd1ed6..c1908a5 100644
--- a/src/cobalt/dom/media_source.cc
+++ b/src/cobalt/dom/media_source.cc
@@ -223,7 +223,7 @@
DCHECK(dom_settings);
media::CanPlayTypeHandler* handler = dom_settings->can_play_type_handler();
DCHECK(handler);
- std::string result = handler->CanPlayType(type, "");
+ std::string result = handler->CanPlayType(false, type, "");
DLOG(INFO) << "MediaSource::IsTypeSupported(" << type << ") -> " << result;
return result == "probably";
}
diff --git a/src/cobalt/dom/on_error_event_listener.cc b/src/cobalt/dom/on_error_event_listener.cc
index 1401531..fb9daf0 100644
--- a/src/cobalt/dom/on_error_event_listener.cc
+++ b/src/cobalt/dom/on_error_event_listener.cc
@@ -21,7 +21,6 @@
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/dom/error_event.h"
#include "cobalt/dom/event_target.h"
-#include "cobalt/dom/script_event_log.h"
namespace cobalt {
namespace dom {
diff --git a/src/cobalt/dom/script_event_log.cc b/src/cobalt/dom/script_event_log.cc
deleted file mode 100644
index 9ede256..0000000
--- a/src/cobalt/dom/script_event_log.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2018 The Cobalt Authors. 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/dom/script_event_log.h"
-
-#include "cobalt/dom/event_target.h"
-
-namespace cobalt {
-namespace dom {
-
-ScriptEventLog::ScriptEventLog() : current_stack_depth_(0) {
- base::UserLog::Register(base::UserLog::kEventStackLevelCountIndex,
- "EventLevelCnt", ¤t_stack_depth_,
- sizeof(current_stack_depth_));
-
- memset(event_log_stack_, 0, sizeof(event_log_stack_));
- const int kLogNameBufferSize = 16;
- char log_name_buffer[kLogNameBufferSize];
- for (int i = 0; i < base::UserLog::kEventStackMaxDepth; i++) {
- snprintf(log_name_buffer, kLogNameBufferSize, "EventLevel%d", i);
- base::UserLog::Register(static_cast<base::UserLog::Index>(
- base::UserLog::kEventStackMinLevelIndex + i),
- log_name_buffer, event_log_stack_[i],
- kLogEntryMaxLength);
- }
-}
-
-ScriptEventLog::~ScriptEventLog() {
- base::UserLog::Deregister(base::UserLog::kEventStackLevelCountIndex);
- for (int i = 0; i < base::UserLog::kEventStackMaxDepth; i++) {
- base::UserLog::Deregister(static_cast<base::UserLog::Index>(
- base::UserLog::kEventStackMinLevelIndex + i));
- }
-}
-
-void ScriptEventLog::PushEvent(Event* event) {
- if (current_stack_depth_ < base::UserLog::kEventStackMaxDepth) {
- snprintf(event_log_stack_[current_stack_depth_], kLogEntryMaxLength,
- "%s@%s", event->type().c_str(),
- event->current_target()->GetDebugName().c_str());
- } else if (current_stack_depth_ == base::UserLog::kEventStackMaxDepth) {
- DLOG(WARNING) << "Reached maximum depth of " << kLogEntryMaxLength
- << ". Subsequent events will not be logged.";
- }
- current_stack_depth_++;
-}
-
-void ScriptEventLog::PopEvent() {
- DCHECK(current_stack_depth_);
- current_stack_depth_--;
- if (current_stack_depth_ < base::UserLog::kEventStackMaxDepth) {
- memset(event_log_stack_[current_stack_depth_], 0, kLogEntryMaxLength);
- }
-}
-
-base::LazyInstance<ScriptEventLog> script_event_log = LAZY_INSTANCE_INITIALIZER;
-
-} // namespace dom
-} // namespace cobalt
diff --git a/src/cobalt/dom/script_event_log.h b/src/cobalt/dom/script_event_log.h
deleted file mode 100644
index 3d77748..0000000
--- a/src/cobalt/dom/script_event_log.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018 The Cobalt Authors. 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_DOM_SCRIPT_EVENT_LOG_H_
-#define COBALT_DOM_SCRIPT_EVENT_LOG_H_
-
-#include "base/lazy_instance.h"
-#include "cobalt/base/user_log.h"
-#include "cobalt/dom/event.h"
-
-namespace cobalt {
-namespace dom {
-
-// This class records the nested events and manages the user log information.
-class ScriptEventLog {
- public:
- ScriptEventLog();
- ~ScriptEventLog();
- void PushEvent(Event* event);
- void PopEvent();
-
- private:
- static const size_t kLogEntryMaxLength = 64;
- int current_stack_depth_;
- char event_log_stack_[base::UserLog::kEventStackMaxDepth][kLogEntryMaxLength];
-
- DISALLOW_COPY_AND_ASSIGN(ScriptEventLog);
-};
-
-extern base::LazyInstance<ScriptEventLog> script_event_log;
-
-} // namespace dom
-} // namespace cobalt
-
-#endif // COBALT_DOM_SCRIPT_EVENT_LOG_H_
diff --git a/src/cobalt/h5vcc/h5vcc_accessibility.cc b/src/cobalt/h5vcc/h5vcc_accessibility.cc
index 948f3f8..9255ce9 100644
--- a/src/cobalt/h5vcc/h5vcc_accessibility.cc
+++ b/src/cobalt/h5vcc/h5vcc_accessibility.cc
@@ -62,10 +62,11 @@
dom::MutationObserverTaskManager* mutation_observer_task_manager)
: event_dispatcher_(event_dispatcher) {
message_loop_proxy_ = base::MessageLoopProxy::current();
+ on_application_event_callback_ = base::Bind(
+ &H5vccAccessibility::OnApplicationEvent, base::Unretained(this));
event_dispatcher_->AddEventCallback(
base::AccessibilitySettingsChangedEvent::TypeId(),
- base::Bind(&H5vccAccessibility::OnApplicationEvent,
- base::Unretained(this)));
+ on_application_event_callback_);
if (ShouldForceTextToSpeech()) {
#if SB_HAS(SPEECH_SYNTHESIS)
// Create a StarboardTTSEngine if the platform has speech synthesis.
@@ -88,6 +89,12 @@
}
}
+H5vccAccessibility::~H5vccAccessibility() {
+ event_dispatcher_->RemoveEventCallback(
+ base::AccessibilitySettingsChangedEvent::TypeId(),
+ on_application_event_callback_);
+}
+
bool H5vccAccessibility::built_in_screen_reader() const {
return screen_reader_ && screen_reader_->enabled();
}
diff --git a/src/cobalt/h5vcc/h5vcc_accessibility.h b/src/cobalt/h5vcc/h5vcc_accessibility.h
index 50dce1a..eefccd4 100644
--- a/src/cobalt/h5vcc/h5vcc_accessibility.h
+++ b/src/cobalt/h5vcc/h5vcc_accessibility.h
@@ -37,6 +37,7 @@
base::EventDispatcher* event_dispatcher,
const scoped_refptr<dom::Window>& window,
dom::MutationObserverTaskManager* mutation_observer_task_manager);
+ ~H5vccAccessibility();
bool high_contrast_text() const;
void AddHighContrastTextListener(
@@ -58,6 +59,7 @@
scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
+ base::EventCallback on_application_event_callback_;
base::EventDispatcher* event_dispatcher_;
scoped_ptr<H5vccAccessibilityCallbackReference> high_contrast_text_listener_;
scoped_ptr<accessibility::TTSEngine> tts_engine_;
diff --git a/src/cobalt/layout/box_generator.h b/src/cobalt/layout/box_generator.h
index f03eb6f..edc6ce1 100644
--- a/src/cobalt/layout/box_generator.h
+++ b/src/cobalt/layout/box_generator.h
@@ -108,7 +108,7 @@
const scoped_refptr<cssom::CSSComputedStyleDeclaration>
parent_css_computed_style_declaration_;
- const scoped_refptr<const web_animations::AnimationSet>& parent_animations_;
+ const scoped_refptr<const web_animations::AnimationSet> parent_animations_;
scoped_refptr<Paragraph>* paragraph_;
// The current element depth.
const int dom_element_depth_;
diff --git a/src/cobalt/layout/topmost_event_target.cc b/src/cobalt/layout/topmost_event_target.cc
index 8864210..ae53426 100644
--- a/src/cobalt/layout/topmost_event_target.cc
+++ b/src/cobalt/layout/topmost_event_target.cc
@@ -331,8 +331,10 @@
pointer_state->SetActive(pointer_event->pointer_id());
// Implicitly capture the pointer to the active element.
// https://www.w3.org/TR/pointerevents/#implicit-pointer-capture
- scoped_refptr<dom::HTMLElement> html_element =
- view->document()->active_element()->AsHTMLElement();
+ scoped_refptr<dom::HTMLElement> html_element;
+ if (view->document()->active_element()) {
+ html_element = view->document()->active_element()->AsHTMLElement();
+ }
if (html_element) {
pointer_state->SetPendingPointerCaptureTargetOverride(
pointer_event->pointer_id(), html_element);
diff --git a/src/cobalt/loader/file_fetcher.cc b/src/cobalt/loader/file_fetcher.cc
index fdcdaa7..b8d9e7d 100644
--- a/src/cobalt/loader/file_fetcher.cc
+++ b/src/cobalt/loader/file_fetcher.cc
@@ -54,6 +54,18 @@
FileFetcher::~FileFetcher() {
DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (message_loop_proxy_ != base::MessageLoopProxy::current()) {
+ // In case we are currently in the middle of a fetch (in which case it will
+ // be aborted), invalidate the weak pointers to this FileFetcher object to
+ // ensure that we do not process any responses from pending file I/O, which
+ // also guarantees that no new file I/O requests will be generated after the
+ // current one (if one is currently active).
+ weak_ptr_factory_.InvalidateWeakPtrs();
+ // Then wait for any currently active file I/O to complete, after which
+ // everything will be quiet and we can shutdown safely.
+ message_loop_proxy_->WaitForFence();
+ }
CloseFile();
}
diff --git a/src/cobalt/media/can_play_type_handler.h b/src/cobalt/media/can_play_type_handler.h
index 6fed16b..868b4a2 100644
--- a/src/cobalt/media/can_play_type_handler.h
+++ b/src/cobalt/media/can_play_type_handler.h
@@ -23,7 +23,8 @@
class CanPlayTypeHandler {
public:
virtual ~CanPlayTypeHandler() {}
- virtual std::string CanPlayType(const std::string& mime_type,
+ virtual std::string CanPlayType(bool is_progressive,
+ const std::string& mime_type,
const std::string& key_system) = 0;
protected:
diff --git a/src/cobalt/media/decoder_buffer_allocator.cc b/src/cobalt/media/decoder_buffer_allocator.cc
index 246f8db..3096515 100644
--- a/src/cobalt/media/decoder_buffer_allocator.cc
+++ b/src/cobalt/media/decoder_buffer_allocator.cc
@@ -125,6 +125,9 @@
if (!kEnableMultiblockAllocate || kEnableAllocationLog) {
void* p = reuse_allocator_->Allocate(size, alignment);
+ if (!p) {
+ return Allocations();
+ }
LOG_IF(INFO, kEnableAllocationLog)
<< "======== Media Allocation Log " << p << " " << size << " "
<< alignment << " " << context;
@@ -141,6 +144,9 @@
void* p = reuse_allocator_->AllocateBestBlock(alignment, context,
&allocated_size);
DCHECK_LE(allocated_size, size);
+ if (!p) {
+ return Allocations();
+ }
if (allocated_size == size) {
if (!UpdateAllocationRecord()) {
// UpdateAllocationRecord may fail with non-NULL p when capacity is
@@ -160,6 +166,9 @@
allocated_size = size;
void* p = reuse_allocator_->AllocateBestBlock(alignment, context,
&allocated_size);
+ if (!p) {
+ return Allocations();
+ }
if (!UpdateAllocationRecord()) {
update_allocation_record_failed = true;
reuse_allocator_->Free(p);
@@ -226,19 +235,21 @@
const VideoDecoderConfig& config) {
#if COBALT_MEDIA_BUFFER_USING_MEMORY_POOL || SB_API_VERSION >= 10
if (using_memory_pool_) {
- if (!reuse_allocator_) {
- return;
- }
- VideoResolution resolution =
- GetVideoResolution(config.visible_rect().size());
#if SB_API_VERSION >= 10
video_codec_ = MediaVideoCodecToSbMediaVideoCodec(config.codec());
resolution_width_ = config.visible_rect().size().width();
resolution_height_ = config.visible_rect().size().height();
bits_per_pixel_ = config.webm_color_metadata().BitsPerChannel;
+#endif // SB_API_VERSION >= 10
+ if (!reuse_allocator_) {
+ return;
+ }
+#if SB_API_VERSION >= 10
reuse_allocator_->set_max_capacity(SbMediaGetMaxBufferCapacity(
video_codec_, resolution_width_, resolution_height_, bits_per_pixel_));
#else // SB_API_VERSION >= 10
+ VideoResolution resolution =
+ GetVideoResolution(config.visible_rect().size());
if (reuse_allocator_->max_capacity() &&
resolution > kVideoResolution1080p) {
reuse_allocator_->set_max_capacity(COBALT_MEDIA_BUFFER_MAX_CAPACITY_4K);
diff --git a/src/cobalt/media/filters/shell_demuxer.cc b/src/cobalt/media/filters/shell_demuxer.cc
index 5232d1b..aca84cb 100644
--- a/src/cobalt/media/filters/shell_demuxer.cc
+++ b/src/cobalt/media/filters/shell_demuxer.cc
@@ -36,11 +36,7 @@
namespace media {
ShellDemuxerStream::ShellDemuxerStream(ShellDemuxer* demuxer, Type type)
- : demuxer_(demuxer),
- type_(type),
- last_buffer_timestamp_(kNoTimestamp),
- stopped_(false),
- total_buffer_size_(0) {
+ : demuxer_(demuxer), type_(type) {
TRACE_EVENT0("media_stack", "ShellDemuxerStream::ShellDemuxerStream()");
DCHECK(demuxer_);
}
@@ -71,6 +67,7 @@
} else {
// Do not pop EOS buffers, so that subsequent read requests also get EOS
total_buffer_size_ -= buffer->data_size();
+ --total_buffer_count_;
buffer_queue_.pop_front();
}
read_cb.Run(
@@ -139,6 +136,7 @@
buffer_queue_.push_back(buffer);
if (!buffer->end_of_stream()) {
total_buffer_size_ += buffer->data_size();
+ ++total_buffer_count_;
}
}
}
@@ -153,6 +151,11 @@
return total_buffer_size_;
}
+size_t ShellDemuxerStream::GetTotalBufferCount() const {
+ base::AutoLock auto_lock(lock_);
+ return total_buffer_count_;
+}
+
void ShellDemuxerStream::FlushBuffers() {
TRACE_EVENT0("media_stack", "ShellDemuxerStream::FlushBuffers()");
base::AutoLock auto_lock(lock_);
@@ -160,6 +163,7 @@
DLOG_IF(WARNING, !read_queue_.empty()) << "Read requests should be empty";
buffer_queue_.clear();
total_buffer_size_ = 0;
+ total_buffer_count_ = 0;
last_buffer_timestamp_ = kNoTimestamp;
}
@@ -169,6 +173,7 @@
base::AutoLock auto_lock(lock_);
buffer_queue_.clear();
total_buffer_size_ = 0;
+ total_buffer_count_ = 0;
last_buffer_timestamp_ = kNoTimestamp;
// fulfill any pending callbacks with EOS buffers set to end timestamp
for (ReadQueue::iterator it = read_queue_.begin(); it != read_queue_.end();
@@ -368,16 +373,26 @@
if (requested_au_) {
size_t total_buffer_size = audio_demuxer_stream_->GetTotalBufferSize() +
video_demuxer_stream_->GetTotalBufferSize();
+ size_t total_buffer_count = audio_demuxer_stream_->GetTotalBufferCount() +
+ video_demuxer_stream_->GetTotalBufferCount();
#if SB_API_VERSION >= 10
int progressive_budget = SbMediaGetProgressiveBufferBudget(
MediaVideoCodecToSbMediaVideoCodec(VideoConfig().codec()),
VideoConfig().visible_rect().size().width(),
VideoConfig().visible_rect().size().height(),
VideoConfig().webm_color_metadata().BitsPerChannel);
+ int progressive_duration_cap_in_seconds =
+ SbMediaGetBufferGarbageCollectionDurationThreshold() / kSbTimeSecond;
#else // SB_API_VERSION >= 10
int progressive_budget = COBALT_MEDIA_BUFFER_PROGRESSIVE_BUDGET;
+ int progressive_duration_cap_in_seconds =
+ COBALT_MEDIA_SOURCE_GARBAGE_COLLECTION_DURATION_THRESHOLD_IN_SECONDS;
#endif // SB_API_VERSION >= 10
- if (total_buffer_size >= progressive_budget) {
+ const int kEstimatedBufferCountPerSeconds = 70;
+ int progressive_buffer_count_cap =
+ progressive_duration_cap_in_seconds * kEstimatedBufferCountPerSeconds;
+ if (total_buffer_size >= progressive_budget ||
+ total_buffer_count > progressive_buffer_count_cap) {
// Retry after 100 milliseconds.
const base::TimeDelta kDelay = base::TimeDelta::FromMilliseconds(100);
blocking_thread_.message_loop()->PostDelayedTask(
diff --git a/src/cobalt/media/filters/shell_demuxer.h b/src/cobalt/media/filters/shell_demuxer.h
index ef33f0e..a560a91 100644
--- a/src/cobalt/media/filters/shell_demuxer.h
+++ b/src/cobalt/media/filters/shell_demuxer.h
@@ -62,6 +62,7 @@
void Stop();
base::TimeDelta GetLastBufferTimestamp() const;
size_t GetTotalBufferSize() const;
+ size_t GetTotalBufferCount() const;
private:
// The Ranges object doesn't offer a complement object so we rebuild
@@ -83,8 +84,8 @@
// 1. Used with the timestamp of the current frame to calculate the
// buffer range.
// 2. Used by the demuxer to deteminate what type of frame to get next.
- base::TimeDelta last_buffer_timestamp_;
- bool stopped_;
+ base::TimeDelta last_buffer_timestamp_ = kNoTimestamp;
+ bool stopped_ = false;
typedef std::deque<scoped_refptr<DecoderBuffer> > BufferQueue;
BufferQueue buffer_queue_;
@@ -92,7 +93,8 @@
typedef std::deque<ReadCB> ReadQueue;
ReadQueue read_queue_;
- size_t total_buffer_size_;
+ size_t total_buffer_size_ = 0;
+ size_t total_buffer_count_ = 0;
DISALLOW_COPY_AND_ASSIGN(ShellDemuxerStream);
};
diff --git a/src/cobalt/media/filters/source_buffer_stream.cc b/src/cobalt/media/filters/source_buffer_stream.cc
index 47b30d7..a2e2b21 100644
--- a/src/cobalt/media/filters/source_buffer_stream.cc
+++ b/src/cobalt/media/filters/source_buffer_stream.cc
@@ -1545,12 +1545,6 @@
return false;
}
- if (!audio_configs_[0].encryption_scheme().Matches(
- config.encryption_scheme())) {
- MEDIA_LOG(ERROR, media_log_) << "Audio encryption changes not allowed.";
- return false;
- }
-
// Check to see if the new config matches an existing one.
for (size_t i = 0; i < audio_configs_.size(); ++i) {
if (config.Matches(audio_configs_[i])) {
@@ -1599,12 +1593,6 @@
return false;
}
- if (!video_configs_[0].encryption_scheme().Matches(
- config.encryption_scheme())) {
- MEDIA_LOG(ERROR, media_log_) << "Video encryption changes not allowed.";
- return false;
- }
-
// Check to see if the new config matches an existing one.
for (size_t i = 0; i < video_configs_.size(); ++i) {
if (config.Matches(video_configs_[i])) {
diff --git a/src/cobalt/media/media_module_starboard.cc b/src/cobalt/media/media_module_starboard.cc
index 92dc615..2d63a41 100644
--- a/src/cobalt/media/media_module_starboard.cc
+++ b/src/cobalt/media/media_module_starboard.cc
@@ -23,6 +23,7 @@
#include "cobalt/system_window/system_window.h"
#include "nb/memory_scope.h"
#include "starboard/media.h"
+#include "starboard/string.h"
#include "starboard/window.h"
namespace cobalt {
@@ -32,8 +33,21 @@
class CanPlayTypeHandlerStarboard : public CanPlayTypeHandler {
public:
- std::string CanPlayType(const std::string& mime_type,
+ std::string CanPlayType(bool is_progressive, const std::string& mime_type,
const std::string& key_system) override {
+ if (is_progressive) {
+ // |mime_type| is something like:
+ // video/mp4
+ // video/webm
+ // video/mp4; codecs="avc1.4d401e"
+ // video/webm; codecs="vp9"
+ // We do a rough pre-filter to ensure that only video/mp4 is supported as
+ // progressive.
+ if (SbStringFindString(mime_type.c_str(), "video/mp4") == 0 &&
+ SbStringFindString(mime_type.c_str(), "application/x-mpegURL") == 0) {
+ return "";
+ }
+ }
SbMediaSupportType type =
SbMediaCanPlayMimeAndKeySystem(mime_type.c_str(), key_system.c_str());
switch (type) {
diff --git a/src/cobalt/media/player/web_media_player.h b/src/cobalt/media/player/web_media_player.h
index 3ca8eb7..f0a3238 100644
--- a/src/cobalt/media/player/web_media_player.h
+++ b/src/cobalt/media/player/web_media_player.h
@@ -193,7 +193,8 @@
// in |WebMediaPlayerClient::EncryptedMediaInitData|.
//
// |drm_system| must not be NULL. The method can only be called once.
- virtual void SetDrmSystem(DrmSystem* drm_system) = 0;
+ virtual void SetDrmSystem(
+ const scoped_refptr<media::DrmSystem>& drm_system) = 0;
};
// TODO: Add prefix "On" to all methods that handle events, such
diff --git a/src/cobalt/media/player/web_media_player_impl.cc b/src/cobalt/media/player/web_media_player_impl.cc
index 1920b76..373bb88 100644
--- a/src/cobalt/media/player/web_media_player_impl.cc
+++ b/src/cobalt/media/player/web_media_player_impl.cc
@@ -586,7 +586,8 @@
return true;
}
-void WebMediaPlayerImpl::SetDrmSystem(DrmSystem* drm_system) {
+void WebMediaPlayerImpl::SetDrmSystem(
+ const scoped_refptr<media::DrmSystem>& drm_system) {
DCHECK_EQ(static_cast<DrmSystem*>(NULL), drm_system_);
DCHECK_NE(static_cast<DrmSystem*>(NULL), drm_system);
diff --git a/src/cobalt/media/player/web_media_player_impl.h b/src/cobalt/media/player/web_media_player_impl.h
index 92fdb4a..c52a7a3 100644
--- a/src/cobalt/media/player/web_media_player_impl.h
+++ b/src/cobalt/media/player/web_media_player_impl.h
@@ -187,7 +187,7 @@
bool GetDebugReportDataAddress(void** out_address, size_t* out_size) override;
- void SetDrmSystem(DrmSystem* drm_system) override;
+ void SetDrmSystem(const scoped_refptr<media::DrmSystem>& drm_system) override;
void SetDrmSystemReadyCB(const DrmSystemReadyCB& drm_system_ready_cb);
void OnPipelineSeek(PipelineStatus status);
@@ -326,7 +326,7 @@
media_time_and_seeking_state_cb_;
DrmSystemReadyCB drm_system_ready_cb_;
- DrmSystem* drm_system_;
+ scoped_refptr<DrmSystem> drm_system_;
DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl);
};
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_texture_lookup_ellipse.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_texture_lookup_ellipse.glsl
new file mode 100644
index 0000000..ce95493
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_texture_lookup_ellipse.glsl
@@ -0,0 +1,37 @@
+#version 100
+uniform highp float u_skRTHeight;
+precision mediump float;
+uniform highp vec4 uellipse_Stage2;
+uniform highp sampler2D uTextureSampler_0_Stage1;
+varying mediump vec4 vcolor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+
+void main() {
+ highp vec2 _sktmpCoord = gl_FragCoord.xy;
+ highp vec4 sk_FragCoord = vec4(_sktmpCoord.x, u_skRTHeight - _sktmpCoord.y, 1.0, 1.0);
+ vec4 outputColor_Stage0;
+ {
+ outputColor_Stage0 = vcolor_Stage0;
+ }
+ vec4 output_Stage1;
+ {
+ output_Stage1 = texture2D(uTextureSampler_0_Stage1, vTransformedCoords_0_Stage0).wwww;
+ }
+ vec4 output_Stage2;
+ {
+ vec2 d = sk_FragCoord.xy - uellipse_Stage2.xy;
+ vec2 Z = d * uellipse_Stage2.zw;
+ float implicit = dot(Z, d) - 1.0;
+ float grad_dot = 4.0 * dot(Z, Z);
+ grad_dot = max(grad_dot, 0.0001);
+ float approx_dist = implicit * inversesqrt(grad_dot);
+ float alpha;
+ {
+ alpha = clamp(0.5 + approx_dist, 0.0, 1.0);
+ }
+ output_Stage2 = output_Stage1 * alpha;
+ }
+ {
+ gl_FragColor = outputColor_Stage0 * output_Stage2;
+ }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_texture_lookup_rectangle.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_texture_lookup_rectangle.glsl
new file mode 100644
index 0000000..d0d7f54
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_texture_lookup_rectangle.glsl
@@ -0,0 +1,37 @@
+#version 100
+uniform highp float u_skRTHeight;
+precision mediump float;
+uniform vec4 uinnerRect_Stage2;
+uniform vec2 uinvRadiiXY_Stage2;
+uniform highp sampler2D uTextureSampler_0_Stage1;
+varying mediump vec4 vcolor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+
+void main() {
+ highp vec2 _sktmpCoord = gl_FragCoord.xy;
+ highp vec4 sk_FragCoord = vec4(_sktmpCoord.x, u_skRTHeight - _sktmpCoord.y, 1.0, 1.0);
+ vec4 outputColor_Stage0;
+ {
+ outputColor_Stage0 = vcolor_Stage0;
+ }
+ vec4 output_Stage1;
+ {
+ output_Stage1 = texture2D(uTextureSampler_0_Stage1, vTransformedCoords_0_Stage0).wwww;
+ }
+ vec4 output_Stage2;
+ {
+ vec2 dxy0 = uinnerRect_Stage2.xy - sk_FragCoord.xy;
+ vec2 dxy1 = sk_FragCoord.xy - uinnerRect_Stage2.zw;
+ vec2 dxy = max(max(dxy0, dxy1), 0.0);
+ vec2 Z = dxy * uinvRadiiXY_Stage2.xy;
+ float implicit = dot(Z, dxy) - 1.0;
+ float grad_dot = 4.0 * dot(Z, Z);
+ grad_dot = max(grad_dot, 0.0001);
+ float approx_dist = implicit * inversesqrt(grad_dot);
+ float alpha = clamp(0.5 + approx_dist, 0.0, 1.0);
+ output_Stage2 = output_Stage1 * alpha;
+ }
+ {
+ gl_FragColor = outputColor_Stage0 * output_Stage2;
+ }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/vertex_skia_color_position_passthrough_4kx8k_texcoords.glsl b/src/cobalt/renderer/glimp_shaders/glsl/vertex_skia_color_position_passthrough_4kx8k_texcoords.glsl
new file mode 100644
index 0000000..911c25c
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/vertex_skia_color_position_passthrough_4kx8k_texcoords.glsl
@@ -0,0 +1,17 @@
+#version 100
+
+precision highp float;
+uniform highp vec4 urtAdjustment_Stage0;
+attribute highp vec2 inPosition;
+attribute mediump vec4 inColor;
+attribute highp vec2 inTextureCoords;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTextureCoords_Stage0;
+varying highp vec2 vIntTextureCoords_Stage0;
+void main() {
+ vinColor_Stage0 = inColor;
+ vec2 pos2 = inPosition;
+ vTextureCoords_Stage0 = inTextureCoords;
+ vIntTextureCoords_Stage0 = vec2(4096.0, 8192.0) * inTextureCoords;
+ gl_Position = vec4(pos2.x * urtAdjustment_Stage0.x + urtAdjustment_Stage0.y, pos2.y * urtAdjustment_Stage0.z + urtAdjustment_Stage0.w, 0.0, 1.0);
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/vertex_skia_distance_field_path.glsl b/src/cobalt/renderer/glimp_shaders/glsl/vertex_skia_distance_field_path.glsl
new file mode 100644
index 0000000..d052f69
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/vertex_skia_distance_field_path.glsl
@@ -0,0 +1,16 @@
+#version 100
+
+precision highp float;
+uniform highp vec4 urtAdjustment_Stage0;
+uniform highp mat3 uViewM_Stage0;
+attribute highp vec2 inPosition;
+attribute mediump vec4 inColor;
+attribute mediump vec2 inTextureCoords;
+varying highp vec2 vTextureCoords_Stage0;
+varying mediump vec4 vinColor_Stage0;
+void main() {
+ vinColor_Stage0 = inColor;
+ vTextureCoords_Stage0 = inTextureCoords;
+ vec2 pos2 = (uViewM_Stage0 * vec3(inPosition, 1.0)).xy;
+ gl_Position = vec4(pos2.x * urtAdjustment_Stage0.x + urtAdjustment_Stage0.y, pos2.y * urtAdjustment_Stage0.z + urtAdjustment_Stage0.w, 0.0, 1.0);
+}
diff --git a/src/cobalt/renderer/rasterizer/pixel_test.cc b/src/cobalt/renderer/rasterizer/pixel_test.cc
index 3655b47..6d773c3 100644
--- a/src/cobalt/renderer/rasterizer/pixel_test.cc
+++ b/src/cobalt/renderer/rasterizer/pixel_test.cc
@@ -1103,6 +1103,17 @@
ColorRGBA(1.0f, 0, 0, 1.0)));
}
+TEST_F(PixelTest, TooManyGlyphs) {
+ // Overflow the glyph atlas to force path rendering.
+ CompositionNode::Builder builder;
+ for (char ch = 33; ch < 127; ++ch) {
+ builder.AddChild(CreateTextNodeWithinSurface(
+ GetResourceProvider(), std::string(1, ch), FontStyle(), 500,
+ ColorRGBA(0, 0, 0, 0.1)));
+ }
+ TestTree(new CompositionNode(builder));
+}
+
TEST_F(PixelTest, ShearedText) {
TestTree(new MatrixTransformNode(
CreateTextNodeWithinSurface(GetResourceProvider(), "Cobalt", FontStyle(),
diff --git a/src/cobalt/renderer/rasterizer/testdata/TooManyGlyphs-expected.png b/src/cobalt/renderer/rasterizer/testdata/TooManyGlyphs-expected.png
new file mode 100644
index 0000000..4f577e3
--- /dev/null
+++ b/src/cobalt/renderer/rasterizer/testdata/TooManyGlyphs-expected.png
Binary files differ
diff --git a/src/cobalt/script/v8c/isolate_fellowship.cc b/src/cobalt/script/v8c/isolate_fellowship.cc
index 78a99e4..4cef531 100644
--- a/src/cobalt/script/v8c/isolate_fellowship.cc
+++ b/src/cobalt/script/v8c/isolate_fellowship.cc
@@ -53,7 +53,7 @@
}
}
-} // namespace
+} // namespace
IsolateFellowship::IsolateFellowship() {
TRACE_EVENT0("cobalt::script", "IsolateFellowship::IsolateFellowship");
@@ -68,7 +68,9 @@
// to write the snapshot data. We need to make sure all global command line
// flags are set before that.
V8FlagsInit();
+#if !defined(COBALT_V8_BUILDTIME_SNAPSHOT)
InitializeStartupData();
+#endif // !defined(COBALT_V8_BUILDTIME_SNAPSHOT)
}
IsolateFellowship::~IsolateFellowship() {
@@ -80,14 +82,17 @@
delete array_buffer_allocator;
array_buffer_allocator = nullptr;
+#if !defined(COBALT_V8_BUILDTIME_SNAPSHOT)
// Note that both us and V8 will have created this with new[], see
// "snapshot-common.cc". Also note that both startup data creation failure
// from V8 is possible, and deleting a null pointer is safe, so there is no
// DCHECK here.
delete[] startup_data.data;
startup_data = {nullptr, 0};
+#endif
}
+#if !defined(COBALT_V8_BUILDTIME_SNAPSHOT)
void IsolateFellowship::InitializeStartupData() {
TRACE_EVENT0("cobalt::script", "IsolateFellowship::InitializeStartupData");
DCHECK(startup_data.data == nullptr);
@@ -223,6 +228,7 @@
maybe_remove_cache_file();
}
+#endif // !defined(COBALT_V8_BUILDTIME_SNAPSHOT)
} // namespace v8c
} // namespace script
diff --git a/src/cobalt/script/v8c/isolate_fellowship.h b/src/cobalt/script/v8c/isolate_fellowship.h
index 6b6a631..705a126 100644
--- a/src/cobalt/script/v8c/isolate_fellowship.h
+++ b/src/cobalt/script/v8c/isolate_fellowship.h
@@ -18,8 +18,8 @@
#include "base/memory/singleton.h"
#include "cobalt/script/v8c/cobalt_platform.h"
#include "v8/include/libplatform/libplatform.h"
-#include "v8/include/v8-platform.h"
#include "v8/include/v8.h"
+#include "v8/include/v8-platform.h"
namespace cobalt {
namespace script {
@@ -28,7 +28,8 @@
// A helper singleton to hold global state required by all V8 isolates across
// the entire process (the fellowship). Initialization logic for this data is
// also handled here, most notably, the possible reading/writing of
-// |startup_data| from/to a cache file.
+// |startup_data| from/to a cache file if snapshot has not been generated at
+// build time.
struct IsolateFellowship {
public:
static IsolateFellowship* GetInstance() {
@@ -38,7 +39,9 @@
scoped_refptr<CobaltPlatform> platform = nullptr;
v8::ArrayBuffer::Allocator* array_buffer_allocator = nullptr;
+#if !defined(COBALT_V8_BUILDTIME_SNAPSHOT)
v8::StartupData startup_data = {nullptr, 0};
+#endif // !defined(COBALT_V8_BUILDTIME_SNAPSHOT)
friend struct StaticMemorySingletonTraits<IsolateFellowship>;
@@ -46,11 +49,13 @@
IsolateFellowship();
~IsolateFellowship();
+#if !defined(COBALT_V8_BUILDTIME_SNAPSHOT)
// Initialize |startup_data| by either reading it from a cache file or
// creating it. If creating it for the first time, then when appropriate
// (i.e. the platform has a suitable directory) attempt to write it to a cache
// file.
void InitializeStartupData();
+#endif // !defined(COBALT_V8_BUILDTIME_SNAPSHOT)
};
} // namespace v8c
diff --git a/src/cobalt/script/v8c/v8c_engine.cc b/src/cobalt/script/v8c/v8c_engine.cc
index 25daf87..cc55ee4 100644
--- a/src/cobalt/script/v8c/v8c_engine.cc
+++ b/src/cobalt/script/v8c/v8c_engine.cc
@@ -108,6 +108,7 @@
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator =
isolate_fellowship->array_buffer_allocator;
+#if !defined(COBALT_V8_BUILDTIME_SNAPSHOT)
auto* startup_data = &isolate_fellowship->startup_data;
if (startup_data->data != nullptr) {
create_params.snapshot_blob = startup_data;
@@ -117,6 +118,7 @@
LOG(WARNING) << "Isolate fellowship startup data was null, this will "
"significantly slow down startup time.";
}
+#endif // !defined(COBALT_V8_BUILDTIME_SNAPSHOT)
isolate_ = v8::Isolate::New(create_params);
CHECK(isolate_);
diff --git a/src/cobalt/storage/store_upgrade/upgrade_test.cc b/src/cobalt/storage/store_upgrade/upgrade_test.cc
index 2c8b4fb..c64d7df 100644
--- a/src/cobalt/storage/store_upgrade/upgrade_test.cc
+++ b/src/cobalt/storage/store_upgrade/upgrade_test.cc
@@ -73,8 +73,7 @@
Storage storage;
EXPECT_TRUE(storage.ParseFromArray(buffer.data() + kStorageHeaderSize,
- buffer.size()) -
- kStorageHeaderSize);
+ buffer.size() - kStorageHeaderSize));
if (storage.cookies(0).name() == "foo") {
ValidateCookie(storage.cookies(0), "foo", "bar", "localhost", "/",
diff --git a/src/cobalt/tools/automated_testing/cobalt_runner.py b/src/cobalt/tools/automated_testing/cobalt_runner.py
index 46ab679..29c4326 100644
--- a/src/cobalt/tools/automated_testing/cobalt_runner.py
+++ b/src/cobalt/tools/automated_testing/cobalt_runner.py
@@ -69,6 +69,7 @@
device_id = None
config = None
out_directory = None
+ target_params = None
class WindowDriverCreatedTimeoutException(Exception):
"""Exception thrown when WindowDriver was not created in time."""
@@ -92,9 +93,9 @@
url: The intial URL to launch Cobalt on.
log_file: The log file's name string.
target_params: An array of command line arguments to launch Cobalt
- with.
+ with.
success_message: Optional success message to be printed on successful
- exit.
+ exit.
"""
self.test_script_started = threading.Event()
@@ -242,15 +243,14 @@
def _KillLauncher(self):
"""Kills the launcher and its attached Cobalt instance."""
- try:
- self.launcher.Kill()
- except Exception as e: # pylint: disable=broad-except
- sys.stderr.write('Exception killing launcher:\n')
- sys.stderr.write('{}\n'.format(str(e)))
+ self.ExecuteJavaScript('window.close();')
self.runner_thread.join(COBALT_EXIT_TIMEOUT_SECONDS)
if self.runner_thread.isAlive():
- sys.stderr.write('***Runner thread still alive***\n')
+ sys.stderr.write(
+ '***Runner thread still alive after sending graceful shutdown command, try again by killing app***\n'
+ )
+ self.launcher.Kill()
# Once the write end of the pipe has been closed by the launcher, the reader
# thread will get EOF and exit.
self.reader_thread.join(COBALT_EXIT_TIMEOUT_SECONDS)
@@ -301,16 +301,20 @@
thread.interrupt_main()
return 0
+ def ExecuteJavaScript(self, js_code):
+ return self.webdriver.execute_script(js_code)
+
def GetCval(self, cval_name):
"""Returns the Python object represented by a JSON cval string.
Args:
cval_name: Name of the cval.
+
Returns:
Python object represented by the JSON cval string
"""
javascript_code = 'return h5vcc.cVal.getValue(\'{}\')'.format(cval_name)
- json_result = self.webdriver.execute_script(javascript_code)
+ json_result = self.ExecuteJavaScript(javascript_code)
if json_result is None:
return None
else:
@@ -322,6 +326,7 @@
Args:
css_selector: A CSS selector
expected_num: The expected number of the selector type to be found.
+
Raises:
Underlying WebDriver exceptions
"""
@@ -337,6 +342,7 @@
Args:
unique_selector: A CSS selector that will select only one element
+
Raises:
AssertException: the element isn't unique
Returns:
@@ -349,6 +355,7 @@
Args:
css_selector: A CSS selector
+
Raises:
AssertException: the element isn't found
"""
@@ -364,6 +371,7 @@
Args:
css_selector: A CSS selector
expected_num: Expected number of matching elements
+
Raises:
AssertException: expected_num isn't met
Returns:
@@ -406,6 +414,7 @@
Args:
url: URL string to be loaded by Cobalt.
+
Raises:
Underlying WebDriver exceptions
"""
@@ -434,5 +443,9 @@
device_params.config = args.config
device_params.device_id = args.device_id
device_params.out_directory = args.out_directory
+ if args.target_params == None:
+ device_params.target_params = []
+ else:
+ device_params.target_params = [args.target_params]
return device_params
diff --git a/src/cobalt/version.h b/src/cobalt/version.h
index e6a94f6..3c73b6c 100644
--- a/src/cobalt/version.h
+++ b/src/cobalt/version.h
@@ -35,6 +35,6 @@
// release is cut.
//.
-#define COBALT_VERSION "19.lts.2"
+#define COBALT_VERSION "19.lts.3"
#endif // COBALT_VERSION_H_
diff --git a/src/cobalt/webdriver/web_driver_module.cc b/src/cobalt/webdriver/web_driver_module.cc
index c0b24f4..993e0aa 100644
--- a/src/cobalt/webdriver/web_driver_module.cc
+++ b/src/cobalt/webdriver/web_driver_module.cc
@@ -445,8 +445,8 @@
} // NOLINT(readability/fn_size)
WebDriverModule::~WebDriverModule() {
- webdriver_thread_.message_loop()->PostTask(
- FROM_HERE, base::Bind(&WebDriverModule::StopServer,
+ webdriver_thread_.message_loop()->PostBlockingTask(
+ FROM_HERE, base::Bind(&WebDriverModule::StopServerAndSession,
base::Unretained(this)));
webdriver_thread_.Stop();
} // NOLINT(readability/fn_size)
@@ -474,8 +474,9 @@
base::Unretained(webdriver_dispatcher_.get()))));
}
-void WebDriverModule::StopServer() {
+void WebDriverModule::StopServerAndSession() {
webdriver_server_.reset();
+ session_.reset();
}
SessionDriver* WebDriverModule::GetSessionDriver(
diff --git a/src/cobalt/webdriver/web_driver_module.h b/src/cobalt/webdriver/web_driver_module.h
index 8d8c96f..347e3d6 100644
--- a/src/cobalt/webdriver/web_driver_module.h
+++ b/src/cobalt/webdriver/web_driver_module.h
@@ -71,7 +71,7 @@
private:
void StartServer(int server_port, const std::string& listen_ip);
- void StopServer();
+ void StopServerAndSession();
void GetServerStatus(
const base::Value* parameters,
const WebDriverDispatcher::PathVariableMap* path_variables,
diff --git a/src/nb/reuse_allocator_base.cc b/src/nb/reuse_allocator_base.cc
index 2a64b43..6a38327 100644
--- a/src/nb/reuse_allocator_base.cc
+++ b/src/nb/reuse_allocator_base.cc
@@ -329,10 +329,16 @@
std::size_t size_to_try = 0;
if (allocation_increment_ > size) {
size_to_try = std::max(size, allocation_increment_);
+ if (max_capacity_ && capacity_ + size_to_try > max_capacity_) {
+ return free_blocks_.end();
+ }
ptr = fallback_allocator_->AllocateForAlignment(&size_to_try, alignment);
}
if (ptr == NULL) {
size_to_try = size;
+ if (max_capacity_ && capacity_ + size_to_try > max_capacity_) {
+ return free_blocks_.end();
+ }
ptr = fallback_allocator_->AllocateForAlignment(&size_to_try, alignment);
}
if (ptr != NULL) {
@@ -350,6 +356,9 @@
// in the hope that they are continuous and can be connect to a block that is
// large enough to fulfill |size|.
size_t size_difference = size - free_blocks_.rbegin()->size();
+ if (max_capacity_ && capacity_ + size_difference > max_capacity_) {
+ return free_blocks_.end();
+ }
ptr = fallback_allocator_->AllocateForAlignment(&size_difference, alignment);
if (ptr == NULL) {
return free_blocks_.end();
diff --git a/src/nb/reuse_allocator_base.h b/src/nb/reuse_allocator_base.h
index cb70f0f..0e4f935 100644
--- a/src/nb/reuse_allocator_base.h
+++ b/src/nb/reuse_allocator_base.h
@@ -17,6 +17,7 @@
#ifndef NB_REUSE_ALLOCATOR_BASE_H_
#define NB_REUSE_ALLOCATOR_BASE_H_
+#include <algorithm>
#include <map>
#include <set>
#include <vector>
@@ -66,7 +67,9 @@
std::size_t max_capacity() const { return max_capacity_; }
void set_max_capacity(std::size_t max_capacity) {
- max_capacity_ = max_capacity;
+ // TODO: Properly implement decreasing the max capacity so that the
+ // capacity is not suddenly exceeded.
+ max_capacity_ = std::max(max_capacity, max_capacity_);
}
protected:
diff --git a/src/net/base/transport_security_state_unittest.cc b/src/net/base/transport_security_state_unittest.cc
index 7d7f7fe..69afef4 100644
--- a/src/net/base/transport_security_state_unittest.cc
+++ b/src/net/base/transport_security_state_unittest.cc
@@ -34,7 +34,7 @@
#include "crypto/nss_util.h"
#endif
-#if defined(__LB_SHELL__)
+#if defined(OS_STARBOARD)
// We don't support cert pinning, so it's not compiled in.
// Disable all tests related to cert pins.
#define MAYBE_IsPreloaded DISABLED_IsPreloaded
diff --git a/src/net/dial/dial_udp_socket_factory.cc b/src/net/dial/dial_udp_socket_factory.cc
index 3e5e2b0..f78a8d8 100644
--- a/src/net/dial/dial_udp_socket_factory.cc
+++ b/src/net/dial/dial_udp_socket_factory.cc
@@ -70,8 +70,14 @@
SetupSocketAfterCreate(s);
- if (!NativeBind(s, address))
+ if (!NativeBind(s, address)) {
+#if defined(OS_POSIX)
+ close(s);
+#elif defined(OS_STARBOARD)
+ SbSocketDestroy(s);
+#endif
return NULL;
+ }
SetupSocketAfterBind(s);
diff --git a/src/starboard/build/base_configuration.gypi b/src/starboard/build/base_configuration.gypi
index f085dfc..0853f2c 100644
--- a/src/starboard/build/base_configuration.gypi
+++ b/src/starboard/build/base_configuration.gypi
@@ -147,8 +147,6 @@
'compiler_flags_host%': [],
'compiler_flags_c_host%': [],
- 'compiler_flags_cc_host%': [],
- 'linker_flags_host%': [],
'defines_host%': [],
'platform_libraries%': [],
@@ -157,6 +155,38 @@
# List of platform-specific targets that get compiled into cobalt.
'cobalt_platform_dependencies%': [],
+
+ 'conditions': [
+ ['host_os=="linux"', {
+ 'conditions': [
+ ['target_arch=="arm" or target_arch=="ia32" or target_arch=="x32"\
+ or target_arch=="mips" or target_arch=="mipsel" or\
+ target_arch=="ppc"', {
+ # All the 32 bit CPU architectures v8 supports.
+ 'compiler_flags_cc_host%': [
+ '-m32',
+ '--std=gnu++11',
+ ],
+ 'linker_flags_host%': [
+ '-target', 'i386-unknown-linux-gnu',
+ '-pthread',
+ '-fuse-ld=lld',
+ ],
+ }, {
+ 'compiler_flags_cc_host%': [
+ '--std=gnu++11',
+ ],
+ 'linker_flags_host%': [
+ '-pthread',
+ '-fuse-ld=lld',
+ ],
+ }],
+ ],
+ }, {
+ 'compiler_flags_cc_host%': [],
+ 'linker_flags_host%': [],
+ }],
+ ],
},
'target_defaults': {
diff --git a/src/starboard/linux/shared/player_components_impl.cc b/src/starboard/linux/shared/player_components_impl.cc
index 809b7df..fe97e20 100644
--- a/src/starboard/linux/shared/player_components_impl.cc
+++ b/src/starboard/linux/shared/player_components_impl.cc
@@ -88,8 +88,12 @@
}
video_render_algorithm->reset(new VideoRenderAlgorithmImpl);
- *video_renderer_sink = new PunchoutVideoRendererSink(
- video_parameters.player, kVideoSinkRenderInterval);
+ if (video_parameters.output_mode == kSbPlayerOutputModeDecodeToTexture) {
+ *video_renderer_sink = NULL;
+ } else {
+ *video_renderer_sink = new PunchoutVideoRendererSink(
+ video_parameters.player, kVideoSinkRenderInterval);
+ }
}
void GetAudioRendererParams(int* max_cached_frames,
diff --git a/src/starboard/nplb/socket_join_multicast_group_test.cc b/src/starboard/nplb/socket_join_multicast_group_test.cc
index f6021b4..6b06998 100644
--- a/src/starboard/nplb/socket_join_multicast_group_test.cc
+++ b/src/starboard/nplb/socket_join_multicast_group_test.cc
@@ -14,6 +14,7 @@
#include "starboard/nplb/socket_helpers.h"
#include "starboard/socket.h"
+#include "starboard/thread.h"
#include "starboard/time.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -79,15 +80,16 @@
}
SbSocketAddress receive_address;
- int loop_counts = 10000;
+ SbTimeMonotonic stop_time = SbTimeGetMonotonicNow() + kSbTimeSecond;
while (true) {
// Breaks the case where the test will hang in a loop when
// SbSocketReceiveFrom() always returns kSbSocketPending.
- ASSERT_GE(loop_counts--, 0) << "Multicast timed out.";
+ ASSERT_LE(SbTimeGetMonotonicNow(), stop_time) << "Multicast timed out.";
int received = SbSocketReceiveFrom(
receive_socket, buf, SB_ARRAY_SIZE_INT(buf), &receive_address);
if (received < 0 &&
SbSocketGetLastError(receive_socket) == kSbSocketPending) {
+ SbThreadSleep(kSbTimeMillisecond);
continue;
}
EXPECT_EQ(SB_ARRAY_SIZE_INT(kBuf), received);
diff --git a/src/starboard/raspi/shared/launcher.py b/src/starboard/raspi/shared/launcher.py
index 20ffbbb..75e57c6 100644
--- a/src/starboard/raspi/shared/launcher.py
+++ b/src/starboard/raspi/shared/launcher.py
@@ -35,8 +35,8 @@
Args:
signum: Signal number that triggered this callback. Passed in when the
signal handler is called by python runtime.
- frame: Current stack frame. Passed in when the signal handler is called
- by python runtime.
+ frame: Current stack frame. Passed in when the signal handler is called by
+ python runtime.
"""
sys.exit(signum)
@@ -48,6 +48,7 @@
_RASPI_USERNAME = 'pi'
_RASPI_PASSWORD = 'raspberry'
+ _SSH_LOGIN_SIGNAL = 'cobalt-launcher-login-success'
# pexpect times out each second to allow Kill to quickly stop a test run
_PEXPECT_TIMEOUT = 1
@@ -101,7 +102,7 @@
raspi_test_path = os.path.join(test_base_dir, test_file)
# rsync command setup
- options = '-avzh --exclude obj*'
+ options = '-avzLh --exclude obj/ --exclude obj.host/ --exclude gen/'
source = test_dir_path
destination = raspi_user_hostname + ':~/'
self.rsync_command = 'rsync ' + options + ' ' + source + ' ' + destination
@@ -140,18 +141,26 @@
self.pexpect_process = pexpect.spawn(
command, timeout=Launcher._PEXPECT_TIMEOUT)
retry_count = 0
+ expected_prompts = [
+ r'.*Are\syou\ssure.*', # Fingerprint verification
+ r'\S+ password:', # Password prompt
+ '.*[a-zA-Z]+.*', # Any other text input
+ ]
while True:
- expected_prompts = [
- r'.*Are\syou\ssure.*', # Fingerprint verification
- r'\S+ password:', # Password prompt
- ]
try:
i = self.pexpect_process.expect(expected_prompts)
if i == 0:
self.pexpect_process.sendline('yes')
- else:
+ elif i == 1:
self.pexpect_process.sendline(Launcher._RASPI_PASSWORD)
break
+ else:
+ # If any other input comes in, maybe we've logged in with rsa key or
+ # raspi does not have password. Check if we've logged in by echoing
+ # a special sentence and expect it back.
+ self.pexpect_process.sendline('echo ' + Launcher._SSH_LOGIN_SIGNAL)
+ i = self.pexpect_process.expect([Launcher._SSH_LOGIN_SIGNAL])
+ break
except pexpect.TIMEOUT:
if self.shutdown_initiated.is_set():
return
@@ -232,8 +241,7 @@
logging.exception('pexpect encountered EOF while reading line.')
except pexpect.TIMEOUT:
logging.exception('pexpect timed out while reading line.')
- # pylint: disable=W0703
- except Exception:
+ except Exception: # pylint: disable=broad-except
logging.exception('Error occured while running test.')
finally:
self._CleanupPexpectProcess()
diff --git a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder_impl.cc b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder_impl.cc
index 37170aa..e60fe47 100644
--- a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder_impl.cc
+++ b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder_impl.cc
@@ -188,6 +188,9 @@
TeardownCodec();
InitializeCodec();
}
+
+ decltype(frames_) frames;
+ frames_ = std::queue<scoped_refptr<CpuVideoFrame>>();
}
bool VideoDecoderImpl<FFMPEG>::is_valid() const {
@@ -293,29 +296,25 @@
bool result = true;
if (output_mode_ == kSbPlayerOutputModeDecodeToTexture) {
- result = UpdateDecodeTarget(frame);
+ frames_.push(frame);
}
decoder_status_cb_(kBufferFull, frame);
- return result;
+ return true;
}
-bool VideoDecoderImpl<FFMPEG>::UpdateDecodeTarget(
+void VideoDecoderImpl<FFMPEG>::UpdateDecodeTarget_Locked(
const scoped_refptr<CpuVideoFrame>& frame) {
SbDecodeTarget decode_target = DecodeTargetCreate(
decode_target_graphics_context_provider_, frame, decode_target_);
// Lock only after the post to the renderer thread, to prevent deadlock.
- ScopedLock lock(decode_target_mutex_);
decode_target_ = decode_target;
if (!SbDecodeTargetIsValid(decode_target)) {
SB_LOG(ERROR) << "Could not acquire a decode target from provider.";
- return false;
}
-
- return true;
}
void VideoDecoderImpl<FFMPEG>::InitializeCodec() {
@@ -397,6 +396,12 @@
// We must take a lock here since this function can be called from a
// separate thread.
ScopedLock lock(decode_target_mutex_);
+ while (frames_.size() > 1 && frames_.front()->HasOneRef()) {
+ frames_.pop();
+ }
+ if (!frames_.empty()) {
+ UpdateDecodeTarget_Locked(frames_.front());
+ }
if (SbDecodeTargetIsValid(decode_target_)) {
// Make a disposable copy, since the state is internally reused by this
// class (to avoid recreating GL objects).
diff --git a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder_impl.h b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder_impl.h
index b1b05b3..b7a55e8 100644
--- a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder_impl.h
+++ b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder_impl.h
@@ -15,6 +15,8 @@
#ifndef STARBOARD_SHARED_FFMPEG_FFMPEG_VIDEO_DECODER_IMPL_H_
#define STARBOARD_SHARED_FFMPEG_FFMPEG_VIDEO_DECODER_IMPL_H_
+#include <queue>
+
#include "starboard/common/ref_counted.h"
#include "starboard/log.h"
#include "starboard/media.h"
@@ -114,7 +116,7 @@
void TeardownCodec();
SbDecodeTarget GetCurrentDecodeTarget() override;
- bool UpdateDecodeTarget(const scoped_refptr<CpuVideoFrame>& frame);
+ void UpdateDecodeTarget_Locked(const scoped_refptr<CpuVideoFrame>& frame);
FFMPEGDispatch* ffmpeg_;
@@ -158,6 +160,7 @@
// int frame_last_rendered_pts_;
// scoped_refptr<VideoFrame> frame_;
+ std::queue<scoped_refptr<CpuVideoFrame>> frames_;
};
} // namespace ffmpeg
diff --git a/src/starboard/shared/libvpx/vpx_video_decoder.cc b/src/starboard/shared/libvpx/vpx_video_decoder.cc
index fdd2a35..b511b68 100644
--- a/src/starboard/shared/libvpx/vpx_video_decoder.cc
+++ b/src/starboard/shared/libvpx/vpx_video_decoder.cc
@@ -104,6 +104,9 @@
stream_ended_ = false;
TeardownCodec();
+
+ ScopedLock lock(decode_target_mutex_);
+ frames_ = std::queue<scoped_refptr<CpuVideoFrame>>();
}
// static
@@ -134,21 +137,17 @@
}
}
-bool VideoDecoder::UpdateDecodeTarget(
+void VideoDecoder::UpdateDecodeTarget_Locked(
const scoped_refptr<CpuVideoFrame>& frame) {
SbDecodeTarget decode_target = DecodeTargetCreate(
decode_target_graphics_context_provider_, frame, decode_target_);
// Lock only after the post to the renderer thread, to prevent deadlock.
- ScopedLock lock(decode_target_mutex_);
decode_target_ = decode_target;
if (!SbDecodeTargetIsValid(decode_target)) {
SB_LOG(ERROR) << "Could not acquire a decode target from provider.";
- return false;
}
-
- return true;
}
void VideoDecoder::ReportError(const std::string& error_message) {
@@ -268,7 +267,8 @@
vpx_image->stride[VPX_PLANE_Y], timestamp, vpx_image->planes[VPX_PLANE_Y],
vpx_image->planes[VPX_PLANE_U], vpx_image->planes[VPX_PLANE_V]);
if (output_mode_ == kSbPlayerOutputModeDecodeToTexture) {
- UpdateDecodeTarget(frame);
+ ScopedLock lock(decode_target_mutex_);
+ frames_.push(frame);
}
decoder_status_cb_(kNeedMoreInput, frame);
@@ -281,6 +281,12 @@
// We must take a lock here since this function can be called from a
// separate thread.
ScopedLock lock(decode_target_mutex_);
+ while (frames_.size() > 1 && frames_.front()->HasOneRef()) {
+ frames_.pop();
+ }
+ if (!frames_.empty()) {
+ UpdateDecodeTarget_Locked(frames_.front());
+ }
if (SbDecodeTargetIsValid(decode_target_)) {
// Make a disposable copy, since the state is internally reused by this
// class (to avoid recreating GL objects).
diff --git a/src/starboard/shared/libvpx/vpx_video_decoder.h b/src/starboard/shared/libvpx/vpx_video_decoder.h
index 12eb6f3..5d9292f 100644
--- a/src/starboard/shared/libvpx/vpx_video_decoder.h
+++ b/src/starboard/shared/libvpx/vpx_video_decoder.h
@@ -15,6 +15,7 @@
#ifndef STARBOARD_SHARED_LIBVPX_VPX_VIDEO_DECODER_H_
#define STARBOARD_SHARED_LIBVPX_VPX_VIDEO_DECODER_H_
+#include <queue>
#include <string>
#include "starboard/common/ref_counted.h"
@@ -92,7 +93,7 @@
SbDecodeTarget GetCurrentDecodeTarget() override;
- bool UpdateDecodeTarget(const scoped_refptr<CpuVideoFrame>& frame);
+ void UpdateDecodeTarget_Locked(const scoped_refptr<CpuVideoFrame>& frame);
// The following callbacks will be initialized in Initialize() and won't be
// changed during the life time of this class.
@@ -126,6 +127,8 @@
// copy of |decode_target_|), we need to safe-guard access to |decode_target_|
// and we do so through this mutex.
Mutex decode_target_mutex_;
+
+ std::queue<scoped_refptr<CpuVideoFrame>> frames_;
};
} // namespace vpx
diff --git a/src/starboard/shared/linux/system_get_used_cpu_memory.cc b/src/starboard/shared/linux/system_get_used_cpu_memory.cc
index f7dca8f..0e9f2a5 100644
--- a/src/starboard/shared/linux/system_get_used_cpu_memory.cc
+++ b/src/starboard/shared/linux/system_get_used_cpu_memory.cc
@@ -26,68 +26,54 @@
#include "starboard/string.h"
// We find the current amount of used memory on Linux by opening
-// '/proc/self/status' and scan the file for its "VmRSS" entry. Essentially,
-// we need to parse a buffer that has the following format:
+// '/proc/self/status' and scan the file for its "VmRSS" and "VmSwap" entries.
+// Essentially, we need to parse a buffer that has the following format:
//
// xxxxxx: 45327 kB
// yyyyyy: 23 kB
// VmRSS: 87432 kB
// zzzzzz: 3213 kB
+// VmSwap: 15 kB
// ...
//
-// And here, we would want to return the value 87432 * 1024.
+// And here, we would want to return the value 87432 * 1024 + 15 * 1024 (i.e.
+// (VmRSS + VmSwap) * 1024).
// See http://man7.org/linux/man-pages/man5/proc.5.html for more details.
-// Searches for the value of VmRSS and returns it. Will modify |buffer| in
-// order to do so quickly and easily.
-int64_t SearchForVmRSSValue(char* buffer, size_t length) {
- // Search for the string ""VmRSS:".
- const char kSearchString[] = "\nVmRSS:";
- enum State {
- // We are currently searching for kSearchString
- kSearchingForSearchString,
- // We found the search string and are advancing through spaces/tabs until
- // we see a number.
- kAdvancingSpacesToNumber,
- // We found the number and are now searching for the end of it.
- kFindingEndOfNumber,
- };
- State state = kSearchingForSearchString;
- const char* number_start = NULL;
- for (size_t i = 0; i < length - sizeof(kSearchString); ++i) {
- if (state == kSearchingForSearchString) {
- if (SbStringCompare(&buffer[i], kSearchString,
- sizeof(kSearchString) - 1) == 0) {
- // Advance until we find a number.
- state = kAdvancingSpacesToNumber;
- i += sizeof(kSearchString) - 2;
- }
- } else if (state == kAdvancingSpacesToNumber) {
- if (buffer[i] >= '0' && buffer[i] <= '9') {
- // We found the start of the number, record where that is and then
- // continue searching for the end of the number.
- number_start = &buffer[i];
- state = kFindingEndOfNumber;
- }
- } else {
- SB_DCHECK(state == kFindingEndOfNumber);
- if (buffer[i] < '0' || buffer[i] > '9') {
- // Drop a null at the end of the number so that we can call atoi() on
- // it and return.
- buffer[i] = '\0';
- return SbStringAToI(number_start);
- }
- }
+// Searches for a specific value we're interested in and return it. Will
+// modify |buffer| in order to do so quickly and easily. Returns the memory
+// value in bytes (not kilobytes as it is presented in /proc/self/status).
+int64_t SearchForMemoryValue(
+ const char* search_key, const char* buffer) {
+ const char* found = SbStringFindString(buffer, search_key);
+ if (!found) {
+ SB_LOG(ERROR) << "Could not find '" << search_key << "' in "
+ << "/proc/self/status.";
+ return 0;
}
- SB_LOG(ERROR) << "Could not find 'VmRSS:' in /proc/self/status.";
- return 0;
+ while (*found != '\0' && (*found < '0' || *found > '9')) {
+ ++found;
+ }
+
+ if (*found == '\0') {
+ SB_LOG(ERROR) << "Unexpected end of string when searching for '"
+ << search_key << "' in /proc/self/status.";
+ return 0;
+ }
+
+ // Convert the number string into an integer.
+ int64_t memory_value_in_kilobytes = 0;
+ while (*found >= '0' && *found <= '9') {
+ memory_value_in_kilobytes = memory_value_in_kilobytes * 10 + (*found - '0');
+ ++found;
+ }
+
+ return memory_value_in_kilobytes * 1024;
}
int64_t SbSystemGetUsedCPUMemory() {
// Read our process' current physical memory usage from /proc/self/status.
- // This requires a bit of parsing through the output to find the value for
- // the "VmRSS" field which indicates used physical memory.
starboard::ScopedFile status_file("/proc/self/status",
kSbFileOpenOnly | kSbFileRead);
if (!status_file.IsValid()) {
@@ -100,19 +86,15 @@
// Read the entire file into memory.
const int kBufferSize = 2048;
char buffer[kBufferSize];
- int remaining = kBufferSize;
- char* output_pointer = buffer;
- do {
- int result = status_file.Read(output_pointer, remaining);
- if (result <= 0)
- break;
+ int bytes_read = status_file.ReadAll(buffer, kBufferSize);
- remaining -= result;
- output_pointer += result;
- } while (remaining);
+ // Ensure that this is a null-terminated string.
+ if (bytes_read == kBufferSize) {
+ bytes_read = kBufferSize - 1;
+ }
+ buffer[bytes_read] = '\0';
// Return the result, multiplied by 1024 because it is given in kilobytes.
- return SearchForVmRSSValue(buffer,
- static_cast<size_t>(output_pointer - buffer)) *
- 1024;
+ return SearchForMemoryValue("VmRSS", buffer) +
+ SearchForMemoryValue("VmSwap", buffer);
}
diff --git a/src/starboard/shared/opus/opus_audio_decoder.cc b/src/starboard/shared/opus/opus_audio_decoder.cc
new file mode 100644
index 0000000..dda6c11
--- /dev/null
+++ b/src/starboard/shared/opus/opus_audio_decoder.cc
@@ -0,0 +1,179 @@
+// Copyright 2018 The Cobalt Authors. 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/opus/opus_audio_decoder.h"
+
+#include "starboard/log.h"
+#include "starboard/memory.h"
+#include "starboard/shared/starboard/media/media_util.h"
+#include "starboard/string.h"
+
+namespace starboard {
+namespace shared {
+namespace opus {
+
+namespace {
+const int kMaxOpusFramesPerAU = 9600;
+} // namespace
+
+OpusAudioDecoder::OpusAudioDecoder(const SbMediaAudioHeader& audio_header)
+ : audio_header_(audio_header) {
+#if SB_HAS_QUIRK(SUPPORT_INT16_AUDIO_SAMPLES)
+ working_buffer_.resize(kMaxOpusFramesPerAU *
+ audio_header_.number_of_channels * sizeof(opus_int16));
+#else // SB_HAS_QUIRK(SUPPORT_INT16_AUDIO_SAMPLES)
+ working_buffer_.resize(kMaxOpusFramesPerAU *
+ audio_header_.number_of_channels * sizeof(float));
+#endif // SB_HAS_QUIRK(SUPPORT_INT16_AUDIO_SAMPLES)
+
+ int error;
+ decoder_ = opus_decoder_create(audio_header_.samples_per_second,
+ audio_header_.number_of_channels, &error);
+ if (error != OPUS_OK) {
+ SB_LOG(ERROR) << "Failed to create decoder with error: "
+ << opus_strerror(error);
+ decoder_ = NULL;
+ return;
+ }
+ SB_DCHECK(decoder_ != NULL);
+}
+
+OpusAudioDecoder::~OpusAudioDecoder() {
+ if (decoder_) {
+ opus_decoder_destroy(decoder_);
+ }
+}
+
+void OpusAudioDecoder::Initialize(const OutputCB& output_cb,
+ const ErrorCB& error_cb) {
+ SB_DCHECK(BelongsToCurrentThread());
+ SB_DCHECK(output_cb);
+ SB_DCHECK(!output_cb_);
+ SB_DCHECK(error_cb);
+ SB_DCHECK(!error_cb_);
+
+ output_cb_ = output_cb;
+ error_cb_ = error_cb;
+}
+
+void OpusAudioDecoder::Decode(const scoped_refptr<InputBuffer>& input_buffer,
+ const ConsumedCB& consumed_cb) {
+ SB_DCHECK(BelongsToCurrentThread());
+ SB_DCHECK(input_buffer);
+ SB_DCHECK(output_cb_);
+
+ Schedule(consumed_cb);
+
+ if (stream_ended_) {
+ SB_LOG(ERROR) << "Decode() is called after WriteEndOfStream() is called.";
+ return;
+ }
+
+#if SB_HAS_QUIRK(SUPPORT_INT16_AUDIO_SAMPLES)
+ const char kDecodeFunctionName[] = "opus_decode";
+ int decoded_frames = opus_decode(
+ decoder_, static_cast<const unsigned char*>(input_buffer->data()),
+ input_buffer->size(),
+ reinterpret_cast<opus_int16*>(working_buffer_.data()),
+ kMaxOpusFramesPerAU, 0);
+#else // SB_HAS_QUIRK(SUPPORT_INT16_AUDIO_SAMPLES)
+ const char kDecodeFunctionName[] = "opus_decode_float";
+ int decoded_frames = opus_decode_float(
+ decoder_, static_cast<const unsigned char*>(input_buffer->data()),
+ input_buffer->size(), reinterpret_cast<float*>(working_buffer_.data()),
+ kMaxOpusFramesPerAU, 0);
+#endif // SB_HAS_QUIRK(SUPPORT_INT16_AUDIO_SAMPLES)
+ if (decoded_frames <= 0) {
+ // TODO: Consider fill it with silence.
+ SB_LOG(ERROR) << kDecodeFunctionName
+ << "() failed with error code: " << decoded_frames;
+ error_cb_(kSbPlayerErrorDecode,
+ FormatString("%s() failed with error code: %d",
+ kDecodeFunctionName, decoded_frames));
+ return;
+ }
+
+ scoped_refptr<DecodedAudio> decoded_audio = new DecodedAudio(
+ audio_header_.number_of_channels, GetSampleType(), GetStorageType(),
+ input_buffer->timestamp(),
+ audio_header_.number_of_channels * decoded_frames *
+ starboard::media::GetBytesPerSample(GetSampleType()));
+ SbMemoryCopy(decoded_audio->buffer(), working_buffer_.data(),
+ decoded_audio->size());
+ decoded_audios_.push(decoded_audio);
+ Schedule(output_cb_);
+}
+
+void OpusAudioDecoder::WriteEndOfStream() {
+ SB_DCHECK(BelongsToCurrentThread());
+ SB_DCHECK(output_cb_);
+
+ // Opus has no dependent frames so we needn't flush the decoder. Set the
+ // flag to ensure that Decode() is not called when the stream is ended.
+ stream_ended_ = true;
+ // Put EOS into the queue.
+ decoded_audios_.push(new DecodedAudio);
+
+ Schedule(output_cb_);
+}
+
+scoped_refptr<OpusAudioDecoder::DecodedAudio> OpusAudioDecoder::Read() {
+ SB_DCHECK(BelongsToCurrentThread());
+ SB_DCHECK(output_cb_);
+ SB_DCHECK(!decoded_audios_.empty());
+
+ scoped_refptr<DecodedAudio> result;
+ if (!decoded_audios_.empty()) {
+ result = decoded_audios_.front();
+ decoded_audios_.pop();
+ }
+ return result;
+}
+
+void OpusAudioDecoder::Reset() {
+ SB_DCHECK(BelongsToCurrentThread());
+
+ stream_ended_ = false;
+ while (!decoded_audios_.empty()) {
+ decoded_audios_.pop();
+ }
+
+ CancelPendingJobs();
+}
+
+bool OpusAudioDecoder::is_valid() const {
+ return decoder_ != NULL;
+}
+
+SbMediaAudioSampleType OpusAudioDecoder::GetSampleType() const {
+ SB_DCHECK(BelongsToCurrentThread());
+#if SB_HAS_QUIRK(SUPPORT_INT16_AUDIO_SAMPLES)
+ return kSbMediaAudioSampleTypeInt16;
+#else // SB_HAS_QUIRK(SUPPORT_INT16_AUDIO_SAMPLES)
+ return kSbMediaAudioSampleTypeFloat32;
+#endif // SB_HAS_QUIRK(SUPPORT_INT16_AUDIO_SAMPLES)
+}
+
+SbMediaAudioFrameStorageType OpusAudioDecoder::GetStorageType() const {
+ SB_DCHECK(BelongsToCurrentThread());
+ return kSbMediaAudioFrameStorageTypeInterleaved;
+}
+
+int OpusAudioDecoder::GetSamplesPerSecond() const {
+ return audio_header_.samples_per_second;
+}
+
+} // namespace opus
+} // namespace shared
+} // namespace starboard
diff --git a/src/starboard/shared/opus/opus_audio_decoder.h b/src/starboard/shared/opus/opus_audio_decoder.h
new file mode 100644
index 0000000..e20db96
--- /dev/null
+++ b/src/starboard/shared/opus/opus_audio_decoder.h
@@ -0,0 +1,68 @@
+// Copyright 2018 The Cobalt Authors. 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_OPUS_OPUS_AUDIO_DECODER_H_
+#define STARBOARD_SHARED_OPUS_OPUS_AUDIO_DECODER_H_
+
+#include <queue>
+#include <vector>
+
+#include "starboard/common/ref_counted.h"
+#include "starboard/media.h"
+#include "starboard/shared/internal_only.h"
+#include "starboard/shared/starboard/player/decoded_audio_internal.h"
+#include "starboard/shared/starboard/player/filter/audio_decoder_internal.h"
+#include "starboard/shared/starboard/player/job_queue.h"
+#include "third_party/opus/include/opus.h"
+
+namespace starboard {
+namespace shared {
+namespace opus {
+
+class OpusAudioDecoder
+ : public ::starboard::shared::starboard::player::filter::AudioDecoder,
+ private starboard::player::JobQueue::JobOwner {
+ public:
+ explicit OpusAudioDecoder(const SbMediaAudioHeader& audio_header);
+ ~OpusAudioDecoder() override;
+
+ bool is_valid() const;
+
+ // AudioDecoder functions
+ void Initialize(const OutputCB& output_cb, const ErrorCB& error_cb) override;
+ void Decode(const scoped_refptr<InputBuffer>& input_buffer,
+ const ConsumedCB& consumed_cb) override;
+ void WriteEndOfStream() override;
+ scoped_refptr<DecodedAudio> Read() override;
+ void Reset() override;
+ SbMediaAudioSampleType GetSampleType() const override;
+ SbMediaAudioFrameStorageType GetStorageType() const override;
+ int GetSamplesPerSecond() const override;
+
+ private:
+ OutputCB output_cb_;
+ ErrorCB error_cb_;
+
+ OpusDecoder* decoder_ = NULL;
+ bool stream_ended_ = false;
+ std::queue<scoped_refptr<DecodedAudio> > decoded_audios_;
+ SbMediaAudioHeader audio_header_;
+ std::vector<uint8_t> working_buffer_;
+};
+
+} // namespace opus
+} // namespace shared
+} // namespace starboard
+
+#endif // STARBOARD_SHARED_OPUS_OPUS_AUDIO_DECODER_H_
diff --git a/src/starboard/shared/starboard/media/media_can_play_mime_and_key_system.cc b/src/starboard/shared/starboard/media/media_can_play_mime_and_key_system.cc
index e6dbcfa..c478ea2 100644
--- a/src/starboard/shared/starboard/media/media_can_play_mime_and_key_system.cc
+++ b/src/starboard/shared/starboard/media/media_can_play_mime_and_key_system.cc
@@ -34,74 +34,148 @@
const int64_t kDefaultBitRate = 0;
const int64_t kDefaultAudioChannels = 2;
-// A progressive video contains both audio and video data. The JS app uses
-// canPlayType() like "canPlayType(video/mp4; codecs="avc1.42001E, mp4a.40.2",)"
-// to query for support on both the audio and video codecs, which is being
-// forwarded to here.
-//
-// Note that canPlayType() doesn't support extra parameters like width, height
-// and channels.
-SbMediaSupportType CanPlayProgressiveVideo(const MimeType& mime_type,
- bool decode_to_texture_required) {
+bool IsSupportedAudioCodec(const MimeType& mime_type,
+ const std::string& codec,
+ const char* key_system) {
+ SbMediaAudioCodec audio_codec = GetAudioCodecFromString(codec.c_str());
+ if (audio_codec == kSbMediaAudioCodecNone) {
+ return false;
+ }
+ if (SbStringGetLength(key_system) != 0) {
+ if (!SbMediaIsSupported(kSbMediaVideoCodecNone, audio_codec, key_system)) {
+ return false;
+ }
+ }
+
+ int channels = mime_type.GetParamIntValue("channels", kDefaultAudioChannels);
+ if (!IsAudioOutputSupported(kSbMediaAudioCodingTypePcm, channels)) {
+ return false;
+ }
+
+ int bitrate = mime_type.GetParamIntValue("bitrate", kDefaultBitRate);
+
+ if (!SbMediaIsAudioSupported(audio_codec, bitrate)) {
+ return false;
+ }
+
+ switch (audio_codec) {
+ case kSbMediaAudioCodecNone:
+ SB_NOTREACHED();
+ return false;
+ case kSbMediaAudioCodecAac:
+ return mime_type.subtype() == "mp4";
+#if SB_HAS(AC3_AUDIO)
+ case kSbMediaAudioCodecAc3:
+ return mime_type.subtype() == "mp4";
+#endif // SB_HAS(AC3_AUDIO)
+ case kSbMediaAudioCodecOpus:
+ case kSbMediaAudioCodecVorbis:
+ return mime_type.subtype() == "webm";
+ }
+
+ SB_NOTREACHED();
+ return false;
+}
+
+bool IsSupportedVideoCodec(const MimeType& mime_type,
+ const std::string& codec,
+ const char* key_system,
+ bool decode_to_texture_required) {
#if SB_API_VERSION < 10
SB_UNREFERENCED_PARAMETER(decode_to_texture_required);
#endif // SB_API_VERSION < 10
- const std::vector<std::string>& codecs = mime_type.GetCodecs();
+ SbMediaVideoCodec video_codec = GetVideoCodecFromString(codec.c_str());
+ if (video_codec == kSbMediaVideoCodecNone) {
+ return false;
+ }
- SB_DCHECK(codecs.size() == 2) << codecs.size();
-
- bool has_audio_codec = false;
- bool has_video_codec = false;
- for (size_t i = 0; i < codecs.size(); ++i) {
- SbMediaAudioCodec audio_codec = GetAudioCodecFromString(codecs[i].c_str());
- if (audio_codec != kSbMediaAudioCodecNone) {
- if (!SbMediaIsAudioSupported(audio_codec, kDefaultBitRate)) {
- return kSbMediaSupportTypeNotSupported;
- }
- has_audio_codec = true;
- continue;
+ if (SbStringGetLength(key_system) != 0) {
+ if (!SbMediaIsSupported(video_codec, kSbMediaAudioCodecNone, key_system)) {
+ return false;
}
- SbMediaVideoCodec video_codec = GetVideoCodecFromString(codecs[i].c_str());
- if (video_codec == kSbMediaVideoCodecNone) {
- return kSbMediaSupportTypeNotSupported;
+ }
+
+ std::string eotf = mime_type.GetParamStringValue("eotf", "");
+ SbMediaTransferId transfer_id = kSbMediaTransferIdUnspecified;
+ if (!eotf.empty()) {
+ transfer_id = GetTransferIdFromString(eotf);
+ // If the eotf is not known, reject immediately - without checking with
+ // the platform.
+ if (transfer_id == kSbMediaTransferIdUnknown) {
+ return false;
}
-
- has_video_codec = true;
-
- int width = 0;
- int height = 0;
- int fps = 0;
-
- if (video_codec == kSbMediaVideoCodecH264) {
- if (!ParseH264Info(codecs[i].c_str(), &width, &height, &fps)) {
- return kSbMediaSupportTypeNotSupported;
- }
+#if !SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
+ if (!SbMediaIsTransferCharacteristicsSupported(transfer_id)) {
+ return false;
}
- if (!SbMediaIsVideoSupported(video_codec, width, height, kDefaultBitRate,
- fps
+#endif // !SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
+ }
+
+ std::string cryptoblockformat =
+ mime_type.GetParamStringValue("cryptoblockformat", "");
+ if (!cryptoblockformat.empty()) {
+ if (mime_type.subtype() != "webm" || cryptoblockformat != "subsample") {
+ return false;
+ }
+ }
+
+ int width = 0;
+ int height = 0;
+ int fps = 0;
+
+ if (video_codec == kSbMediaVideoCodecH264) {
+ if (!ParseH264Info(codec.c_str(), &width, &height, &fps)) {
+ return false;
+ }
+ }
+
+ width = mime_type.GetParamIntValue("width", width);
+ height = mime_type.GetParamIntValue("height", height);
+ fps = mime_type.GetParamIntValue("framerate", fps);
+
+ int bitrate = mime_type.GetParamIntValue("bitrate", kDefaultBitRate);
+
+ if (!SbMediaIsVideoSupported(video_codec, width, height, bitrate, fps
#if SB_API_VERSION >= 10
- ,
- decode_to_texture_required
+ ,
+ decode_to_texture_required
#endif // SB_API_VERSION >= 10
#if SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
- ,
- kSbMediaTransferIdUnspecified
+ ,
+ transfer_id
#endif // SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
- )) {
- return kSbMediaSupportTypeNotSupported;
- }
+ )) {
+ return false;
}
- if (has_audio_codec && has_video_codec) {
- return kSbMediaSupportTypeProbably;
+ switch (video_codec) {
+ case kSbMediaVideoCodecNone:
+ SB_NOTREACHED();
+ return false;
+ case kSbMediaVideoCodecH264:
+ case kSbMediaVideoCodecH265:
+ return mime_type.subtype() == "mp4";
+ case kSbMediaVideoCodecMpeg2:
+ case kSbMediaVideoCodecTheora:
+ return false; // No associated container in YT.
+ case kSbMediaVideoCodecVc1:
+ case kSbMediaVideoCodecVp10:
+ return mime_type.subtype() == "mp4";
+ case kSbMediaVideoCodecVp8:
+ case kSbMediaVideoCodecVp9:
+ return mime_type.subtype() == "webm";
}
- return kSbMediaSupportTypeNotSupported;
+ SB_NOTREACHED();
+ return false;
}
-// Calls to isTypeSupported() are redirected to this function. Following are
-// some example inputs:
+// Calls to canPlayType() and isTypeSupported() are redirected to this function.
+// Following are some example inputs:
+// canPlayType(video/mp4)
+// canPlayType(video/mp4; codecs="avc1.42001E, mp4a.40.2")
+// canPlayType(video/webm)
// isTypeSupported(video/webm; codecs="vp9")
// isTypeSupported(video/mp4; codecs="avc1.4d401e"; width=640)
// isTypeSupported(video/mp4; codecs="avc1.4d401e"; width=99999)
@@ -125,6 +199,10 @@
const char* key_system) {
SB_DCHECK(mime_type.is_valid());
+ if (mime_type.type() != "audio" && mime_type.type() != "video") {
+ return kSbMediaSupportTypeNotSupported;
+ }
+
const std::vector<std::string>& codecs = mime_type.GetCodecs();
// Pre-filter for |key_system|.
@@ -149,114 +227,48 @@
#endif // SB_API_VERSION >= 10
if (codecs.size() == 0) {
- // When there is no codecs listed, returns |kSbMediaSupportTypeMaybe| and
- // reject unsupported formats when query again with valid "codecs".
- return kSbMediaSupportTypeMaybe;
+ // This is a progressive query. We only support "video/mp4" in this case.
+ if (mime_type.type() == "video" && mime_type.subtype() == "mp4") {
+ return kSbMediaSupportTypeMaybe;
+ }
+ return kSbMediaSupportTypeNotSupported;
}
if (codecs.size() > 2) {
return kSbMediaSupportTypeNotSupported;
}
- if (codecs.size() == 2) {
- SB_DCHECK(SbStringGetLength(key_system) == 0);
- return CanPlayProgressiveVideo(mime_type, decode_to_texture_required);
- }
-
- SB_DCHECK(codecs.size() == 1);
-
- if (mime_type.type() == "audio") {
- SbMediaAudioCodec audio_codec = GetAudioCodecFromString(codecs[0].c_str());
- if (audio_codec == kSbMediaAudioCodecNone) {
- return kSbMediaSupportTypeNotSupported;
- }
-
- if (SbStringGetLength(key_system) != 0) {
- if (!SbMediaIsSupported(kSbMediaVideoCodecNone, audio_codec,
- key_system)) {
+ bool has_audio_codec = false;
+ bool has_video_codec = false;
+ for (const auto& codec : codecs) {
+ if (IsSupportedAudioCodec(mime_type, codec, key_system)) {
+ if (has_audio_codec) {
+ // We don't support two audio codecs in one stream.
return kSbMediaSupportTypeNotSupported;
}
+ has_audio_codec = true;
+ continue;
}
-
- int channels =
- mime_type.GetParamIntValue("channels", kDefaultAudioChannels);
- if (!IsAudioOutputSupported(kSbMediaAudioCodingTypePcm, channels)) {
- return kSbMediaSupportTypeNotSupported;
+ if (IsSupportedVideoCodec(mime_type, codec, key_system,
+ decode_to_texture_required)) {
+ if (mime_type.type() != "video") {
+ // Video can only be contained in "video/*", while audio can be
+ // contained in both "audio/*" and "video/*".
+ return kSbMediaSupportTypeNotSupported;
+ }
+ if (has_video_codec) {
+ // We don't support two video codecs in one stream.
+ return kSbMediaSupportTypeNotSupported;
+ }
+ has_video_codec = true;
+ continue;
}
-
- int bitrate = mime_type.GetParamIntValue("bitrate", kDefaultBitRate);
-
- if (SbMediaIsAudioSupported(audio_codec, bitrate)) {
- return kSbMediaSupportTypeProbably;
- }
-
return kSbMediaSupportTypeNotSupported;
}
- if (mime_type.type() == "video") {
- SbMediaVideoCodec video_codec = GetVideoCodecFromString(codecs[0].c_str());
- if (video_codec == kSbMediaVideoCodecNone) {
- return kSbMediaSupportTypeNotSupported;
- }
-
- if (SbStringGetLength(key_system) != 0) {
- if (!SbMediaIsSupported(video_codec, kSbMediaAudioCodecNone,
- key_system)) {
- return kSbMediaSupportTypeNotSupported;
- }
- }
-
- std::string eotf = mime_type.GetParamStringValue("eotf", "");
- SbMediaTransferId transfer_id = kSbMediaTransferIdUnspecified;
- if (!eotf.empty()) {
- transfer_id = GetTransferIdFromString(eotf);
- // If the eotf is not known, reject immediately - without checking with
- // the platform.
- if (transfer_id == kSbMediaTransferIdUnknown) {
- return kSbMediaSupportTypeNotSupported;
- }
- }
-
- std::string cryptoblockformat =
- mime_type.GetParamStringValue("cryptoblockformat", "");
- if (!cryptoblockformat.empty()) {
- if (mime_type.subtype() != "webm" || cryptoblockformat != "subsample") {
- return kSbMediaSupportTypeNotSupported;
- }
- }
-
- int width = 0;
- int height = 0;
- int fps = 0;
-
- if (video_codec == kSbMediaVideoCodecH264) {
- if (!ParseH264Info(codecs[0].c_str(), &width, &height, &fps)) {
- return kSbMediaSupportTypeNotSupported;
- }
- }
-
- width = mime_type.GetParamIntValue("width", width);
- height = mime_type.GetParamIntValue("height", height);
- fps = mime_type.GetParamIntValue("framerate", fps);
-
- int bitrate = mime_type.GetParamIntValue("bitrate", kDefaultBitRate);
-
- if (SbMediaIsVideoSupported(video_codec, width, height, bitrate, fps
-#if SB_API_VERSION >= 10
- ,
- decode_to_texture_required
-#endif // SB_API_VERSION >= 10
-#if SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
- ,
- transfer_id
-#endif // SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
- )) {
- return kSbMediaSupportTypeProbably;
- }
-
- return kSbMediaSupportTypeNotSupported;
+ if (has_audio_codec || has_video_codec) {
+ return kSbMediaSupportTypeProbably;
}
-
return kSbMediaSupportTypeNotSupported;
}
diff --git a/src/starboard/shared/starboard/net_log.cc b/src/starboard/shared/starboard/net_log.cc
index 1a27602..525cc07 100644
--- a/src/starboard/shared/starboard/net_log.cc
+++ b/src/starboard/shared/starboard/net_log.cc
@@ -62,44 +62,27 @@
namespace starboard {
namespace {
-using JoinFunction = std::function<void()>;
-using RunFunction = std::function<void(Semaphore*, atomic_bool*)>;
-using std::placeholders::_1;
-using std::placeholders::_2;
+using RunFunction = std::function<void(Semaphore*)>;
class FunctionThread : public Thread {
public:
static scoped_ptr<Thread> Create(
const std::string& thread_name,
- RunFunction run_function,
- JoinFunction on_join_called = JoinFunction()) {
- scoped_ptr<Thread> out(
- new FunctionThread(thread_name, run_function, on_join_called));
+ RunFunction run_function) {
+ scoped_ptr<Thread> out(new FunctionThread(thread_name, run_function));
return out.Pass();
}
- FunctionThread(const std::string& name,
- RunFunction run_function,
- JoinFunction join_function)
- : Thread(name),
- run_function_(run_function),
- join_function_(join_function) {
+ FunctionThread(const std::string& name, RunFunction run_function)
+ : Thread(name), run_function_(run_function) {
}
void Run() override {
- run_function_(join_sema(), joined_bool());
- }
-
- void Join() override {
- if (join_function_) {
- join_function_();
- }
- Thread::Join();
+ run_function_(join_sema());
}
private:
RunFunction run_function_;
- JoinFunction join_function_;
};
std::string ToString(SbSocketError error) {
@@ -289,9 +272,8 @@
SocketListener(Socket* listen_socket, Callback cb)
: listen_socket_(listen_socket),
callback_(cb) {
- RunFunction run_cb = std::bind(&SocketListener::Run, this, _1, _2);
- thread_ = FunctionThread::Create("NetLogSocketListener",
- run_cb);
+ auto run_cb = [this](Semaphore* sema) { this->Run(sema); };
+ thread_ = FunctionThread::Create("NetLogSocketListener", run_cb);
thread_->Start();
}
@@ -300,7 +282,7 @@
}
private:
- void Run(Semaphore* joined_sema, atomic_bool*) {
+ void Run(Semaphore* joined_sema) {
while (!joined_sema->TakeWait(100 * kSbTimeMillisecond)) {
scoped_ptr<Socket> client_connection(listen_socket_->Accept());
@@ -326,9 +308,8 @@
ListenForClient();
writer_thread_ = FunctionThread::Create(
- "NetLogSocketWriter",
- std::bind(&NetLogServer::WriterTask, this, _1, _2),
- std::bind(&NetLogServer::OnWriterTaskJoined, this));
+ "NetLogSocketWriter",
+ [this](Semaphore* sema) { this->WriterTask(sema); });
writer_thread_->Start();
}
@@ -366,6 +347,8 @@
void Close() {
socket_listener_.reset();
if (writer_thread_) {
+ is_joined_.store(true);
+ writer_thread_sema_.Put();
writer_thread_->Join();
writer_thread_.reset(nullptr);
Flush(); // One last flush to the socket.
@@ -389,11 +372,7 @@
}
private:
- void OnWriterTaskJoined() {
- writer_thread_sema_.Put();
- }
-
- void WriterTask(Semaphore* /*joined_sema*/, atomic_bool* is_joined) {
+ void WriterTask(Semaphore* /*joined_sema*/) {
while (true) {
writer_thread_sema_.Take();
@@ -402,7 +381,7 @@
break; // Connection dropped.
}
}
- if (is_joined->load()) {
+ if (is_joined_.load()) {
break;
}
}
@@ -415,6 +394,7 @@
scoped_ptr<SocketListener> socket_listener_;
scoped_ptr<Thread> writer_thread_;
Semaphore writer_thread_sema_;
+ atomic_bool is_joined_;
BufferedSocketWriter buffered_socket_writer_;
};
diff --git a/src/starboard/shared/starboard/player/filter/player_components.h b/src/starboard/shared/starboard/player/filter/player_components.h
index 976143c..a0401b7 100644
--- a/src/starboard/shared/starboard/player/filter/player_components.h
+++ b/src/starboard/shared/starboard/player/filter/player_components.h
@@ -88,7 +88,7 @@
scoped_refptr<VideoRendererSink> video_renderer_sink;
CreateVideoComponents(video_parameters, &video_decoder,
&video_render_algorithm, &video_renderer_sink);
- if (!video_decoder || !video_render_algorithm || !video_renderer_sink) {
+ if (!video_decoder || !video_render_algorithm) {
return scoped_ptr<VideoRenderer>();
}
return make_scoped_ptr(
diff --git a/src/starboard/shared/starboard/player/filter/testing/video_decoder_test.cc b/src/starboard/shared/starboard/player/filter/testing/video_decoder_test.cc
index 3f678f0..aa1cac2 100644
--- a/src/starboard/shared/starboard/player/filter/testing/video_decoder_test.cc
+++ b/src/starboard/shared/starboard/player/filter/testing/video_decoder_test.cc
@@ -122,8 +122,10 @@
&video_renderer_sink_);
ASSERT_TRUE(video_decoder_);
- video_renderer_sink_->SetRenderCB(
- std::bind(&VideoDecoderTest::Render, this, _1));
+ if (video_renderer_sink_) {
+ video_renderer_sink_->SetRenderCB(
+ std::bind(&VideoDecoderTest::Render, this, _1));
+ }
video_decoder_->Initialize(
std::bind(&VideoDecoderTest::OnDecoderStatusUpdate, this, _1, _2),
@@ -439,8 +441,10 @@
&video_renderer_sinks[i]);
ASSERT_TRUE(video_decoders[i]);
- video_renderer_sinks[i]->SetRenderCB(
- std::bind(&VideoDecoderTest::Render, this, _1));
+ if (video_renderer_sinks[i]) {
+ video_renderer_sinks[i]->SetRenderCB(
+ std::bind(&VideoDecoderTest::Render, this, _1));
+ }
video_decoders[i]->Initialize(
std::bind(&VideoDecoderTest::OnDecoderStatusUpdate, this, _1, _2),
diff --git a/src/starboard/shared/starboard/player/filter/video_render_algorithm.h b/src/starboard/shared/starboard/player/filter/video_render_algorithm.h
index 9bf14fb..0e21b5b 100644
--- a/src/starboard/shared/starboard/player/filter/video_render_algorithm.h
+++ b/src/starboard/shared/starboard/player/filter/video_render_algorithm.h
@@ -42,6 +42,10 @@
VideoRendererSink;
virtual ~VideoRenderAlgorithm() {}
+
+ // |draw_frame_cb| can be empty. When it is empty, this function simply runs
+ // the frame picking algorithm without calling |draw_frame_cb| to render the
+ // frame explicitly.
virtual void Render(MediaTimeProvider* media_time_provider,
std::list<scoped_refptr<VideoFrame>>* frames,
VideoRendererSink::DrawFrameCB draw_frame_cb) = 0;
diff --git a/src/starboard/shared/starboard/player/filter/video_render_algorithm_impl.cc b/src/starboard/shared/starboard/player/filter/video_render_algorithm_impl.cc
index b54a451..8342789 100644
--- a/src/starboard/shared/starboard/player/filter/video_render_algorithm_impl.cc
+++ b/src/starboard/shared/starboard/player/filter/video_render_algorithm_impl.cc
@@ -34,7 +34,6 @@
VideoRendererSink::DrawFrameCB draw_frame_cb) {
SB_DCHECK(media_time_provider);
SB_DCHECK(frames);
- SB_DCHECK(draw_frame_cb);
if (frames->empty() || frames->front()->is_end_of_stream()) {
return;
@@ -102,9 +101,11 @@
if (!frames->front()->is_end_of_stream()) {
last_frame_timestamp_ = frames->front()->timestamp();
- auto status = draw_frame_cb(frames->front(), 0);
- if (status == VideoRendererSink::kReleased) {
- frames->pop_front();
+ if (draw_frame_cb) {
+ auto status = draw_frame_cb(frames->front(), 0);
+ if (status == VideoRendererSink::kReleased) {
+ frames->pop_front();
+ }
}
}
}
diff --git a/src/starboard/shared/starboard/player/filter/video_renderer_internal.cc b/src/starboard/shared/starboard/player/filter/video_renderer_internal.cc
index 48ab311..161dd69 100644
--- a/src/starboard/shared/starboard/player/filter/video_renderer_internal.cc
+++ b/src/starboard/shared/starboard/player/filter/video_renderer_internal.cc
@@ -47,7 +47,6 @@
number_of_frames_(0) {
SB_DCHECK(decoder_ != NULL);
SB_DCHECK(algorithm_ != NULL);
- SB_DCHECK(sink_ != NULL);
SB_DCHECK(decoder_->GetMaxNumberOfCachedFrames() > 1);
SB_DLOG_IF(WARNING, decoder_->GetMaxNumberOfCachedFrames() < 4)
<< "VideoDecoder::GetMaxNumberOfCachedFrames() returns "
@@ -206,7 +205,9 @@
int y,
int width,
int height) {
- sink_->SetBounds(z_index, x, y, width, height);
+ if (sink_) {
+ sink_->SetBounds(z_index, x, y, width, height);
+ }
}
SbDecodeTarget VideoRenderer::GetCurrentDecodeTarget() {
@@ -215,6 +216,12 @@
// NULL inside the dtor.
SB_DCHECK(decoder_);
+ // TODO: Ensure that |sink_| is NULL when decode target is used across all
+ // platforms.
+ if (!sink_) {
+ Render(VideoRendererSink::DrawFrameCB());
+ }
+
return decoder_->GetCurrentDecodeTarget();
}
diff --git a/src/third_party/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/third_party/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index ce19a29..db531ee 100644
--- a/src/third_party/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/third_party/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -26,6 +26,21 @@
#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
#include "libANGLE/renderer/d3d/VertexDataManager.h"
+#if defined(ANGLE_STD_ASYNC_WORKERS) && defined(_MSC_VER)
+#if (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) && (_MSC_VER >= 1915)
+// Starting with MSVC++ 14.15 std::future::wait() will throw an exception
+// with the message "Illegal to wait on a task in a Windows Runtime STA"
+// whenever it is invoked from the UI thread. This define signals a
+// workaround to avoid this exception by invoking future::wait() on a
+// separate thread and then immediately doing a thread join.
+#define ANGLE_MSVC_STA_EXCEPTION_WORKAROUND
+#endif
+#endif
+
+#ifdef ANGLE_MSVC_STA_EXCEPTION_WORKAROUND
+#include <thread>
+#endif
+
using namespace angle;
namespace rx
@@ -1411,7 +1426,11 @@
workerPool->postWorkerTask(&pixelTask),
workerPool->postWorkerTask(&geometryTask)}};
+#ifdef ANGLE_MSVC_STA_EXCEPTION_WORKAROUND
+ std::thread([&]() { WaitableEvent::WaitMany(&waitEvents); }).join();
+#else
WaitableEvent::WaitMany(&waitEvents);
+#endif
infoLog << vertexTask.getInfoLog().str();
infoLog << pixelTask.getInfoLog().str();
diff --git a/src/third_party/icu/source/common/ucase.cpp b/src/third_party/icu/source/common/ucase.cpp
index 0f5f705..0930574 100644
--- a/src/third_party/icu/source/common/ucase.cpp
+++ b/src/third_party/icu/source/common/ucase.cpp
@@ -620,6 +620,18 @@
result=UCASE_LOC_LITHUANIAN;
}
}
+ } else if(is_e(c)) {
+ /* el or ell? */
+ c=*locale++;
+ if(is_l(c)) {
+ c=*locale++;
+ if(is_l(c)) {
+ c=*locale;
+ }
+ if(is_sep(c)) {
+ result=UCASE_LOC_GREEK;
+ }
+ }
} else if(is_n(c)) {
/* nl or nld? */
c=*locale++;
diff --git a/src/third_party/icu/source/common/ucase.h b/src/third_party/icu/source/common/ucase.h
index 8f24769..12771a3 100644
--- a/src/third_party/icu/source/common/ucase.h
+++ b/src/third_party/icu/source/common/ucase.h
@@ -62,6 +62,7 @@
UCASE_LOC_ROOT,
UCASE_LOC_TURKISH,
UCASE_LOC_LITHUANIAN,
+ UCASE_LOC_GREEK,
UCASE_LOC_DUTCH
};
@@ -156,7 +157,7 @@
U_CAPI int32_t U_EXPORT2
ucase_getType(const UCaseProps *csp, UChar32 c);
-/** @return same as ucase_getType(), or <0 if c is case-ignorable */
+/** @return same as ucase_getType() and set bit 2 if c is case-ignorable */
U_CAPI int32_t U_EXPORT2
ucase_getTypeOrIgnorable(const UCaseProps *csp, UChar32 c);
diff --git a/src/third_party/icu/source/common/ucasemap.cpp b/src/third_party/icu/source/common/ucasemap.cpp
index 8d5b260..48fd558 100644
--- a/src/third_party/icu/source/common/ucasemap.cpp
+++ b/src/third_party/icu/source/common/ucasemap.cpp
@@ -175,6 +175,15 @@
return destIndex;
}
+static inline int32_t
+appendUChar(uint8_t *dest, int32_t destIndex, int32_t destCapacity, UChar c) {
+ int32_t limit=destIndex+U8_LENGTH(c);
+ if(limit<destCapacity) {
+ U8_APPEND_UNSAFE(dest, destIndex, c);
+ }
+ return limit;
+}
+
static UChar32 U_CALLCONV
utf8_caseContextIterator(void *context, int8_t dir) {
UCaseContext *csc=(UCaseContext *)context;
@@ -387,6 +396,141 @@
#endif
+U_NAMESPACE_BEGIN
+namespace GreekUpper {
+
+UBool isFollowedByCasedLetter(const UCaseProps *csp, const uint8_t *s, int32_t i, int32_t length) {
+ while (i < length) {
+ UChar32 c;
+ U8_NEXT(s, i, length, c);
+ int32_t type = ucase_getTypeOrIgnorable(csp, c);
+ if ((type & UCASE_IGNORABLE) != 0) {
+ // Case-ignorable, continue with the loop.
+ } else if (type != UCASE_NONE) {
+ return TRUE; // Followed by cased letter.
+ } else {
+ return FALSE; // Uncased and not case-ignorable.
+ }
+ }
+ return FALSE; // Not followed by cased letter.
+}
+
+// Keep this consistent with the UTF-16 version in ustrcase.cpp and the Java version in CaseMap.java.
+int32_t toUpper(const UCaseMap *csm,
+ uint8_t *dest, int32_t destCapacity,
+ const uint8_t *src, int32_t srcLength,
+ UErrorCode *pErrorCode) {
+ int32_t locCache = UCASE_LOC_GREEK;
+ int32_t destIndex=0;
+ uint32_t state = 0;
+ for (int32_t i = 0; i < srcLength;) {
+ int32_t nextIndex = i;
+ UChar32 c;
+ U8_NEXT(src, nextIndex, srcLength, c);
+ uint32_t nextState = 0;
+ int32_t type = ucase_getTypeOrIgnorable(csm->csp, c);
+ if ((type & UCASE_IGNORABLE) != 0) {
+ // c is case-ignorable
+ nextState |= (state & AFTER_CASED);
+ } else if (type != UCASE_NONE) {
+ // c is cased
+ nextState |= AFTER_CASED;
+ }
+ uint32_t data = getLetterData(c);
+ if (data > 0) {
+ uint32_t upper = data & UPPER_MASK;
+ // Add a dialytika to this iota or ypsilon vowel
+ // if we removed a tonos from the previous vowel,
+ // and that previous vowel did not also have (or gain) a dialytika.
+ // Adding one only to the final vowel in a longer sequence
+ // (which does not occur in normal writing) would require lookahead.
+ // Set the same flag as for preserving an existing dialytika.
+ if ((data & HAS_VOWEL) != 0 && (state & AFTER_VOWEL_WITH_ACCENT) != 0 &&
+ (upper == 0x399 || upper == 0x3A5)) {
+ data |= HAS_DIALYTIKA;
+ }
+ int32_t numYpogegrammeni = 0; // Map each one to a trailing, spacing, capital iota.
+ if ((data & HAS_YPOGEGRAMMENI) != 0) {
+ numYpogegrammeni = 1;
+ }
+ // Skip combining diacritics after this Greek letter.
+ int32_t nextNextIndex = nextIndex;
+ while (nextIndex < srcLength) {
+ UChar32 c2;
+ U8_NEXT(src, nextNextIndex, srcLength, c2);
+ uint32_t diacriticData = getDiacriticData(c2);
+ if (diacriticData != 0) {
+ data |= diacriticData;
+ if ((diacriticData & HAS_YPOGEGRAMMENI) != 0) {
+ ++numYpogegrammeni;
+ }
+ nextIndex = nextNextIndex;
+ } else {
+ break; // not a Greek diacritic
+ }
+ }
+ if ((data & HAS_VOWEL_AND_ACCENT_AND_DIALYTIKA) == HAS_VOWEL_AND_ACCENT) {
+ nextState |= AFTER_VOWEL_WITH_ACCENT;
+ }
+ // Map according to Greek rules.
+ UBool addTonos = FALSE;
+ if (upper == 0x397 &&
+ (data & HAS_ACCENT) != 0 &&
+ numYpogegrammeni == 0 &&
+ (state & AFTER_CASED) == 0 &&
+ !isFollowedByCasedLetter(csm->csp, src, nextIndex, srcLength)) {
+ // Keep disjunctive "or" with (only) a tonos.
+ // We use the same "word boundary" conditions as for the Final_Sigma test.
+ if (i == nextIndex) {
+ upper = 0x389; // Preserve the precomposed form.
+ } else {
+ addTonos = TRUE;
+ }
+ } else if ((data & HAS_DIALYTIKA) != 0) {
+ // Preserve a vowel with dialytika in precomposed form if it exists.
+ if (upper == 0x399) {
+ upper = 0x3AA;
+ data &= ~HAS_EITHER_DIALYTIKA;
+ } else if (upper == 0x3A5) {
+ upper = 0x3AB;
+ data &= ~HAS_EITHER_DIALYTIKA;
+ }
+ }
+ destIndex=appendUChar(dest, destIndex, destCapacity, (UChar)upper);
+ if ((data & HAS_EITHER_DIALYTIKA) != 0) {
+ destIndex=appendUChar(dest, destIndex, destCapacity, 0x308); // restore or add a dialytika
+ }
+ if (addTonos) {
+ destIndex=appendUChar(dest, destIndex, destCapacity, 0x301);
+ }
+ while (numYpogegrammeni > 0) {
+ destIndex=appendUChar(dest, destIndex, destCapacity, 0x399);
+ --numYpogegrammeni;
+ }
+ } else {
+ const UChar *s;
+ UChar32 c2 = 0;
+ c=ucase_toFullUpper(csm->csp, c, NULL, NULL, &s, csm->locale, &locCache);
+ if((destIndex<destCapacity) && (c<0 ? (c2=~c)<=0x7f : UCASE_MAX_STRING_LENGTH<c && (c2=c)<=0x7f)) {
+ /* fast path version of appendResult() for ASCII results */
+ dest[destIndex++]=(uint8_t)c2;
+ } else {
+ destIndex=appendResult(dest, destIndex, destCapacity, c, s);
+ }
+ }
+ i = nextIndex;
+ state = nextState;
+ }
+
+ if(destIndex>destCapacity) {
+ *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+ }
+ return destIndex;
+}
+
+} // namespace GreekUpper
+U_NAMESPACE_END
+
static int32_t U_CALLCONV
ucasemap_internalUTF8ToLower(const UCaseMap *csm,
uint8_t *dest, int32_t destCapacity,
@@ -407,6 +551,10 @@
uint8_t *dest, int32_t destCapacity,
const uint8_t *src, int32_t srcLength,
UErrorCode *pErrorCode) {
+ int32_t locCache = csm->locCache;
+ if (ucase_getCaseLocale(csm->locale, &locCache) == UCASE_LOC_GREEK) {
+ return GreekUpper::toUpper(csm, dest, destCapacity, src, srcLength, pErrorCode);
+ }
UCaseContext csc=UCASECONTEXT_INITIALIZER;
csc.p=(void *)src;
csc.limit=srcLength;
diff --git a/src/third_party/icu/source/common/unicode/utf8.h b/src/third_party/icu/source/common/unicode/utf8.h
index 1198a17..808d9f2 100644
--- a/src/third_party/icu/source/common/unicode/utf8.h
+++ b/src/third_party/icu/source/common/unicode/utf8.h
@@ -431,21 +431,22 @@
* @stable ICU 2.4
*/
#define U8_APPEND_UNSAFE(s, i, c) { \
- if((uint32_t)(c)<=0x7f) { \
- (s)[(i)++]=(uint8_t)(c); \
+ uint32_t __uc=(c); \
+ if(__uc<=0x7f) { \
+ (s)[(i)++]=(uint8_t)__uc; \
} else { \
- if((uint32_t)(c)<=0x7ff) { \
- (s)[(i)++]=(uint8_t)(((c)>>6)|0xc0); \
+ if(__uc<=0x7ff) { \
+ (s)[(i)++]=(uint8_t)((__uc>>6)|0xc0); \
} else { \
- if((uint32_t)(c)<=0xffff) { \
- (s)[(i)++]=(uint8_t)(((c)>>12)|0xe0); \
+ if(__uc<=0xffff) { \
+ (s)[(i)++]=(uint8_t)((__uc>>12)|0xe0); \
} else { \
- (s)[(i)++]=(uint8_t)(((c)>>18)|0xf0); \
- (s)[(i)++]=(uint8_t)((((c)>>12)&0x3f)|0x80); \
+ (s)[(i)++]=(uint8_t)((__uc>>18)|0xf0); \
+ (s)[(i)++]=(uint8_t)(((__uc>>12)&0x3f)|0x80); \
} \
- (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80); \
+ (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \
} \
- (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \
+ (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \
} \
}
@@ -467,17 +468,23 @@
* @stable ICU 2.4
*/
#define U8_APPEND(s, i, capacity, c, isError) { \
- if((uint32_t)(c)<=0x7f) { \
- (s)[(i)++]=(uint8_t)(c); \
- } else if((uint32_t)(c)<=0x7ff && (i)+1<(capacity)) { \
- (s)[(i)++]=(uint8_t)(((c)>>6)|0xc0); \
- (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \
- } else if((uint32_t)(c)<=0xd7ff && (i)+2<(capacity)) { \
- (s)[(i)++]=(uint8_t)(((c)>>12)|0xe0); \
- (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80); \
- (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \
+ uint32_t __uc=(c); \
+ if(__uc<=0x7f) { \
+ (s)[(i)++]=(uint8_t)__uc; \
+ } else if(__uc<=0x7ff && (i)+1<(capacity)) { \
+ (s)[(i)++]=(uint8_t)((__uc>>6)|0xc0); \
+ (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \
+ } else if((__uc<=0xd7ff || (0xe000<=__uc && __uc<=0xffff)) && (i)+2<(capacity)) { \
+ (s)[(i)++]=(uint8_t)((__uc>>12)|0xe0); \
+ (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \
+ (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \
+ } else if(0xffff<__uc && __uc<=0x10ffff && (i)+3<(capacity)) { \
+ (s)[(i)++]=(uint8_t)((__uc>>18)|0xf0); \
+ (s)[(i)++]=(uint8_t)(((__uc>>12)&0x3f)|0x80); \
+ (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \
+ (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \
} else { \
- (i)=utf8_appendCharSafeBody(s, (i), (capacity), c, &(isError)); \
+ (isError)=TRUE; \
} \
}
diff --git a/src/third_party/icu/source/common/ustr_imp.h b/src/third_party/icu/source/common/ustr_imp.h
index a746016..051292a 100644
--- a/src/third_party/icu/source/common/ustr_imp.h
+++ b/src/third_party/icu/source/common/ustr_imp.h
@@ -218,6 +218,44 @@
UTF8CaseMapper *stringCaseMapper,
UErrorCode *pErrorCode);
+#ifdef __cplusplus
+
+U_NAMESPACE_BEGIN
+namespace GreekUpper {
+
+// Data bits.
+static const uint32_t UPPER_MASK = 0x3ff;
+static const uint32_t HAS_VOWEL = 0x1000;
+static const uint32_t HAS_YPOGEGRAMMENI = 0x2000;
+static const uint32_t HAS_ACCENT = 0x4000;
+static const uint32_t HAS_DIALYTIKA = 0x8000;
+// Further bits during data building and processing, not stored in the data map.
+static const uint32_t HAS_COMBINING_DIALYTIKA = 0x10000;
+static const uint32_t HAS_OTHER_GREEK_DIACRITIC = 0x20000;
+
+static const uint32_t HAS_VOWEL_AND_ACCENT = HAS_VOWEL | HAS_ACCENT;
+static const uint32_t HAS_VOWEL_AND_ACCENT_AND_DIALYTIKA =
+ HAS_VOWEL_AND_ACCENT | HAS_DIALYTIKA;
+static const uint32_t HAS_EITHER_DIALYTIKA = HAS_DIALYTIKA | HAS_COMBINING_DIALYTIKA;
+
+// State bits.
+static const uint32_t AFTER_CASED = 1;
+static const uint32_t AFTER_VOWEL_WITH_ACCENT = 2;
+
+uint32_t getLetterData(UChar32 c);
+
+/**
+ * Returns a non-zero value for each of the Greek combining diacritics
+ * listed in The Unicode Standard, version 8, chapter 7.2 Greek,
+ * plus some perispomeni look-alikes.
+ */
+uint32_t getDiacriticData(UChar32 c);
+
+} // namespace GreekUpper
+U_NAMESPACE_END
+
+#endif // __cplusplus
+
U_CAPI int32_t U_EXPORT2
ustr_hashUCharsN(const UChar *str, int32_t length);
diff --git a/src/third_party/icu/source/common/ustrcase.cpp b/src/third_party/icu/source/common/ustrcase.cpp
index ae3893a..5b8f8f6 100644
--- a/src/third_party/icu/source/common/ustrcase.cpp
+++ b/src/third_party/icu/source/common/ustrcase.cpp
@@ -89,6 +89,14 @@
return destIndex;
}
+static inline int32_t
+appendUChar(UChar *dest, int32_t destIndex, int32_t destCapacity, UChar c) {
+ if(destIndex<destCapacity) {
+ dest[destIndex]=c;
+ }
+ return destIndex+1;
+}
+
static UChar32 U_CALLCONV
utf16_caseContextIterator(void *context, int8_t dir) {
UCaseContext *csc=(UCaseContext *)context;
@@ -295,6 +303,597 @@
#endif // !UCONFIG_NO_BREAK_ITERATION
+U_NAMESPACE_BEGIN
+namespace GreekUpper {
+
+// Data generated by prototype code, see
+// http://site.icu-project.org/design/case/greek-upper
+// TODO: Move this data into ucase.icu.
+static const uint16_t data0370[] = {
+ // U+0370..03FF
+ 0x0370,
+ 0x0370,
+ 0x0372,
+ 0x0372,
+ 0,
+ 0,
+ 0x0376,
+ 0x0376,
+ 0,
+ 0,
+ 0x037A,
+ 0x03FD,
+ 0x03FE,
+ 0x03FF,
+ 0,
+ 0x037F,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT | HAS_DIALYTIKA,
+ 0x0391 | HAS_VOWEL,
+ 0x0392,
+ 0x0393,
+ 0x0394,
+ 0x0395 | HAS_VOWEL,
+ 0x0396,
+ 0x0397 | HAS_VOWEL,
+ 0x0398,
+ 0x0399 | HAS_VOWEL,
+ 0x039A,
+ 0x039B,
+ 0x039C,
+ 0x039D,
+ 0x039E,
+ 0x039F | HAS_VOWEL,
+ 0x03A0,
+ 0x03A1,
+ 0,
+ 0x03A3,
+ 0x03A4,
+ 0x03A5 | HAS_VOWEL,
+ 0x03A6,
+ 0x03A7,
+ 0x03A8,
+ 0x03A9 | HAS_VOWEL,
+ 0x0399 | HAS_VOWEL | HAS_DIALYTIKA,
+ 0x03A5 | HAS_VOWEL | HAS_DIALYTIKA,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT | HAS_DIALYTIKA,
+ 0x0391 | HAS_VOWEL,
+ 0x0392,
+ 0x0393,
+ 0x0394,
+ 0x0395 | HAS_VOWEL,
+ 0x0396,
+ 0x0397 | HAS_VOWEL,
+ 0x0398,
+ 0x0399 | HAS_VOWEL,
+ 0x039A,
+ 0x039B,
+ 0x039C,
+ 0x039D,
+ 0x039E,
+ 0x039F | HAS_VOWEL,
+ 0x03A0,
+ 0x03A1,
+ 0x03A3,
+ 0x03A3,
+ 0x03A4,
+ 0x03A5 | HAS_VOWEL,
+ 0x03A6,
+ 0x03A7,
+ 0x03A8,
+ 0x03A9 | HAS_VOWEL,
+ 0x0399 | HAS_VOWEL | HAS_DIALYTIKA,
+ 0x03A5 | HAS_VOWEL | HAS_DIALYTIKA,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03CF,
+ 0x0392,
+ 0x0398,
+ 0x03D2,
+ 0x03D2 | HAS_ACCENT,
+ 0x03D2 | HAS_DIALYTIKA,
+ 0x03A6,
+ 0x03A0,
+ 0x03CF,
+ 0x03D8,
+ 0x03D8,
+ 0x03DA,
+ 0x03DA,
+ 0x03DC,
+ 0x03DC,
+ 0x03DE,
+ 0x03DE,
+ 0x03E0,
+ 0x03E0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0x039A,
+ 0x03A1,
+ 0x03F9,
+ 0x037F,
+ 0x03F4,
+ 0x0395 | HAS_VOWEL,
+ 0,
+ 0x03F7,
+ 0x03F7,
+ 0x03F9,
+ 0x03FA,
+ 0x03FA,
+ 0x03FC,
+ 0x03FD,
+ 0x03FE,
+ 0x03FF,
+};
+
+static const uint16_t data1F00[] = {
+ // U+1F00..1FFF
+ 0x0391 | HAS_VOWEL,
+ 0x0391 | HAS_VOWEL,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL,
+ 0x0391 | HAS_VOWEL,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0395 | HAS_VOWEL,
+ 0x0395 | HAS_VOWEL,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0,
+ 0,
+ 0x0395 | HAS_VOWEL,
+ 0x0395 | HAS_VOWEL,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0,
+ 0,
+ 0x0397 | HAS_VOWEL,
+ 0x0397 | HAS_VOWEL,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL,
+ 0x0397 | HAS_VOWEL,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL,
+ 0x0399 | HAS_VOWEL,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL,
+ 0x0399 | HAS_VOWEL,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x039F | HAS_VOWEL,
+ 0x039F | HAS_VOWEL,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0,
+ 0,
+ 0x039F | HAS_VOWEL,
+ 0x039F | HAS_VOWEL,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0,
+ 0,
+ 0x03A5 | HAS_VOWEL,
+ 0x03A5 | HAS_VOWEL,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0,
+ 0x03A5 | HAS_VOWEL,
+ 0,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL,
+ 0x03A9 | HAS_VOWEL,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL,
+ 0x03A9 | HAS_VOWEL,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0,
+ 0,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL,
+ 0x0391 | HAS_VOWEL,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL,
+ 0x0391 | HAS_VOWEL,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_ACCENT,
+ 0x0391 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0,
+ 0x0399 | HAS_VOWEL,
+ 0,
+ 0,
+ 0,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0x0395 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_ACCENT,
+ 0x0397 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0,
+ 0,
+ 0,
+ 0x0399 | HAS_VOWEL,
+ 0x0399 | HAS_VOWEL,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT | HAS_DIALYTIKA,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT | HAS_DIALYTIKA,
+ 0,
+ 0,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT | HAS_DIALYTIKA,
+ 0x0399 | HAS_VOWEL,
+ 0x0399 | HAS_VOWEL,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0x0399 | HAS_VOWEL | HAS_ACCENT,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0x03A5 | HAS_VOWEL,
+ 0x03A5 | HAS_VOWEL,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT | HAS_DIALYTIKA,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT | HAS_DIALYTIKA,
+ 0x03A1,
+ 0x03A1,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT | HAS_DIALYTIKA,
+ 0x03A5 | HAS_VOWEL,
+ 0x03A5 | HAS_VOWEL,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A5 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI | HAS_ACCENT,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0x039F | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_ACCENT,
+ 0x03A9 | HAS_VOWEL | HAS_YPOGEGRAMMENI,
+ 0,
+ 0,
+ 0,
+};
+
+// U+2126 Ohm sign
+static const uint16_t data2126 = 0x03A9 | HAS_VOWEL;
+
+uint32_t getLetterData(UChar32 c) {
+ if (c < 0x370 || 0x2126 < c || (0x3ff < c && c < 0x1f00)) {
+ return 0;
+ } else if (c <= 0x3ff) {
+ return data0370[c - 0x370];
+ } else if (c <= 0x1fff) {
+ return data1F00[c - 0x1f00];
+ } else if (c == 0x2126) {
+ return data2126;
+ } else {
+ return 0;
+ }
+}
+
+uint32_t getDiacriticData(UChar32 c) {
+ switch (c) {
+ case 0x0300: // varia
+ case 0x0301: // tonos = oxia
+ case 0x0342: // perispomeni
+ case 0x0302: // circumflex can look like perispomeni
+ case 0x0303: // tilde can look like perispomeni
+ case 0x0311: // inverted breve can look like perispomeni
+ return HAS_ACCENT;
+ case 0x0308: // dialytika = diaeresis
+ return HAS_COMBINING_DIALYTIKA;
+ case 0x0344: // dialytika tonos
+ return HAS_COMBINING_DIALYTIKA | HAS_ACCENT;
+ case 0x0345: // ypogegrammeni = iota subscript
+ return HAS_YPOGEGRAMMENI;
+ case 0x0304: // macron
+ case 0x0306: // breve
+ case 0x0313: // comma above
+ case 0x0314: // reversed comma above
+ case 0x0343: // koronis
+ return HAS_OTHER_GREEK_DIACRITIC;
+ default:
+ return 0;
+ }
+}
+
+UBool isFollowedByCasedLetter(const UCaseProps *csp, const UChar *s, int32_t i, int32_t length) {
+ while (i < length) {
+ UChar32 c;
+ U16_NEXT(s, i, length, c);
+ int32_t type = ucase_getTypeOrIgnorable(csp, c);
+ if ((type & UCASE_IGNORABLE) != 0) {
+ // Case-ignorable, continue with the loop.
+ } else if (type != UCASE_NONE) {
+ return TRUE; // Followed by cased letter.
+ } else {
+ return FALSE; // Uncased and not case-ignorable.
+ }
+ }
+ return FALSE; // Not followed by cased letter.
+}
+
+/**
+ * Greek string uppercasing with a state machine.
+ * Probably simpler than a stateless function that has to figure out complex context-before
+ * for each character.
+ * TODO: Try to re-consolidate one way or another with the non-Greek function.
+ */
+int32_t toUpper(const UCaseMap *csm,
+ UChar *dest, int32_t destCapacity,
+ const UChar *src, int32_t srcLength,
+ UErrorCode *pErrorCode) {
+ int32_t locCache = UCASE_LOC_GREEK;
+ int32_t destIndex=0;
+ uint32_t state = 0;
+ for (int32_t i = 0; i < srcLength;) {
+ int32_t nextIndex = i;
+ UChar32 c;
+ U16_NEXT(src, nextIndex, srcLength, c);
+ uint32_t nextState = 0;
+ int32_t type = ucase_getTypeOrIgnorable(csm->csp, c);
+ if ((type & UCASE_IGNORABLE) != 0) {
+ // c is case-ignorable
+ nextState |= (state & AFTER_CASED);
+ } else if (type != UCASE_NONE) {
+ // c is cased
+ nextState |= AFTER_CASED;
+ }
+ uint32_t data = getLetterData(c);
+ if (data > 0) {
+ uint32_t upper = data & UPPER_MASK;
+ // Add a dialytika to this iota or ypsilon vowel
+ // if we removed a tonos from the previous vowel,
+ // and that previous vowel did not also have (or gain) a dialytika.
+ // Adding one only to the final vowel in a longer sequence
+ // (which does not occur in normal writing) would require lookahead.
+ // Set the same flag as for preserving an existing dialytika.
+ if ((data & HAS_VOWEL) != 0 && (state & AFTER_VOWEL_WITH_ACCENT) != 0 &&
+ (upper == 0x399 || upper == 0x3A5)) {
+ data |= HAS_DIALYTIKA;
+ }
+ int32_t numYpogegrammeni = 0; // Map each one to a trailing, spacing, capital iota.
+ if ((data & HAS_YPOGEGRAMMENI) != 0) {
+ numYpogegrammeni = 1;
+ }
+ // Skip combining diacritics after this Greek letter.
+ while (nextIndex < srcLength) {
+ uint32_t diacriticData = getDiacriticData(src[nextIndex]);
+ if (diacriticData != 0) {
+ data |= diacriticData;
+ if ((diacriticData & HAS_YPOGEGRAMMENI) != 0) {
+ ++numYpogegrammeni;
+ }
+ ++nextIndex;
+ } else {
+ break; // not a Greek diacritic
+ }
+ }
+ if ((data & HAS_VOWEL_AND_ACCENT_AND_DIALYTIKA) == HAS_VOWEL_AND_ACCENT) {
+ nextState |= AFTER_VOWEL_WITH_ACCENT;
+ }
+ // Map according to Greek rules.
+ UBool addTonos = FALSE;
+ if (upper == 0x397 &&
+ (data & HAS_ACCENT) != 0 &&
+ numYpogegrammeni == 0 &&
+ (state & AFTER_CASED) == 0 &&
+ !isFollowedByCasedLetter(csm->csp, src, nextIndex, srcLength)) {
+ // Keep disjunctive "or" with (only) a tonos.
+ // We use the same "word boundary" conditions as for the Final_Sigma test.
+ if (i == nextIndex) {
+ upper = 0x389; // Preserve the precomposed form.
+ } else {
+ addTonos = TRUE;
+ }
+ } else if ((data & HAS_DIALYTIKA) != 0) {
+ // Preserve a vowel with dialytika in precomposed form if it exists.
+ if (upper == 0x399) {
+ upper = 0x3AA;
+ data &= ~HAS_EITHER_DIALYTIKA;
+ } else if (upper == 0x3A5) {
+ upper = 0x3AB;
+ data &= ~HAS_EITHER_DIALYTIKA;
+ }
+ }
+ destIndex=appendUChar(dest, destIndex, destCapacity, (UChar)upper);
+ if ((data & HAS_EITHER_DIALYTIKA) != 0) {
+ destIndex=appendUChar(dest, destIndex, destCapacity, 0x308); // restore or add a dialytika
+ }
+ if (addTonos) {
+ destIndex=appendUChar(dest, destIndex, destCapacity, 0x301);
+ }
+ while (numYpogegrammeni > 0) {
+ destIndex=appendUChar(dest, destIndex, destCapacity, 0x399);
+ --numYpogegrammeni;
+ }
+ } else {
+ const UChar *s;
+ UChar32 c2 = 0;
+ c=ucase_toFullUpper(csm->csp, c, NULL, NULL, &s, csm->locale, &locCache);
+ if((destIndex<destCapacity) && (c<0 ? (c2=~c)<=0xffff : UCASE_MAX_STRING_LENGTH<c && (c2=c)<=0xffff)) {
+ /* fast path version of appendResult() for BMP results */
+ dest[destIndex++]=(UChar)c2;
+ } else {
+ destIndex=appendResult(dest, destIndex, destCapacity, c, s);
+ }
+ }
+ i = nextIndex;
+ state = nextState;
+ }
+
+ if(destIndex>destCapacity) {
+ *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+ }
+ return destIndex;
+}
+
+} // namespace GreekUpper
+U_NAMESPACE_END
+
/* functions available in the common library (for unistr_case.cpp) */
U_CFUNC int32_t U_CALLCONV
@@ -317,6 +916,10 @@
UChar *dest, int32_t destCapacity,
const UChar *src, int32_t srcLength,
UErrorCode *pErrorCode) {
+ int32_t locCache = csm->locCache;
+ if (ucase_getCaseLocale(csm->locale, &locCache) == UCASE_LOC_GREEK) {
+ return GreekUpper::toUpper(csm, dest, destCapacity, src, srcLength, pErrorCode);
+ }
UCaseContext csc=UCASECONTEXT_INITIALIZER;
csc.p=(void *)src;
csc.limit=srcLength;
diff --git a/src/third_party/icu/source/test/intltest/strcase.cpp b/src/third_party/icu/source/test/intltest/strcase.cpp
index 01d8db9..124841e 100644
--- a/src/third_party/icu/source/test/intltest/strcase.cpp
+++ b/src/third_party/icu/source/test/intltest/strcase.cpp
@@ -16,6 +16,7 @@
* Test file for string casing C++ API functions.
*/
+#include "unicode/std_string.h"
#include "unicode/uchar.h"
#include "unicode/ures.h"
#include "unicode/uloc.h"
@@ -28,6 +29,8 @@
#include "unicode/tstdtmod.h"
#include "cmemory.h"
+StringCaseTest::StringCaseTest() : GREEK_LOCALE_("el") {}
+
StringCaseTest::~StringCaseTest() {}
void
@@ -41,6 +44,7 @@
TESTCASE_AUTO(TestCasing);
#endif
TESTCASE_AUTO(TestFullCaseFoldingIterator);
+ TESTCASE_AUTO(TestGreekUpper);
TESTCASE_AUTO_END;
}
@@ -571,3 +575,113 @@
errln("error: FullCaseFoldingIterator yielded only %d (cp, full) pairs", (int)count);
}
}
+
+void
+StringCaseTest::assertGreekUpper(const char *s, const char *expected) {
+ UnicodeString s16 = UnicodeString(s).unescape();
+ UnicodeString expected16 = UnicodeString(expected).unescape();
+ UnicodeString msg = UnicodeString("UnicodeString::toUpper/Greek(\"") + s16 + "\")";
+ UnicodeString result16(s16);
+ result16.toUpper(GREEK_LOCALE_);
+ assertEquals(msg, expected16, result16);
+
+#if U_HAVE_STD_STRING
+ UErrorCode errorCode = U_ZERO_ERROR;
+ LocalUCaseMapPointer csm(ucasemap_open("el", 0, &errorCode));
+ assertSuccess("ucasemap_open", errorCode);
+ std::string s8;
+ s16.toUTF8String(s8);
+ msg = UnicodeString("ucasemap_utf8ToUpper/Greek(\"") + s16 + "\")";
+ char dest[1000];
+ int32_t length = ucasemap_utf8ToUpper(csm.getAlias(), dest, UPRV_LENGTHOF(dest),
+ s8.data(), s8.length(), &errorCode);
+ assertSuccess("ucasemap_utf8ToUpper", errorCode);
+ StringPiece result8(dest, length);
+ UnicodeString result16From8 = UnicodeString::fromUTF8(result8);
+ assertEquals(msg, expected16, result16From8);
+#endif
+}
+
+void
+StringCaseTest::TestGreekUpper() {
+ // See UCharacterCaseTest.java for human-readable strings.
+
+ // http://bugs.icu-project.org/trac/ticket/5456
+ assertGreekUpper("\\u03AC\\u03B4\\u03B9\\u03BA\\u03BF\\u03C2, "
+ "\\u03BA\\u03B5\\u03AF\\u03BC\\u03B5\\u03BD\\u03BF, "
+ "\\u03AF\\u03C1\\u03B9\\u03B4\\u03B1",
+ "\\u0391\\u0394\\u0399\\u039A\\u039F\\u03A3, "
+ "\\u039A\\u0395\\u0399\\u039C\\u0395\\u039D\\u039F, "
+ "\\u0399\\u03A1\\u0399\\u0394\\u0391");
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=307039
+ // https://bug307039.bmoattachments.org/attachment.cgi?id=194893
+ assertGreekUpper("\\u03A0\\u03B1\\u03C4\\u03AC\\u03C4\\u03B1",
+ "\\u03A0\\u0391\\u03A4\\u0391\\u03A4\\u0391");
+ assertGreekUpper("\\u0391\\u03AD\\u03C1\\u03B1\\u03C2, "
+ "\\u039C\\u03C5\\u03C3\\u03C4\\u03AE\\u03C1\\u03B9\\u03BF, "
+ "\\u03A9\\u03C1\\u03B1\\u03AF\\u03BF",
+ "\\u0391\\u0395\\u03A1\\u0391\\u03A3, "
+ "\\u039C\\u03A5\\u03A3\\u03A4\\u0397\\u03A1\\u0399\\u039F, "
+ "\\u03A9\\u03A1\\u0391\\u0399\\u039F");
+ assertGreekUpper("\\u039C\\u03B1\\u0390\\u03BF\\u03C5, \\u03A0\\u03CC\\u03C1\\u03BF\\u03C2, "
+ "\\u03A1\\u03CD\\u03B8\\u03BC\\u03B9\\u03C3\\u03B7",
+ "\\u039C\\u0391\\u03AA\\u039F\\u03A5, \\u03A0\\u039F\\u03A1\\u039F\\u03A3, "
+ "\\u03A1\\u03A5\\u0398\\u039C\\u0399\\u03A3\\u0397");
+ assertGreekUpper("\\u03B0, \\u03A4\\u03B7\\u03C1\\u03CE, \\u039C\\u03AC\\u03B9\\u03BF\\u03C2",
+ "\\u03AB, \\u03A4\\u0397\\u03A1\\u03A9, \\u039C\\u0391\\u03AA\\u039F\\u03A3");
+ assertGreekUpper("\\u03AC\\u03C5\\u03BB\\u03BF\\u03C2",
+ "\\u0391\\u03AB\\u039B\\u039F\\u03A3");
+ assertGreekUpper("\\u0391\\u03AB\\u039B\\u039F\\u03A3",
+ "\\u0391\\u03AB\\u039B\\u039F\\u03A3");
+ assertGreekUpper("\\u0386\\u03BA\\u03BB\\u03B9\\u03C4\\u03B1 "
+ "\\u03C1\\u03AE\\u03BC\\u03B1\\u03C4\\u03B1 \\u03AE "
+ "\\u03AC\\u03BA\\u03BB\\u03B9\\u03C4\\u03B5\\u03C2 "
+ "\\u03BC\\u03B5\\u03C4\\u03BF\\u03C7\\u03AD\\u03C2",
+ "\\u0391\\u039A\\u039B\\u0399\\u03A4\\u0391 "
+ "\\u03A1\\u0397\\u039C\\u0391\\u03A4\\u0391 \\u0397\\u0301 "
+ "\\u0391\\u039A\\u039B\\u0399\\u03A4\\u0395\\u03A3 "
+ "\\u039C\\u0395\\u03A4\\u039F\\u03A7\\u0395\\u03A3");
+ // http://www.unicode.org/udhr/d/udhr_ell_monotonic.html
+ assertGreekUpper("\\u0395\\u03C0\\u03B5\\u03B9\\u03B4\\u03AE \\u03B7 "
+ "\\u03B1\\u03BD\\u03B1\\u03B3\\u03BD\\u03CE\\u03C1\\u03B9\\u03C3\\u03B7 "
+ "\\u03C4\\u03B7\\u03C2 \\u03B1\\u03BE\\u03B9\\u03BF\\u03C0\\u03C1\\u03AD"
+ "\\u03C0\\u03B5\\u03B9\\u03B1\\u03C2",
+ "\\u0395\\u03A0\\u0395\\u0399\\u0394\\u0397 \\u0397 "
+ "\\u0391\\u039D\\u0391\\u0393\\u039D\\u03A9\\u03A1\\u0399\\u03A3\\u0397 "
+ "\\u03A4\\u0397\\u03A3 \\u0391\\u039E\\u0399\\u039F\\u03A0\\u03A1\\u0395"
+ "\\u03A0\\u0395\\u0399\\u0391\\u03A3");
+ assertGreekUpper("\\u03BD\\u03BF\\u03BC\\u03B9\\u03BA\\u03BF\\u03CD \\u03AE "
+ "\\u03B4\\u03B9\\u03B5\\u03B8\\u03BD\\u03BF\\u03CD\\u03C2",
+ "\\u039D\\u039F\\u039C\\u0399\\u039A\\u039F\\u03A5 \\u0397\\u0301 "
+ "\\u0394\\u0399\\u0395\\u0398\\u039D\\u039F\\u03A5\\u03A3");
+ // http://unicode.org/udhr/d/udhr_ell_polytonic.html
+ assertGreekUpper("\\u1F18\\u03C0\\u03B5\\u03B9\\u03B4\\u1F74 \\u1F21 "
+ "\\u1F00\\u03BD\\u03B1\\u03B3\\u03BD\\u1F7D\\u03C1\\u03B9\\u03C3\\u03B7",
+ "\\u0395\\u03A0\\u0395\\u0399\\u0394\\u0397 \\u0397 "
+ "\\u0391\\u039D\\u0391\\u0393\\u039D\\u03A9\\u03A1\\u0399\\u03A3\\u0397");
+ assertGreekUpper("\\u03BD\\u03BF\\u03BC\\u03B9\\u03BA\\u03BF\\u1FE6 \\u1F22 "
+ "\\u03B4\\u03B9\\u03B5\\u03B8\\u03BD\\u03BF\\u1FE6\\u03C2",
+ "\\u039D\\u039F\\u039C\\u0399\\u039A\\u039F\\u03A5 \\u0397\\u0301 "
+ "\\u0394\\u0399\\u0395\\u0398\\u039D\\u039F\\u03A5\\u03A3");
+ // From Google bug report
+ assertGreekUpper("\\u039D\\u03AD\\u03BF, "
+ "\\u0394\\u03B7\\u03BC\\u03B9\\u03BF\\u03C5\\u03C1\\u03B3\\u03AF\\u03B1",
+ "\\u039D\\u0395\\u039F, "
+ "\\u0394\\u0397\\u039C\\u0399\\u039F\\u03A5\\u03A1\\u0393\\u0399\\u0391");
+ // http://crbug.com/234797
+ assertGreekUpper("\\u0395\\u03BB\\u03AC\\u03C4\\u03B5 \\u03BD\\u03B1 \\u03C6\\u03AC\\u03C4\\u03B5 "
+ "\\u03C4\\u03B1 \\u03BA\\u03B1\\u03BB\\u03CD\\u03C4\\u03B5\\u03C1\\u03B1 "
+ "\\u03C0\\u03B1\\u03CA\\u03B4\\u03AC\\u03BA\\u03B9\\u03B1!",
+ "\\u0395\\u039B\\u0391\\u03A4\\u0395 \\u039D\\u0391 \\u03A6\\u0391\\u03A4\\u0395 "
+ "\\u03A4\\u0391 \\u039A\\u0391\\u039B\\u03A5\\u03A4\\u0395\\u03A1\\u0391 "
+ "\\u03A0\\u0391\\u03AA\\u0394\\u0391\\u039A\\u0399\\u0391!");
+ assertGreekUpper("\\u039C\\u03B1\\u0390\\u03BF\\u03C5, \\u03C4\\u03C1\\u03CC\\u03BB\\u03B5\\u03CA",
+ "\\u039C\\u0391\\u03AA\\u039F\\u03A5, \\u03A4\\u03A1\\u039F\\u039B\\u0395\\u03AA");
+ assertGreekUpper("\\u03A4\\u03BF \\u03AD\\u03BD\\u03B1 \\u03AE \\u03C4\\u03BF "
+ "\\u03AC\\u03BB\\u03BB\\u03BF.",
+ "\\u03A4\\u039F \\u0395\\u039D\\u0391 \\u0397\\u0301 \\u03A4\\u039F "
+ "\\u0391\\u039B\\u039B\\u039F.");
+ // http://multilingualtypesetting.co.uk/blog/greek-typesetting-tips/
+ assertGreekUpper("\\u03C1\\u03C9\\u03BC\\u03AD\\u03B9\\u03BA\\u03B1",
+ "\\u03A1\\u03A9\\u039C\\u0395\\u03AA\\u039A\\u0391");
+}
diff --git a/src/third_party/icu/source/test/intltest/ustrtest.h b/src/third_party/icu/source/test/intltest/ustrtest.h
index 655af1c..b9be294 100644
--- a/src/third_party/icu/source/test/intltest/ustrtest.h
+++ b/src/third_party/icu/source/test/intltest/ustrtest.h
@@ -7,6 +7,7 @@
#ifndef UNICODESTRINGTEST_H
#define UNICODESTRINGTEST_H
+#include "unicode/locid.h"
#include "unicode/unistr.h"
#include "intltest.h"
@@ -93,7 +94,7 @@
class StringCaseTest: public IntlTest {
public:
- StringCaseTest() {}
+ StringCaseTest();
virtual ~StringCaseTest();
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0);
@@ -106,6 +107,12 @@
void *iter, const char *localeID, uint32_t options);
void TestCasing();
void TestFullCaseFoldingIterator();
+ void TestGreekUpper();
+
+private:
+ void assertGreekUpper(const char *s, const char *expected);
+
+ Locale GREEK_LOCALE_;
};
#endif
diff --git a/src/third_party/mozjs-45/mozjs-45.gyp b/src/third_party/mozjs-45/mozjs-45.gyp
index 7641497..46c5b23 100644
--- a/src/third_party/mozjs-45/mozjs-45.gyp
+++ b/src/third_party/mozjs-45/mozjs-45.gyp
@@ -176,6 +176,13 @@
'target_name': 'mozjs-45_lib',
'type': 'static_library',
'cflags': ['<@(common_cflags)'],
+ # Dependent targets may need the headers from 'build_include_directory'
+ # as well. Although 'build_include_directory' specifies hard_dependency,
+ # that only prevents direct dependents from building in parallel -- it
+ # apparently does not prevent indirect dependents. So specifying this as
+ # a hard_dependency should ensure 'build_include_directory' is done for
+ # targets which depend on this.
+ 'hard_dependency': 1,
'dependencies': [
'build_include_directory',
'<(DEPTH)/starboard/client_porting/pr_starboard/pr_starboard.gyp:pr_starboard',
@@ -188,9 +195,6 @@
'cflags': ['<@(common_cflags)'],
'defines': ['<@(common_defines)'],
},
- 'export_dependent_settings': [
- 'build_include_directory',
- ],
'include_dirs': [
'<(DEPTH)/third_party/mozjs-45/js/src',
'<@(common_include_dirs)',
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/port.h b/src/third_party/protobuf/src/google/protobuf/stubs/port.h
index de90064..49d208e 100644
--- a/src/third_party/protobuf/src/google/protobuf/stubs/port.h
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/port.h
@@ -49,17 +49,18 @@
#include "starboard/memory.h"
#include "starboard/types.h"
// This workaround is for protoc auto-generated files which use memset.
-#ifndef memset
-#define memset SbMemorySet
#if SB_HAS_QUIRK(MEMSET_IN_SYSTEM_HEADERS)
namespace std {
inline namespace _LIBCPP_NAMESPACE {
inline void *SbMemorySet(void* destination, int byte_value,
size_t count) {
- return ::SbMemorySet(destination, byte_value, count);
+ return::SbMemorySet(destination, byte_value, count);
}
}
}
+#else
+#ifndef memset
+#define memset SbMemorySet
#endif // SB_HAS_QUIRK(MEMSET_IN_SYSTEM_HEADERS)
#endif // memset
#endif
diff --git a/src/v8/src/base/atomicops.h b/src/v8/src/base/atomicops.h
index c5ec1ea..9894dc4 100644
--- a/src/v8/src/base/atomicops.h
+++ b/src/v8/src/base/atomicops.h
@@ -38,11 +38,11 @@
#if defined(V8_OS_STARBOARD)
#include "starboard/atomic.h"
-#endif
#if SB_API_VERSION < 10
#error Your version of Starboard must support SbAtomic8 in order to use V8.
-#endif
+#endif // SB_API_VERSION < 10
+#endif // V8_OS_STARBOARD
namespace v8 {
namespace base {
diff --git a/src/v8/src/base/platform/platform-win32.cc b/src/v8/src/base/platform/platform-win32.cc
index 22580cc..a3f4199 100644
--- a/src/v8/src/base/platform/platform-win32.cc
+++ b/src/v8/src/base/platform/platform-win32.cc
@@ -642,7 +642,14 @@
int OS::VSNPrintF(char* str, int length, const char* format, va_list args) {
+#if defined(COBALT)
+ // In testing, _vsnprintf_s can fill result's tail with unexpected
+ // characters if strlen(str) < length. Switching to vsnprintf is what Cobalt
+ // uses for msvs platforms currently.
+ int n = vsnprintf(str, length, format, args);
+#else
int n = _vsnprintf_s(str, length, _TRUNCATE, format, args);
+#endif
// Make sure to zero-terminate the string if the output was
// truncated or if there was an error.
if (n < 0 || n >= length) {
diff --git a/src/v8/src/ostreams.cc b/src/v8/src/ostreams.cc
index 66b5702..4d787a4 100644
--- a/src/v8/src/ostreams.cc
+++ b/src/v8/src/ostreams.cc
@@ -15,6 +15,7 @@
namespace v8 {
namespace internal {
+#if !defined(COBALT)
OFStreamBase::OFStreamBase(FILE* f) : f_(f) {}
@@ -42,6 +43,9 @@
DCHECK_NOT_NULL(f);
rdbuf(&buf_);
}
+#else
+OFStream::OFStream(FILE* f) : std::ostream(nullptr) {}
+#endif // !defined(COBALT)
OFStream::~OFStream() {}
diff --git a/src/v8/src/ostreams.h b/src/v8/src/ostreams.h
index f2f961e..3dc73d9 100644
--- a/src/v8/src/ostreams.h
+++ b/src/v8/src/ostreams.h
@@ -18,7 +18,7 @@
namespace v8 {
namespace internal {
-
+#if !defined(COBALT)
class OFStreamBase : public std::streambuf {
public:
explicit OFStreamBase(FILE* f);
@@ -31,6 +31,7 @@
virtual int_type overflow(int_type c);
virtual std::streamsize xsputn(const char* s, std::streamsize n);
};
+#endif // !defined(COBALT)
// An output stream writing to a file.
@@ -40,7 +41,9 @@
virtual ~OFStream();
private:
+#if !defined(COBALT)
OFStreamBase buf_;
+#endif // !defined(COBALT)
};
diff --git a/src/v8/src/runtime/runtime-atomics.cc b/src/v8/src/runtime/runtime-atomics.cc
index cca1df9..de5d2b1 100644
--- a/src/v8/src/runtime/runtime-atomics.cc
+++ b/src/v8/src/runtime/runtime-atomics.cc
@@ -10,7 +10,9 @@
#include "src/conversions-inl.h"
#include "src/factory.h"
+#if defined(V8_OS_STARBOARD)
#include "starboard/log.h"
+#endif // V8_OS_STARBOARD
// Implement Atomic accesses to SharedArrayBuffers as defined in the
// SharedArrayBuffer draft spec, found here
@@ -21,7 +23,7 @@
namespace {
-#if defined(STARBOARD)
+#if defined(V8_OS_STARBOARD)
template <typename T>
inline T ExchangeSeqCst(T* p, T value) {
@@ -171,7 +173,7 @@
#error Unsupported platform!
-#endif
+#endif // V8_OS_STARBOARD
template <typename T>
T FromObject(Handle<Object> number);
diff --git a/src/v8/src/trap-handler/trap-handler.h b/src/v8/src/trap-handler/trap-handler.h
index b927818..4bfeef5 100644
--- a/src/v8/src/trap-handler/trap-handler.h
+++ b/src/v8/src/trap-handler/trap-handler.h
@@ -13,7 +13,9 @@
#include "src/flags.h"
#include "src/globals.h"
+#if V8_OS_STARBOARD
#include "starboard/log.h"
+#endif //V8_OS_STARBOARD
#if V8_OS_LINUX
#include <ucontext.h>
@@ -74,7 +76,7 @@
return FLAG_wasm_trap_handler && V8_TRAP_HANDLER_SUPPORTED;
}
-#if defined(STARBOARD)
+#if defined(V8_OS_STARBOARD)
inline bool IsThreadInWasm() {
SB_NOTREACHED();
return false;
@@ -85,7 +87,6 @@
extern THREAD_LOCAL int g_thread_in_wasm_code;
inline bool IsThreadInWasm() {
- SB_NOTIMPLEMENTED();
return g_thread_in_wasm_code;
}
@@ -102,7 +103,7 @@
g_thread_in_wasm_code = false;
}
}
-#endif
+#endif // V8_OS_STARBOARD
bool RegisterDefaultSignalHandler();
V8_EXPORT_PRIVATE void RestoreOriginalSignalHandler();
diff --git a/src/v8/src/v8.gyp b/src/v8/src/v8.gyp
index 6a64c48..b40af6c 100644
--- a/src/v8/src/v8.gyp
+++ b/src/v8/src/v8.gyp
@@ -37,16 +37,13 @@
'mksnapshot_exec': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)',
'v8_os_page_size%': 0,
- 'v8_use_snapshot': 0,
+ 'v8_use_snapshot': '<(cobalt_v8_buildtime_snapshot)',
'v8_optimized_debug': 0,
'v8_use_external_startup_data': 0,
# TODO: Enable i18n support.
'v8_enable_i18n_support': 0,
},
'target_defaults': {
- 'defines': [
- 'V8_OS_STARBOARD=1',
- ],
'msvs_disabled_warnings': [4267, 4312, 4351, 4355, 4800, 4838],
'conditions': [
['cobalt_config == "debug"', {
@@ -181,6 +178,11 @@
'toolsets': ['target'],
}],
],
+ 'target_conditions': [
+ ['_toolset=="target"', {
+ 'defines': ['V8_OS_STARBOARD=1'],
+ }],
+ ],
},
{
'target_name': 'v8_initializers',
@@ -312,6 +314,11 @@
],
}],
],
+ 'target_conditions': [
+ ['_toolset=="target"', {
+ 'defines': ['V8_OS_STARBOARD=1'],
+ }],
+ ],
},
{
'target_name': 'v8_snapshot',
@@ -426,7 +433,12 @@
'BUILDING_V8_SHARED',
],
}],
- ]
+ ],
+ 'target_conditions': [
+ ['_toolset=="target"', {
+ 'defines': ['V8_OS_STARBOARD=1'],
+ }],
+ ],
},
{
'target_name': 'v8_external_snapshot',
@@ -1893,6 +1905,17 @@
],
}],
],
+ 'target_conditions': [
+ ['_toolset=="target"', {
+ 'defines': ['V8_OS_STARBOARD=1'],
+ }, {
+ 'conditions': [
+ ['v8_target_arch=="x64" and host_os=="linux"', {
+ 'sources': ['trap-handler/handler-inside.cc']
+ }],
+ ],
+ }],
+ ],
},
{
'target_name': 'v8_libbase',
@@ -1975,6 +1998,9 @@
'src/common/android/include',
],
}],
+ ['_toolset=="target"', {
+ 'defines': ['V8_OS_STARBOARD=1'],
+ }],
],
'conditions': [
['want_separate_host_toolset==1', {
@@ -2010,9 +2036,49 @@
}
],
['OS=="starboard"', {
- 'sources': [
- 'base/debug/stack_trace_starboard.cc',
- 'base/platform/platform-starboard.cc',
+ 'target_conditions': [
+ ['_toolset=="host"', {
+ # if _toolset="host", we use the native host build which does not
+ # involve Starboard at all.
+ 'target_conditions': [
+ ['host_os=="linux"', {
+ 'ldflags_host': [
+ '-ldl',
+ '-lrt'
+ ],
+ 'sources': [
+ 'base/debug/stack_trace_posix.cc',
+ 'base/platform/platform-linux.cc',
+ 'base/platform/platform-posix.h',
+ 'base/platform/platform-posix.cc',
+ 'base/platform/platform-posix-time.h',
+ 'base/platform/platform-posix-time.cc',
+ ],
+ }],
+ ['host_os=="win"', {
+ # Most of the following codes are copied from 'OS="win"'
+ # section.
+ 'defines': [
+ '_CRT_RAND_S' # for rand_s()
+ ],
+ 'variables': {
+ 'gyp_generators': '<!(echo $GYP_GENERATORS)',
+ },
+ 'sources': [
+ 'base/debug/stack_trace_win.cc',
+ 'base/platform/platform-win32.cc',
+ 'base/win32-headers.h',
+ ],
+ 'msvs_disabled_warnings': [4351, 4355, 4800],
+ }],
+ ],
+ }, {
+ # If _toolset=="target", build with target platform's Starboard.
+ 'sources': [
+ 'base/debug/stack_trace_starboard.cc',
+ 'base/platform/platform-starboard.cc',
+ ],
+ }],
],
}],
['OS=="android"', {
@@ -2282,6 +2348,11 @@
'defines': [ 'BUILDING_V8_PLATFORM_SHARED' ],
}]
],
+ 'target_conditions': [
+ ['_toolset=="target"', {
+ 'defines': ['V8_OS_STARBOARD=1'],
+ }],
+ ],
'direct_dependent_settings': {
'include_dirs': [
'../include',
@@ -2312,6 +2383,11 @@
'toolsets': ['target'],
}],
],
+ 'target_conditions': [
+ ['_toolset=="target"', {
+ 'defines': ['V8_OS_STARBOARD=1'],
+ }],
+ ],
'direct_dependent_settings': {
'include_dirs': [
'../include',
@@ -2373,7 +2449,12 @@
}, {
'toolsets': ['target'],
}],
- ]
+ ],
+ 'target_conditions': [
+ ['_toolset=="target"', {
+ 'defines': ['V8_OS_STARBOARD=1'],
+ }],
+ ],
},
{
'target_name': 'js2c',