Import Cobalt 22.lts.1.305559
diff --git a/src/.pylintrc b/src/.pylintrc
index e167680..239c66f 100644
--- a/src/.pylintrc
+++ b/src/.pylintrc
@@ -118,6 +118,7 @@
old-raise-syntax,
parameter-unpacking,
print-statement,
+ raise-missing-from,
raising-string,
range-builtin-not-iterating,
raw_input-builtin,
@@ -129,6 +130,7 @@
setslice-method,
signature-differs,
standarderror-builtin,
+ super-with-arguments,
suppressed-message,
sys-max-int,
too-few-public-methods,
@@ -147,6 +149,8 @@
unicode-builtin,
unnecessary-pass,
unpacking-in-except,
+ unspecified-encoding,
+ use-maxsplit-arg,
useless-else-on-loop,
useless-object-inheritance,
useless-suppression,
diff --git a/src/build/toolchain/gcc_toolchain.gni b/src/build/toolchain/gcc_toolchain.gni
index 09af53d..42e2b80 100644
--- a/src/build/toolchain/gcc_toolchain.gni
+++ b/src/build/toolchain/gcc_toolchain.gni
@@ -665,7 +665,7 @@
ld = cxx
readelf = "${toolprefix}readelf"
ar = "${prefix}/llvm-ar"
- nm = "${prefix}/llvm-nm"
+ nm = "nm"
forward_variables_from(invoker,
[
diff --git a/src/cobalt/browser/browser.gyp b/src/cobalt/browser/browser.gyp
index 65444e2..6eb6f23 100644
--- a/src/cobalt/browser/browser.gyp
+++ b/src/cobalt/browser/browser.gyp
@@ -37,8 +37,6 @@
'memory_settings/checker.cc',
'memory_settings/checker.h',
'memory_settings/constants.h',
- 'memory_settings/constrainer.cc',
- 'memory_settings/constrainer.h',
'memory_settings/scaling_function.cc',
'memory_settings/scaling_function.h',
'memory_settings/memory_settings.cc',
@@ -209,7 +207,6 @@
'memory_settings/auto_mem_test.cc',
'memory_settings/auto_mem_settings_test.cc',
'memory_settings/calculations_test.cc',
- 'memory_settings/constrainer_test.cc',
'memory_settings/memory_settings_test.cc',
'memory_settings/pretty_print_test.cc',
'memory_settings/table_printer_test.cc',
diff --git a/src/cobalt/browser/browser_module.cc b/src/cobalt/browser/browser_module.cc
index f66ed8b..44fc15e 100644
--- a/src/cobalt/browser/browser_module.cc
+++ b/src/cobalt/browser/browser_module.cc
@@ -1641,7 +1641,7 @@
void BrowserModule::InitializeSystemWindow() {
TRACE_EVENT0("cobalt::browser", "BrowserModule::InitializeSystemWindow()");
DCHECK(!system_window_);
- if (media_module_) {
+ if (media_module_ && !window_size_.IsEmpty()) {
system_window_.reset(
new system_window::SystemWindow(event_dispatcher_, window_size_));
} else {
diff --git a/src/cobalt/browser/memory_settings/auto_mem.cc b/src/cobalt/browser/memory_settings/auto_mem.cc
index 30a040f..02e7140 100644
--- a/src/cobalt/browser/memory_settings/auto_mem.cc
+++ b/src/cobalt/browser/memory_settings/auto_mem.cc
@@ -20,6 +20,7 @@
#include <cmath>
#include <memory>
#include <string>
+#include <utility>
#include <vector>
#include "base/optional.h"
@@ -31,7 +32,6 @@
#include "cobalt/browser/memory_settings/auto_mem_settings.h"
#include "cobalt/browser/memory_settings/calculations.h"
#include "cobalt/browser/memory_settings/constants.h"
-#include "cobalt/browser/memory_settings/constrainer.h"
#include "cobalt/browser/memory_settings/memory_settings.h"
#include "cobalt/browser/memory_settings/pretty_print.h"
#include "cobalt/browser/memory_settings/scaling_function.h"
@@ -230,44 +230,6 @@
"monotonically decreasing values as input goes from 1.0 -> 0.0";
}
-int64_t GenerateTargetMemoryBytes(int64_t max_memory_bytes,
- int64_t current_memory_bytes,
- base::Optional<int64_t> reduce_memory_bytes) {
- // Make sure values are sanitized.
- max_memory_bytes = std::max<int64_t>(0, max_memory_bytes);
- current_memory_bytes = std::max<int64_t>(0, current_memory_bytes);
-
- // If reduce_memory_bytes is valid and it's a zero or positive value then
- // this is a signal that the calculation should be based off of this setting.
- bool use_reduce_memory_input =
- (reduce_memory_bytes && (-1 < *reduce_memory_bytes));
-
- if (use_reduce_memory_input) {
- // If reducing_memory_bytes is set exactly to 0, then this
- // this will disable max_memory_bytes setting. current_memory_bytes
- // will be returned as the target memory consumption,
- // which will prevent memory constraining.
- if (*reduce_memory_bytes == 0) {
- return current_memory_bytes;
- } else {
- // Reduce memory bytes will subtract from the current memory
- // consumption.
- const int64_t target_value = current_memory_bytes - *reduce_memory_bytes;
- return math::Clamp<int64_t>(target_value, 0, std::abs(target_value));
- }
- } else { // reduce_memory_bytes is not used. Use max_memory_bytes instead.
- // max_memory_bytes == 0 is special, and signals that no constraining
- // should happen.
- if (max_memory_bytes == 0) {
- return current_memory_bytes;
- } else {
- // A non-zero value means that max_memory_bytes is valid and should
- // be used as the target value.
- return max_memory_bytes;
- }
- }
-}
-
} // namespace
AutoMem::AutoMem(const math::Size& ui_resolution,
@@ -276,28 +238,11 @@
TRACE_EVENT0("cobalt::browser", "AutoMem::AutoMem()");
ConstructSettings(ui_resolution, command_line_settings, build_settings);
- const int64_t target_cpu_memory = GenerateTargetMemoryBytes(
- max_cpu_bytes_->value(), SumAllMemoryOfType(MemorySetting::kCPU),
- base::Optional<int64_t>(0));
- const int64_t target_gpu_memory = GenerateTargetMemoryBytes(
- max_gpu_bytes_->value(), SumAllMemoryOfType(MemorySetting::kGPU),
- reduced_gpu_bytes_->optional_value());
-
std::vector<MemorySetting*> memory_settings = AllMemorySettingsMutable();
- ConstrainToMemoryLimits(target_cpu_memory, target_gpu_memory,
- &memory_settings, &error_msgs_);
}
AutoMem::~AutoMem() {}
-const IntSetting* AutoMem::misc_cobalt_cpu_size_in_bytes() const {
- return misc_cobalt_cpu_size_in_bytes_.get();
-}
-
-const IntSetting* AutoMem::misc_cobalt_gpu_size_in_bytes() const {
- return misc_cobalt_gpu_size_in_bytes_.get();
-}
-
const IntSetting* AutoMem::remote_typeface_cache_size_in_bytes() const {
return remote_typeface_cache_size_in_bytes_.get();
}
@@ -350,8 +295,6 @@
// Keep these in alphabetical order.
all_settings.push_back(encoded_image_cache_size_in_bytes_.get());
all_settings.push_back(image_cache_size_in_bytes_.get());
- all_settings.push_back(misc_cobalt_cpu_size_in_bytes_.get());
- all_settings.push_back(misc_cobalt_gpu_size_in_bytes_.get());
all_settings.push_back(offscreen_target_cache_size_in_bytes_.get());
all_settings.push_back(remote_typeface_cache_size_in_bytes_.get());
all_settings.push_back(skia_atlas_texture_dimensions_.get());
@@ -421,15 +364,6 @@
max_cpu_bytes_ = CreateCpuSetting(command_line_settings, build_settings);
max_gpu_bytes_ = CreateGpuSetting(command_line_settings, build_settings);
- reduced_gpu_bytes_ = CreateSystemMemorySetting(
- switches::kReduceGpuMemoryBy, MemorySetting::kGPU,
- command_line_settings.reduce_gpu_memory_by,
- build_settings.reduce_gpu_memory_by, -1);
- if (reduced_gpu_bytes_->value() == -1) {
- // This effectively disables the value from being used in the constrainer.
- reduced_gpu_bytes_->set_value(MemorySetting::kUnset, 0);
- }
-
// Set the encoded image cache capacity
encoded_image_cache_size_in_bytes_ = CreateMemorySetting<IntSetting, int64_t>(
switches::kEncodedImageCacheSizeInBytes,
@@ -454,19 +388,6 @@
image_cache_size_in_bytes_->set_memory_scaling_function(
MakeLinearMemoryScaler(.75, 1.0));
- // Set the misc cobalt size to a specific size.
- misc_cobalt_cpu_size_in_bytes_.reset(
- new IntSetting("misc_cobalt_cpu_size_in_bytes"));
- misc_cobalt_cpu_size_in_bytes_->set_value(MemorySetting::kAutoSet,
- kMiscCobaltCpuSizeInBytes);
-
- // Set the misc cobalt size to a specific size.
- misc_cobalt_gpu_size_in_bytes_.reset(
- new IntSetting("misc_cobalt_gpu_size_in_bytes"));
- misc_cobalt_gpu_size_in_bytes_->set_memory_type(MemorySetting::kGPU);
- misc_cobalt_gpu_size_in_bytes_->set_value(
- MemorySetting::kAutoSet, CalculateMiscCobaltGpuSize(ui_resolution));
-
// Set remote_type_face_cache size.
remote_typeface_cache_size_in_bytes_ =
CreateMemorySetting<IntSetting, int64_t>(
diff --git a/src/cobalt/browser/memory_settings/auto_mem.h b/src/cobalt/browser/memory_settings/auto_mem.h
index fd78576..6aa2b76 100644
--- a/src/cobalt/browser/memory_settings/auto_mem.h
+++ b/src/cobalt/browser/memory_settings/auto_mem.h
@@ -44,11 +44,8 @@
const IntSetting* encoded_image_cache_size_in_bytes() const;
const IntSetting* image_cache_size_in_bytes() const;
- const IntSetting* javascript_gc_threshold_in_bytes() const;
// This setting represents all others cpu-memory consuming systems within
// the engine. This value has been hard coded.
- const IntSetting* misc_cobalt_cpu_size_in_bytes() const;
- const IntSetting* misc_cobalt_gpu_size_in_bytes() const;
const IntSetting* remote_typeface_cache_size_in_bytes() const;
const DimensionSetting* skia_atlas_texture_dimensions() const;
const IntSetting* skia_cache_size_in_bytes() const;
@@ -82,9 +79,6 @@
// All of the following are included in AllMemorySettings().
std::unique_ptr<IntSetting> encoded_image_cache_size_in_bytes_;
std::unique_ptr<IntSetting> image_cache_size_in_bytes_;
- std::unique_ptr<IntSetting> javascript_gc_threshold_in_bytes_;
- std::unique_ptr<IntSetting> misc_cobalt_cpu_size_in_bytes_;
- std::unique_ptr<IntSetting> misc_cobalt_gpu_size_in_bytes_;
std::unique_ptr<IntSetting> remote_typeface_cache_size_in_bytes_;
std::unique_ptr<DimensionSetting> skia_atlas_texture_dimensions_;
std::unique_ptr<IntSetting> skia_cache_size_in_bytes_;
@@ -95,18 +89,12 @@
// in AllMemorySettings().
std::unique_ptr<IntSetting> max_cpu_bytes_;
std::unique_ptr<IntSetting> max_gpu_bytes_;
- std::unique_ptr<IntSetting>
- reduced_cpu_bytes_; // Forces CPU memory reduction.
- std::unique_ptr<IntSetting>
- reduced_gpu_bytes_; // Forces GPU memory reduction.
std::vector<std::string> error_msgs_;
FRIEND_TEST(AutoMem, AllMemorySettingsAreOrderedByName);
FRIEND_TEST(AutoMem, ConstrainedCPUEnvironment);
FRIEND_TEST(AutoMem, ConstrainedGPUEnvironment);
- FRIEND_TEST(AutoMem, ExplicitReducedCPUMemoryConsumption);
- FRIEND_TEST(AutoMem, ExplicitReducedGPUMemoryConsumption);
FRIEND_TEST(AutoMem, MaxCpuIsIgnoredDuringExplicitMemoryReduction);
};
diff --git a/src/cobalt/browser/memory_settings/auto_mem_settings.cc b/src/cobalt/browser/memory_settings/auto_mem_settings.cc
index 98ef408..1a089e9 100644
--- a/src/cobalt/browser/memory_settings/auto_mem_settings.cc
+++ b/src/cobalt/browser/memory_settings/auto_mem_settings.cc
@@ -264,8 +264,6 @@
switches::kOffscreenTargetCacheSizeInBytes);
Set(command_line, &settings.max_cpu_in_bytes, switches::kMaxCobaltCpuUsage);
Set(command_line, &settings.max_gpu_in_bytes, switches::kMaxCobaltGpuUsage);
- Set(command_line, &settings.reduce_gpu_memory_by,
- switches::kReduceGpuMemoryBy);
return settings;
}
diff --git a/src/cobalt/browser/memory_settings/auto_mem_settings_test.cc b/src/cobalt/browser/memory_settings/auto_mem_settings_test.cc
index 5f2a555..3c710ca 100644
--- a/src/cobalt/browser/memory_settings/auto_mem_settings_test.cc
+++ b/src/cobalt/browser/memory_settings/auto_mem_settings_test.cc
@@ -81,8 +81,6 @@
max_cpu_in_bytes);
TEST_PARSE_INT(expected, value, switches::kMaxCobaltGpuUsage,
max_gpu_in_bytes);
- TEST_PARSE_INT(expected, value, switches::kReduceGpuMemoryBy,
- reduce_gpu_memory_by);
#undef TEST_PARSE_INT
}
@@ -122,7 +120,6 @@
EXPECT_FALSE(settings.offscreen_target_cache_size_in_bytes);
EXPECT_FALSE(settings.max_cpu_in_bytes);
EXPECT_FALSE(settings.max_gpu_in_bytes);
- EXPECT_FALSE(settings.reduce_gpu_memory_by);
AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
EXPECT_EQ(AutoMemSettings::kTypeBuild, build_settings.type);
diff --git a/src/cobalt/browser/memory_settings/auto_mem_test.cc b/src/cobalt/browser/memory_settings/auto_mem_test.cc
index 0891d87..64f76d3 100644
--- a/src/cobalt/browser/memory_settings/auto_mem_test.cc
+++ b/src/cobalt/browser/memory_settings/auto_mem_test.cc
@@ -37,12 +37,6 @@
const math::Size kResolution1080p(1920, 1080);
-// Represents what the cobalt engine can scale down to under a default
-// environment.
-const int64_t kSmallEngineCpuMemorySize = 130 * 1024 * 1024;
-
-const int64_t kSmallEngineGpuMemorySize = 68 * 1024 * 1024;
-
#define EXPECT_MEMORY_SETTING(SETTING, SOURCE, MEMORY_TYPE, VALUE) \
EXPECT_EQ(VALUE, SETTING->value()) << " failure for " << SETTING->name(); \
EXPECT_EQ(MEMORY_TYPE, SETTING->memory_type()) \
@@ -54,13 +48,6 @@
return AutoMemSettings(AutoMemSettings::kTypeCommandLine);
}
-std::unique_ptr<AutoMem> CreateDefaultAutoMem() {
- AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
- std::unique_ptr<AutoMem> auto_mem(
- new AutoMem(kResolution1080p, EmptyCommandLine(), build_settings));
- return auto_mem;
-}
-
} // namespace.
// Tests the expectation that the command-line overrides will be applied.
@@ -230,156 +217,6 @@
}
}
-// Tests the expectation that constraining the CPU memory to kSmallEngineSize
-// will result in AutoMem reducing to the expected memory footprint.
-TEST(AutoMem, ConstrainedCPUEnvironment) {
- AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
- build_settings.max_cpu_in_bytes = kSmallEngineCpuMemorySize;
-
- AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings);
-
- const int64_t cpu_memory_consumption =
- auto_mem.SumAllMemoryOfType(MemorySetting::kCPU);
- EXPECT_LE(cpu_memory_consumption, kSmallEngineCpuMemorySize);
-}
-
-// Tests the expectation that constraining the GPU memory will result
-// in AutoMem reducing the the memory footprint.
-TEST(AutoMem, ConstrainedGPUEnvironment) {
- AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
- build_settings.max_gpu_in_bytes = 57 * 1024 * 1024;
- AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings);
-
- std::vector<const MemorySetting*> settings = auto_mem.AllMemorySettings();
- const int64_t gpu_memory_consumption =
- SumMemoryConsumption(MemorySetting::kGPU, settings);
- EXPECT_LE(gpu_memory_consumption, *build_settings.max_gpu_in_bytes);
-}
-
-// Tests the expectation that constraining the CPU memory to 40MB will result
-// in AutoMem reducing the the memory footprint.
-TEST(AutoMem, ExplicitReducedGPUMemoryConsumption) {
- // STEP ONE: Get the "natural" size of the engine at the default test
- // settings.
- std::unique_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem();
-
- AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
- command_line_settings.reduce_gpu_memory_by = 5 * 1024 * 1024;
- AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
- AutoMem reduced_gpu_memory_auto_mem(kResolution1080p, command_line_settings,
- build_settings);
- EXPECT_EQ(5 * 1024 * 1024,
- reduced_gpu_memory_auto_mem.reduced_gpu_bytes_->value());
-
- const int64_t original_memory_consumption =
- default_auto_mem->SumAllMemoryOfType(MemorySetting::kGPU);
- const int64_t reduced_memory_consumption =
- reduced_gpu_memory_auto_mem.SumAllMemoryOfType(MemorySetting::kGPU);
-
- EXPECT_LE(5 * 1024 * 1024,
- original_memory_consumption - reduced_memory_consumption);
-}
-
-// Tests the expectation that the constrainer will not run on cpu memory if
-// --reduce_cpu_memory_by is set to 0.
-TEST(AutoMem, MaxCpuIsIgnoredWithZeroValueReduceCPUCommand) {
- // STEP ONE: Get the "natural" size of the engine at the default test
- // settings.
- std::unique_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem();
-
- AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
- AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
-
- // Max memory is 1-byte. We expect that the kReduceCpuMemoryBy = "0" will
- // override the max_cpu_in_bytes setting.
- build_settings.max_cpu_in_bytes = 1;
- command_line_settings.reduce_cpu_memory_by = 0;
-
- AutoMem auto_mem_no_reduce_cpu(kResolution1080p, command_line_settings,
- build_settings);
-
- const int64_t original_memory_consumption =
- default_auto_mem->SumAllMemoryOfType(MemorySetting::kCPU);
- const int64_t new_memory_consumption =
- auto_mem_no_reduce_cpu.SumAllMemoryOfType(MemorySetting::kCPU);
-
- // Max_cpu_in_bytes specifies one byte of memory, but reduce must override
- // this for this test to pass.
- EXPECT_EQ(original_memory_consumption, new_memory_consumption);
-}
-
-// Tests the expectation that the constrainer will not run on gpu memory if
-// --reduce_gpu_memory_by is set to 0.
-TEST(AutoMem, MaxCpuIsIgnoredWithZeroValueReduceGPUCommand) {
- // STEP ONE: Get the "natural" size of the engine at the default test
- // settings.
- std::unique_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem();
-
- AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
- AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
-
- // Max memory is 1-byte. We expect that the kReduceCpuMemoryBy = "0" will
- // override the max_cpu_in_bytes setting.
- build_settings.max_gpu_in_bytes = 1;
- command_line_settings.reduce_gpu_memory_by = 0;
-
- AutoMem auto_mem_no_reduce_cpu(kResolution1080p, command_line_settings,
- build_settings);
-
- const int64_t original_memory_consumption =
- default_auto_mem->SumAllMemoryOfType(MemorySetting::kGPU);
- const int64_t new_memory_consumption =
- auto_mem_no_reduce_cpu.SumAllMemoryOfType(MemorySetting::kGPU);
-
- // Max_gpu_in_bytes specifies one byte of memory, but reduce must override
- // this for this test to pass.
- EXPECT_EQ(original_memory_consumption, new_memory_consumption);
-}
-
-// Tests the expectation that if --reduce_cpu_memory_by is set to -1 that it
-// will be effectively disabled and --max_cpu_bytes be used as the memory
-// reduction means.
-TEST(AutoMem, MaxCpuIsEnabledWhenReduceCpuMemoryIsExplicitlyDisabled) {
- AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
- AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
-
- // Max memory is 1-byte. We expect that the kReduceCpuMemoryBy = "-1"
- // passed to the command line will cause max_cpu_in_bytes to be the
- // dominating memory reduction mechanism.
- build_settings.max_cpu_in_bytes = kSmallEngineGpuMemorySize;
- command_line_settings.reduce_cpu_memory_by = -1;
-
- AutoMem auto_mem_no_reduce_cpu(kResolution1080p, command_line_settings,
- build_settings);
- const int64_t memory_consumption =
- auto_mem_no_reduce_cpu.SumAllMemoryOfType(MemorySetting::kCPU);
- // Max_cpu_in_bytes specifies one byte of memory, but reduce must override
- // this for this test to pass.
- EXPECT_LE(memory_consumption, kSmallEngineCpuMemorySize);
-}
-
-// Tests the expectation that if --reduce_gpu_memory_by is set to -1 that it
-// will be effectively disabled and --max_gpu_bytes be used as the memory
-// reduction means.
-TEST(AutoMem, MaxGpuIsEnabledWhenReduceCpuMemoryIsExplicitlyDisabled) {
- AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
- AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
-
- // Max memory is 1-byte. We expect that the kReduceCpuMemoryBy = "-1"
- // passed to the command line will cause max_cpu_in_bytes to be the
- // dominating memory reduction mechanism.
- build_settings.max_gpu_in_bytes = kSmallEngineGpuMemorySize;
- command_line_settings.reduce_gpu_memory_by = -1;
-
- AutoMem auto_mem_no_reduce_cpu(kResolution1080p, command_line_settings,
- build_settings);
- const int64_t memory_consumption =
- auto_mem_no_reduce_cpu.SumAllMemoryOfType(MemorySetting::kGPU);
- // Max_cpu_in_bytes specifies one byte of memory, but reduce must override
- // this for this test to pass.
- EXPECT_LE(memory_consumption, kSmallEngineGpuMemorySize);
-}
-
// Tests that if the gpu memory could not be queried then the resulting
// max_gpu_bytes will not be valid.
TEST(AutoMem, NoDefaultGpuMemory) {
diff --git a/src/cobalt/browser/memory_settings/calculations.cc b/src/cobalt/browser/memory_settings/calculations.cc
index 7b5a35f..0bf7d5c 100644
--- a/src/cobalt/browser/memory_settings/calculations.cc
+++ b/src/cobalt/browser/memory_settings/calculations.cc
@@ -182,16 +182,6 @@
return std::max<int64_t>(output, kMinSkiaCacheSize);
}
-int64_t CalculateMiscCobaltGpuSize(const math::Size& ui_resolution) {
- // LinearRemap defines a mapping function which will map the number
- // of ui_resolution pixels to the misc memory of the GPU. This mapping
- // is linear such that:
- // 1080p (1920x1080) => maps to => 24MB
- LinearRemap remap(0, 1920 * 1080, 0, 24 * 1024 * 1024);
-
- return static_cast<int64_t>(remap.Map(ui_resolution.GetArea()));
-}
-
} // namespace memory_settings
} // namespace browser
} // namespace cobalt
diff --git a/src/cobalt/browser/memory_settings/calculations.h b/src/cobalt/browser/memory_settings/calculations.h
index d034fa1..0f4b035 100644
--- a/src/cobalt/browser/memory_settings/calculations.h
+++ b/src/cobalt/browser/memory_settings/calculations.h
@@ -63,10 +63,6 @@
// to be 4MB @ 1080p and scales accordingly.
int64_t CalculateSkiaCacheSize(const math::Size& ui_resolution);
-// Calculates the GPU usage of the app to un-accounted systems. Scales linearly
-// with ui_resolution.
-int64_t CalculateMiscCobaltGpuSize(const math::Size& ui_resolution);
-
} // namespace memory_settings
} // namespace browser
} // namespace cobalt
diff --git a/src/cobalt/browser/memory_settings/calculations_test.cc b/src/cobalt/browser/memory_settings/calculations_test.cc
index c19359a..53e67a2 100644
--- a/src/cobalt/browser/memory_settings/calculations_test.cc
+++ b/src/cobalt/browser/memory_settings/calculations_test.cc
@@ -177,11 +177,6 @@
CalculateSoftwareSurfaceCacheSizeInBytes(ui_resolution));
}
-TEST(MemoryCalculations, CalculateMiscCobaltGpuSize) {
- math::Size ui_resolution = GetDimensions(k1080p);
- EXPECT_EQ(24 * 1024 * 1024, CalculateMiscCobaltGpuSize(ui_resolution));
-}
-
} // namespace memory_settings
} // namespace browser
} // namespace cobalt
diff --git a/src/cobalt/browser/memory_settings/constrainer.cc b/src/cobalt/browser/memory_settings/constrainer.cc
deleted file mode 100644
index 5be827e..0000000
--- a/src/cobalt/browser/memory_settings/constrainer.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright 2017 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/browser/memory_settings/constrainer.h"
-
-#include <algorithm>
-#include <iterator>
-#include <vector>
-
-#include "base/logging.h"
-#include "cobalt/browser/memory_settings/memory_settings.h"
-#include "cobalt/browser/memory_settings/pretty_print.h"
-#include "starboard/configuration.h"
-
-namespace cobalt {
-namespace browser {
-namespace memory_settings {
-namespace {
-
-// Any memory setting that matches the MemoryType and is an AutoSet type is
-// passed to the output.
-std::vector<MemorySetting*> FilterSettings(
- MemorySetting::MemoryType memory_type,
- const std::vector<MemorySetting*>& settings) {
- std::vector<MemorySetting*> output;
- for (size_t i = 0; i < settings.size(); ++i) {
- MemorySetting* setting = settings[i];
- if (setting->memory_type() == memory_type) {
- output.push_back(setting);
- }
- }
- return output;
-}
-
-// Sums the memory consumption at the given global_constraining_value. The
-// settings variable is read buy not modified (despite the non-const
-// declaration). If constrained_values_out is non-null, then the computed
-// constraining values are stored in this vector.
-// Returns: The amount of memory in bytes that the memory settings vector will
-// consume at the given global_constraining_factor.
-int64_t SumMemoryConsumption(double global_constraining_factor,
- const std::vector<MemorySetting*>& memory_settings,
- std::vector<double>* constrained_values_out) {
- if (constrained_values_out) {
- constrained_values_out->clear();
- }
-
- int64_t sum = 0;
-
- // Iterates through the MemorySettings and determines the total memory
- // consumption at the current global_constraining_value.
- for (size_t i = 0; i < memory_settings.size(); ++i) {
- const MemorySetting* setting = memory_settings[i];
-
- const int64_t requested_consumption = setting->MemoryConsumption();
- double local_constraining_value = 1.0;
- if (setting->source_type() == MemorySetting::kAutoSet) {
- local_constraining_value =
- setting->ComputeAbsoluteMemoryScale(global_constraining_factor);
- }
-
- const int64_t new_consumption_value =
- static_cast<int64_t>(local_constraining_value * requested_consumption);
-
- if (constrained_values_out) {
- constrained_values_out->push_back(local_constraining_value);
- }
-
- sum += new_consumption_value;
- }
-
- return sum;
-}
-
-void CheckMemoryChange(const std::string& setting_name,
- int64_t old_memory_consumption,
- int64_t new_memory_consumption,
- double constraining_value) {
- if (old_memory_consumption == 0) {
- // If the system is already using no memory, then it can't use any less.
- return;
- }
-
- // Represents 1% allowed difference.
- static const double kErrorThreshold = 0.01;
-
- const double actual_constraining_value =
- static_cast<double>(new_memory_consumption) /
- static_cast<double>(old_memory_consumption);
-
- double diff = constraining_value - actual_constraining_value;
- if (diff < 0.0) {
- diff = -diff;
- }
-
- DCHECK_LE(diff, kErrorThreshold)
- << "MemorySetting " << setting_name << " did not change it's memory by "
- << "the expected value.\n"
- << " Expected Change: " << (constraining_value * 100) << "%\n"
- << " Actual Change: " << (diff * 100) << "%\n"
- << " Original memory consumption (bytes): " << old_memory_consumption
- << " New memory consumption (bytes): " << new_memory_consumption
- << "\n";
-}
-
-void ConstrainToMemoryLimit(int64_t memory_limit,
- std::vector<MemorySetting*>* memory_settings) {
- if (memory_settings->empty()) {
- return;
- }
-
- // If the memory consumed is already under the memory limit then no further
- // work needs to be done.
- if (SumMemoryConsumption(1.0, *memory_settings, NULL) <= memory_limit) {
- return;
- }
-
- // Iterate by small steps the constraining value from 1.0 (100%) toward
- // 0.0.
- static const double kStep = 0.0001; // .01% change per iteration.
- std::vector<double> constrained_sizes;
- // 1-1 mapping.
- constrained_sizes.resize(memory_settings->size());
- for (double global_constraining_factor = 1.0;
- global_constraining_factor >= 0.0; global_constraining_factor -= kStep) {
- global_constraining_factor = std::max(0.0, global_constraining_factor);
- const int64_t new_global_memory_consumption = SumMemoryConsumption(
- global_constraining_factor, *memory_settings, &constrained_sizes);
-
- const bool finished = (global_constraining_factor == 0.0) ||
- (new_global_memory_consumption <= memory_limit);
-
- if (finished) {
- break;
- }
- }
- DCHECK_EQ(memory_settings->size(), constrained_sizes.size());
- for (size_t i = 0; i < memory_settings->size(); ++i) {
- const double local_constraining_factor = constrained_sizes[i];
- MemorySetting* setting = memory_settings->at(i);
- if (local_constraining_factor != 1.0) {
- const int64_t old_memory_consumption = setting->MemoryConsumption();
- DCHECK_EQ(setting->source_type(), MemorySetting::kAutoSet);
- setting->ScaleMemory(local_constraining_factor);
- const int64_t new_memory_consumption = setting->MemoryConsumption();
-
- // If the memory doesn't actually change as predicted by the constraining
- // value then this check will catch it here.
- CheckMemoryChange(setting->name(), old_memory_consumption,
- new_memory_consumption, local_constraining_factor);
- }
- }
-}
-
-void ConstrainMemoryType(MemorySetting::MemoryType memory_type,
- int64_t max_memory,
- std::vector<MemorySetting*>* memory_settings,
- std::vector<std::string>* error_msgs) {
- if (max_memory == 0) {
- return;
- }
- DCHECK_NE(MemorySetting::kNotApplicable, memory_type);
- const char* memory_type_str = "UNKNOWN";
- switch (memory_type) {
- case MemorySetting::kCPU: {
- memory_type_str = "CPU";
- break;
- }
- case MemorySetting::kGPU: {
- memory_type_str = "GPU";
- break;
- }
- case MemorySetting::kNotApplicable: {
- memory_type_str = "ERROR";
- break;
- }
- }
-
- std::vector<MemorySetting*> filtered_settings =
- FilterSettings(memory_type, *memory_settings);
-
- const int64_t current_consumption =
- SumMemoryConsumption(memory_type, *memory_settings);
-
- if (current_consumption < max_memory) {
- return;
- }
-
- ConstrainToMemoryLimit(max_memory, &filtered_settings);
-
- const int64_t new_memory_size =
- SumMemoryConsumption(memory_type, *memory_settings);
-
- if (new_memory_size > max_memory) {
- std::stringstream ss;
- ss << "WARNING - ATTEMPTED TO CONSTRAIN " << memory_type_str
- << " MEMORY FROM " << ToMegabyteString(current_consumption, 2) << " TO "
- << ToMegabyteString(max_memory, 2) << ".\nBUT STOPPED"
- << " AT " << ToMegabyteString(new_memory_size, 2) << " because"
- << " there was nothing left to\n"
- << "constrain (settings refused to reduce any more memory). Try\n"
- << "setting more memory setting(s) to -1 to allow autoset.\n"
- << "Example: --image_cache_size_in_bytes=-1";
- error_msgs->push_back(ss.str());
- }
-}
-
-} // namespace.
-
-void ConstrainToMemoryLimits(int64_t max_cpu_memory, int64_t max_gpu_memory,
- std::vector<MemorySetting*>* memory_settings,
- std::vector<std::string>* error_msgs) {
- // Constrain cpu memory.
- ConstrainMemoryType(MemorySetting::kCPU, max_cpu_memory, memory_settings,
- error_msgs);
- // Constrain gpu memory.
- ConstrainMemoryType(MemorySetting::kGPU, max_gpu_memory, memory_settings,
- error_msgs);
-}
-
-} // namespace memory_settings
-} // namespace browser
-} // namespace cobalt
diff --git a/src/cobalt/browser/memory_settings/constrainer.h b/src/cobalt/browser/memory_settings/constrainer.h
deleted file mode 100644
index 97d4e04..0000000
--- a/src/cobalt/browser/memory_settings/constrainer.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2017 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_BROWSER_MEMORY_SETTINGS_CONSTRAINER_H_
-#define COBALT_BROWSER_MEMORY_SETTINGS_CONSTRAINER_H_
-
-#include <string>
-#include <vector>
-
-#include "base/optional.h"
-#include "cobalt/browser/memory_settings/memory_settings.h"
-#include "starboard/types.h"
-
-namespace cobalt {
-namespace browser {
-namespace memory_settings {
-
-// Constrains the memory in the memory_settings vector so that the target is
-// such that the sum of memory consumption is below max_cpu_memory and
-// max_gpu_memory.
-//
-// How the memory settings will reduce their memory usage is dependent on
-// the ConstrainerFunction they contain. It's possible that the memory
-// settings won't be able to match the target memory.
-//
-// The output variable error_msgs will be populated with any error messages
-// that result from this function call.
-void ConstrainToMemoryLimits(int64_t max_cpu_memory, int64_t max_gpu_memory,
- std::vector<MemorySetting*>* memory_settings,
- std::vector<std::string>* error_msgs);
-} // namespace memory_settings
-} // namespace browser
-} // namespace cobalt
-
-#endif // COBALT_BROWSER_MEMORY_SETTINGS_CONSTRAINER_H_
diff --git a/src/cobalt/browser/memory_settings/constrainer_test.cc b/src/cobalt/browser/memory_settings/constrainer_test.cc
deleted file mode 100644
index 1047d10..0000000
--- a/src/cobalt/browser/memory_settings/constrainer_test.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2017 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/browser/memory_settings/constrainer.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "cobalt/browser/memory_settings/memory_settings.h"
-#include "cobalt/browser/memory_settings/test_common.h"
-#include "starboard/configuration.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cobalt {
-namespace browser {
-namespace memory_settings {
-namespace {
-const int64_t kOneMegabyte = 1 * 1024 * 1024;
-const int64_t kTwoMegabytes = 2 * 1024 * 1024;
-const int64_t kFiveMegabytes = 5 * 1024 * 1024;
-const int64_t kNoGpuMemory = 0;
-
-ScalingFunction MakeLinearConstrainer() {
- // Linearly scale, but clamp between 0 and 1.
- return MakeLinearMemoryScaler(0.0, 1.0);
-}
-
-} // namespace.
-
-// Tests the expectation that given one IntSetting which occupies 2MB of
-// the available memory, and max_cpu_setting of 1MB, that
-// ConstrainToMemoryLimits() function will reduce the memory setting
-// down 1MB.
-TEST(ConstrainToMemoryLimits, ConstrainCpuMemoryWithOneSetting) {
- IntSetting int_setting("dummy_cpu_setting");
- int_setting.set_memory_type(MemorySetting::kCPU);
- int_setting.set_value(MemorySetting::kAutoSet, kTwoMegabytes);
-
- ScalingFunction constrainer(MakeLinearConstrainer());
-
- int_setting.set_memory_scaling_function(constrainer);
-
- std::vector<MemorySetting*> settings;
- settings.push_back(&int_setting);
-
- std::vector<std::string> error_msgs;
-
- // Will reduce the memory usage of the IntSetting.
- ConstrainToMemoryLimits(kOneMegabyte, kNoGpuMemory, &settings, &error_msgs);
- EXPECT_EQ(kOneMegabyte, int_setting.MemoryConsumption());
- EXPECT_TRUE(error_msgs.empty());
-}
-
-// Tests the expectation that given two IntSettings, one that was AutoSet and
-// one that was set by the command line and one set by the build system, that
-// only the AutoSet IntSetting will be constrained.
-TEST(ConstrainToMemoryLimits, ConstrainerIgnoresNonAutosetVariables) {
- IntSetting int_setting_autoset("autoset_cpu_setting");
- int_setting_autoset.set_memory_type(MemorySetting::kCPU);
- int_setting_autoset.set_value(MemorySetting::kAutoSet, kTwoMegabytes);
- int_setting_autoset.set_memory_scaling_function(MakeLinearConstrainer());
-
- IntSetting int_setting_cmdline("cmdline_cpu_setting");
- int_setting_cmdline.set_memory_type(MemorySetting::kCPU);
- int_setting_cmdline.set_value(MemorySetting::kCmdLine, kTwoMegabytes);
- int_setting_cmdline.set_memory_scaling_function(MakeLinearConstrainer());
-
- IntSetting int_setting_builtin("builtin_cpu_setting");
- int_setting_builtin.set_memory_type(MemorySetting::kCPU);
- int_setting_builtin.set_value(MemorySetting::kBuildSetting, kTwoMegabytes);
- int_setting_builtin.set_memory_scaling_function(MakeLinearConstrainer());
-
- std::vector<MemorySetting*> settings;
- settings.push_back(&int_setting_autoset);
- settings.push_back(&int_setting_cmdline);
- settings.push_back(&int_setting_builtin);
-
- std::vector<std::string> error_msgs;
-
- // Right now we need to shave off 1MB, but this can only come from the
- // MemorySetting that was autoset.
- ConstrainToMemoryLimits(kFiveMegabytes, kNoGpuMemory, &settings, &error_msgs);
-
- EXPECT_EQ(kOneMegabyte, int_setting_autoset.MemoryConsumption());
- EXPECT_EQ(kTwoMegabytes, int_setting_cmdline.MemoryConsumption());
- EXPECT_EQ(kTwoMegabytes, int_setting_builtin.MemoryConsumption());
-
- EXPECT_TRUE(error_msgs.empty());
-}
-
-} // namespace memory_settings
-} // namespace browser
-} // namespace cobalt
diff --git a/src/cobalt/browser/memory_settings/pretty_print.h b/src/cobalt/browser/memory_settings/pretty_print.h
index 868330c..bf049c3 100644
--- a/src/cobalt/browser/memory_settings/pretty_print.h
+++ b/src/cobalt/browser/memory_settings/pretty_print.h
@@ -28,27 +28,17 @@
namespace memory_settings {
// Generates a table, ie:
-//
-// NAME VALUE TYPE SOURCE
-// _______________________________________________________________________________
-// | | | | | |
-// | image_cache_size_in_bytes | 33554432 | 32.0 MB | GPU | AutoSet |
-// |______________________________________|_____________|_________|______|_________|
-// | | | | | |
-// | javascript_gc_threshold_in_bytes | 8388608 | 8.0 MB | CPU | Build |
-// |______________________________________|_____________|_________|______|_________|
-// | | | | | |
-// | misc_cobalt_engine_size_in_bytes | 33554432 | 32.0 MB | CPU | Build |
-// |______________________________________|_____________|_________|______|_________|
-// | | | | | |
-// | skia_atlas_texture_dimensions | 4096x8192x2 | 64.0 MB | GPU | Build |
-// |______________________________________|_____________|_________|______|_________|
-// | | | | | |
-// | skia_cache_size_in_bytes | 4194304 | 4.0 MB | GPU | Build |
-// |______________________________________|_____________|_________|______|_________|
-// | | | | | |
-// | software_surface_cache_size_in_bytes | N/A | N/A | N/A | N/A |
-// |______________________________________|_____________|_________|______|_________|
+// _______________________________________________________________________________
+// |SETTING NAME |VALUE | |TYPE |SOURCE |
+// | encoded_image_cache_size_in_bytes | 1048576 | 1.0 MB | CPU | Build |
+// | image_cache_size_in_bytes | 10485760 | 10.0 MB | GPU | AutoSet |
+// | offscreen_target_cache_size_in_bytes | 2097152 | 2.0 MB | GPU | AutoSet |
+// | remote_typeface_cache_size_in_bytes | 4194304 | 4.0 MB | CPU | Build |
+// | skia_atlas_texture_dimensions | 2048x2048x2 | 8.0 MB | GPU | AutoSet |
+// | skia_cache_size_in_bytes | 4194304 | 4.0 MB | GPU | Build |
+// | software_surface_cache_size_in_bytes | N/A | N/A | N/A | N/A |
+// |______________________________________|_____________|_________|______|_________|
+
std::string GeneratePrettyPrintTable(
bool use_color_ascii,
const std::vector<const MemorySetting*>& memory_settings);
diff --git a/src/cobalt/browser/switches.cc b/src/cobalt/browser/switches.cc
index 439de72..4241402 100644
--- a/src/cobalt/browser/switches.cc
+++ b/src/cobalt/browser/switches.cc
@@ -337,11 +337,6 @@
" and the number of locations can be overwritten by specifying it as the "
" value of the command line parameter, like '--qr_code_overlay=6'.";
-const char kReduceGpuMemoryBy[] = "reduce_gpu_memory_by";
-const char kReduceGpuMemoryByHelp[] =
- "Reduces the gpu-memory of the system by this amount. This causes AutoMem "
- "to reduce the runtime size of the GPU-Memory caches.";
-
const char kRemoteTypefaceCacheSizeInBytes[] =
"remote_typeface_cache_size_in_bytes";
const char kRemoteTypefaceCacheSizeInBytesHelp[] =
@@ -488,7 +483,6 @@
{kOmitDeviceAuthenticationQueryParameters,
kOmitDeviceAuthenticationQueryParametersHelp},
{kProxy, kProxyHelp}, {kQrCodeOverlay, kQrCodeOverlayHelp},
- {kReduceGpuMemoryBy, kReduceGpuMemoryByHelp},
{kRemoteTypefaceCacheSizeInBytes, kRemoteTypefaceCacheSizeInBytesHelp},
{kRetainRemoteTypefaceCacheDuringSuspend,
kRetainRemoteTypefaceCacheDuringSuspendHelp},
diff --git a/src/cobalt/browser/switches.h b/src/cobalt/browser/switches.h
index 0a95017..d07aa1e 100644
--- a/src/cobalt/browser/switches.h
+++ b/src/cobalt/browser/switches.h
@@ -133,8 +133,6 @@
extern const char kProxyHelp[];
extern const char kQrCodeOverlay[];
extern const char kQrCodeOverlayHelp[];
-extern const char kReduceGpuMemoryBy[];
-extern const char kReduceGpuMemoryByHelp[];
extern const char kRemoteTypefaceCacheSizeInBytes[];
extern const char kRemoteTypefaceCacheSizeInBytesHelp[];
extern const char kRetainRemoteTypefaceCacheDuringSuspend[];
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index ce625a1..52c4c5d 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-304997
\ No newline at end of file
+305559
\ No newline at end of file
diff --git a/src/cobalt/configuration/configuration.h b/src/cobalt/configuration/configuration.h
index 6913ea1..0acaec1 100644
--- a/src/cobalt/configuration/configuration.h
+++ b/src/cobalt/configuration/configuration.h
@@ -53,7 +53,6 @@
float CobaltImageCacheCapacityMultiplierWhenPlayingVideo();
int CobaltSkiaGlyphAtlasWidth();
int CobaltSkiaGlyphAtlasHeight();
- int CobaltJsGarbageCollectionThresholdInBytes();
int CobaltReduceCpuMemoryBy();
int CobaltReduceGpuMemoryBy();
bool CobaltGcZeal();
diff --git a/src/cobalt/doc/memory_tuning.md b/src/cobalt/doc/memory_tuning.md
index da5f972..8f65ee8 100644
--- a/src/cobalt/doc/memory_tuning.md
+++ b/src/cobalt/doc/memory_tuning.md
@@ -7,12 +7,6 @@
the memory allocations that will be assigned to the various subsystems in
cobalt.
-As an example, at the cost of performance you can reduce CPU memory on your
-platform by 5MB and GPU memory usage on your platform by 10MB using these
-command line flags:
-
-`cobalt --reduce_cpu_memory_by=5MB --reduce_gpu_memory_by=10MB`
-
Some settings will be "fixed" while others will be "flexible" so that their
memory consumption will scale down for memory constrained platforms.
@@ -20,8 +14,7 @@
**IMPORTANT**
*Setting `--max_cobalt_cpu_usage` and `--max_cobalt_gpu_usage` on the
-command line is a beta feature. When reducing memory, please use
-`--reduce_cpu_memory_by` and `--reduce_gpu_memory_by`.*
+command line is a beta feature.*
### Memory Settings Table ###
@@ -29,33 +22,16 @@
~~~
AutoMem:
-
- SETTING NAME VALUE TYPE SOURCE
- ________________________________________________________________________________
-| | | | | |
-| image_cache_size_in_bytes | 33554432 | 32.0 MB | GPU | AutoSet |
-|______________________________________|_____________|__________|______|_________|
-| | | | | |
-| javascript_gc_threshold_in_bytes | 8388608 | 8.0 MB | CPU | Build |
-|______________________________________|_____________|__________|______|_________|
-| | | | | |
-| misc_cobalt_cpu_size_in_bytes | 124780544 | 119.0 MB | CPU | AutoSet |
-|______________________________________|_____________|__________|______|_________|
-| | | | | |
-| misc_cobalt_gpu_size_in_bytes | 25165824 | 24.0 MB | GPU | AutoSet |
-|______________________________________|_____________|__________|______|_________|
-| | | | | |
-| remote_typeface_cache_size_in_bytes | 4194304 | 4.0 MB | CPU | Build |
-|______________________________________|_____________|__________|______|_________|
-| | | | | |
-| skia_atlas_texture_dimensions | 4096x8192x2 | 64.0 MB | GPU | Build |
-|______________________________________|_____________|__________|______|_________|
-| | | | | |
-| skia_cache_size_in_bytes | 4194304 | 4.0 MB | GPU | Build |
-|______________________________________|_____________|__________|______|_________|
-| | | | | |
-| software_surface_cache_size_in_bytes | N/A | N/A | N/A | N/A |
-|______________________________________|_____________|__________|______|_________|
+ _______________________________________________________________________________
+|SETTING NAME |VALUE | |TYPE |SOURCE |
+| encoded_image_cache_size_in_bytes | 1048576 | 1.0 MB | CPU | Build |
+| image_cache_size_in_bytes | 10485760 | 10.0 MB | GPU | AutoSet |
+| offscreen_target_cache_size_in_bytes | 2097152 | 2.0 MB | GPU | AutoSet |
+| remote_typeface_cache_size_in_bytes | 4194304 | 4.0 MB | CPU | Build |
+| skia_atlas_texture_dimensions | 2048x2048x2 | 8.0 MB | GPU | AutoSet |
+| skia_cache_size_in_bytes | 4194304 | 4.0 MB | GPU | Build |
+| software_surface_cache_size_in_bytes | N/A | N/A | N/A | N/A |
+|______________________________________|_____________|_________|______|_________|
~~~
This table shows the breakdown of how much memory is being allocated to each
@@ -101,8 +77,6 @@
* `AutoSet (Constrained)`
* This value was AutoSet to a default value, but then was reduced in
response to `max_cobalt_cpu_usage` or `max_cobalt_gpu_usage being` set too low.
- This will also trigger in response to `reduce_cpu_memory_by` or
- `reduce_cpu_memory_by` being set. See "Memory Scaling" section below.
### Maximum Memory Table ###
@@ -183,18 +157,6 @@
**TOTAL** value. The memory settings will be scaled down until their consumption is
less than or equal the maximum allowed value **TOTAL**. See also **SETTINGS CONSUME**.
-Another way to scale down the memory size is by passing the flags
-`--reduce_cpu_memory_by=XX` and `--reduce_gpu_memory_by=XX` which will:
-1) Ignore the `--max_cobalt_cpu_usage` and `--max_cobalt_gpu_usage`.
-2) Use the current memory consumption of the settings and then reduce that by
- the amount.
-
-For example, if cobalt uses 160MB of CPU memory then passing in
-`--reduce_cpu_memory_by=10MB` to the command line will attempt to reduce the
-footprint of cobalt by 10MB to 150MB. Note that this reduction is an an attempt,
-and it's possible this attempt will fail if the memory reduction is too aggressive
-or if memory settings have been explicitly set via the build or command line.
-
*Forcing a Memory Setting to be flexible*
If a memory setting is set via a build setting, then it's possible to make it
@@ -265,16 +227,6 @@
* Note that `SbSystemGetTotalGPUMemory()` is optional. If no value exists
for `max_cobalt_gpu_usage` in build/commandline/starboard settings then no
GPU memory checking is performed.
- * `reduce_cpu_memory_by`
- * This setting will trigger CPU memory consumption to be reduced by the amount
- specified. *This overrides the memory scaling behavior of `max_cobalt_cpu_usage`*.
- But this will not affect memory checking of `max_cobalt_cpu_usage` otherwise.
- * Set via command line or else the platform gyp build file.
- * `reduce_cpu_memory_by`
- * This setting will trigger GPU memory consumption to be reduced by the amount
- specified. *This overrides the memory scaling behavior of `max_cobalt_gpu_usage`*.
- But this will not affect memory checking of `max_cobalt_gpu_usage` otherwise.
- * Set via command line or else the platform gyp build file.
#### Memory Setting API ####
@@ -282,10 +234,6 @@
* See documentation *Image cache capacity* in `performance_tuning.md` for what
this setting does.
* Set via command line, or else build system, or else automatically by Cobalt.
- * `javascript_gc_threshold_in_bytes`
- * See documentation *Garbage collection trigger threshold* in `performance_tuning.md`
- for what this setting does.
- * Set via command line, or else build system, or else automatically by Cobalt.
* `remote_typeface_cache_size_in_bytes`
* Determines the capacity of the remote typefaces cache which manages all typefaces
downloaded from a web page.
diff --git a/src/cobalt/dom/event_target.h b/src/cobalt/dom/event_target.h
index 66b4a3f..7aca7e7 100644
--- a/src/cobalt/dom/event_target.h
+++ b/src/cobalt/dom/event_target.h
@@ -400,6 +400,20 @@
SetAttributeEventListener(base::Tokens::beforeunload(), event_listener);
}
+ const EventListenerScriptValue* onoffline() {
+ return GetAttributeEventListener(base::Tokens::offline());
+ }
+ void set_onoffline(const EventListenerScriptValue& event_listener) {
+ SetAttributeEventListener(base::Tokens::offline(), event_listener);
+ }
+
+ const EventListenerScriptValue* ononline() {
+ return GetAttributeEventListener(base::Tokens::online());
+ }
+ void set_ononline(const EventListenerScriptValue& event_listener) {
+ SetAttributeEventListener(base::Tokens::online(), event_listener);
+ }
+
const EventListenerScriptValue* ontransitionend() {
return GetAttributeEventListener(base::Tokens::transitionend());
}
diff --git a/src/cobalt/dom/performance.cc b/src/cobalt/dom/performance.cc
index 390fc55..d1298ce 100644
--- a/src/cobalt/dom/performance.cc
+++ b/src/cobalt/dom/performance.cc
@@ -16,8 +16,8 @@
#include <string>
-#include "base/time/time.h"
#include "base/time/default_clock.h"
+#include "base/time/time.h"
#include "cobalt/browser/stack_size_constants.h"
#include "cobalt/dom/dom_exception.h"
#include "cobalt/dom/memory_info.h"
@@ -67,14 +67,16 @@
return 0.0;
}
-} //namespace
+} // namespace
Performance::Performance(script::EnvironmentSettings* settings,
const scoped_refptr<base::BasicClock>& clock)
: EventTarget(settings),
time_origin_(base::TimeTicks::Now()),
tick_clock_(base::DefaultTickClock::GetInstance()),
- timing_(new PerformanceTiming(clock, time_origin_)),
+ timing_(new PerformanceTiming(
+ clock,
+ (time_origin_ - base::TimeTicks::UnixEpoch()).InMilliseconds())),
memory_(new MemoryInfo()),
resource_timing_buffer_size_limit_(
Performance::kMaxResourceTimingBufferSize),
@@ -83,8 +85,8 @@
resource_timing_secondary_buffer_current_size_(0),
performance_observer_task_queued_flag_(false),
add_to_performance_entry_buffer_flag_(false) {
- unix_at_zero_monotonic_ = GetUnixAtZeroMonotonic(
- base::DefaultClock::GetInstance(), tick_clock_);
+ unix_at_zero_monotonic_ =
+ GetUnixAtZeroMonotonic(base::DefaultClock::GetInstance(), tick_clock_);
lifecycle_timing_ = base::MakeRefCounted<PerformanceLifecycleTiming>(
"lifecycle timing", time_origin());
// Queue lifecycle timing.
@@ -95,15 +97,15 @@
// static
DOMHighResTimeStamp Performance::MonotonicTimeToDOMHighResTimeStamp(
- base::TimeTicks time_origin,
- base::TimeTicks monotonic_time) {
- if (monotonic_time.is_null() || time_origin.is_null())
- return 0.0;
+ base::TimeTicks time_origin, base::TimeTicks monotonic_time) {
+ if (monotonic_time.is_null() || time_origin.is_null()) return 0.0;
DOMHighResTimeStamp clamped_time =
- ClampTimeStampMinimumResolution(monotonic_time,
- Performance::kPerformanceTimerMinResolutionInMicroseconds) -
- ClampTimeStampMinimumResolution(time_origin,
- Performance::kPerformanceTimerMinResolutionInMicroseconds);
+ ClampTimeStampMinimumResolution(
+ monotonic_time,
+ Performance::kPerformanceTimerMinResolutionInMicroseconds) -
+ ClampTimeStampMinimumResolution(
+ time_origin,
+ Performance::kPerformanceTimerMinResolutionInMicroseconds);
return clamped_time;
}
@@ -140,8 +142,7 @@
// Return the sum of t1 and t2.
return ClampTimeStampMinimumResolution(
- t1 + t2,
- Performance::kPerformanceTimerMinResolutionInMicroseconds);
+ t1 + t2, Performance::kPerformanceTimerMinResolutionInMicroseconds);
}
void Performance::Mark(const std::string& mark_name,
@@ -382,8 +383,9 @@
// entry buffer.
PerformanceEntryList performance_entry_buffer;
for (const auto& entry : performance_entry_buffer_) {
- bool should_be_removed = PerformanceEntry::ToEntryTypeEnum(
- entry->entry_type()) == PerformanceEntry::kResource;
+ bool should_be_removed =
+ PerformanceEntry::ToEntryTypeEnum(entry->entry_type()) ==
+ PerformanceEntry::kResource;
if (!should_be_removed) {
performance_entry_buffer.push_back(entry);
}
@@ -606,8 +608,8 @@
// 2.Setup the resource timing entry for entry, given initiatorType,
// requestedURL, timingInfo, and cacheMode.
scoped_refptr<PerformanceResourceTiming> resource_timing(
- new PerformanceResourceTiming(timing_info, initiator_type,
- requested_url, this, time_origin_));
+ new PerformanceResourceTiming(timing_info, initiator_type, requested_url,
+ this, time_origin_));
// 2. Queue entry.
QueuePerformanceEntry(resource_timing);
// 3. Add entry to global's performance entry buffer.
@@ -621,8 +623,8 @@
void Performance::SetApplicationStartOrPreloadTimestamp(
bool is_preload, SbTimeMonotonic timestamp) {
- lifecycle_timing_->SetApplicationStartOrPreloadTimestamp(
- is_preload, timestamp);
+ lifecycle_timing_->SetApplicationStartOrPreloadTimestamp(is_preload,
+ timestamp);
}
void Performance::SetDeepLinkTimestamp(SbTimeMonotonic timestamp) {
diff --git a/src/cobalt/dom/performance_test.cc b/src/cobalt/dom/performance_test.cc
index be1e776..f0a28ed 100644
--- a/src/cobalt/dom/performance_test.cc
+++ b/src/cobalt/dom/performance_test.cc
@@ -25,7 +25,8 @@
new base::SystemMonotonicClock());
testing::StubEnvironmentSettings environment_settings;
- scoped_refptr<Performance> performance(new Performance(&environment_settings, clock));
+ scoped_refptr<Performance> performance(
+ new Performance(&environment_settings, clock));
// Test that now returns a result that is within a correct range for the
// current time.
@@ -46,10 +47,11 @@
new base::SystemMonotonicClock());
testing::StubEnvironmentSettings environment_settings;
- scoped_refptr<Performance> performance(new Performance(&environment_settings, clock));
+ scoped_refptr<Performance> performance(
+ new Performance(&environment_settings, clock));
base::TimeTicks current_time_ticks = base::TimeTicks::Now();
- DOMHighResTimeStamp current_time = ClampTimeStampMinimumResolution(
+ DOMHighResTimeStamp current_time = ClampTimeStampMinimumResolution(
current_time_ticks,
Performance::kPerformanceTimerMinResolutionInMicroseconds);
DOMHighResTimeStamp current_time_respect_to_time_origin =
@@ -70,17 +72,19 @@
// the object will be created at the beginning of a new navigation.
scoped_refptr<base::SystemMonotonicClock> clock(
new base::SystemMonotonicClock());
- base::TimeTicks lower_limit = base::TimeTicks::Now();
- scoped_refptr<PerformanceTiming> performance_timing(
- new PerformanceTiming(clock, base::TimeTicks::Now()));
+ uint64 lower_limit =
+ (base::TimeTicks::Now() - base::TimeTicks::UnixEpoch()).InMilliseconds();
- base::TimeTicks upper_limit = base::TimeTicks::Now();
+ testing::StubEnvironmentSettings environment_settings;
+ scoped_refptr<Performance> performance(
+ new Performance(&environment_settings, clock));
- DCHECK_GE(performance_timing->navigation_start(),
- static_cast<uint64>((lower_limit.ToInternalValue())));
- DCHECK_LE(performance_timing->navigation_start(),
- static_cast<uint64>((upper_limit.ToInternalValue())));
+ uint64 upper_limit =
+ (base::TimeTicks::Now() - base::TimeTicks::UnixEpoch()).InMilliseconds();
+
+ DCHECK_GE(performance->timing()->navigation_start(), lower_limit);
+ DCHECK_LE(performance->timing()->navigation_start(), upper_limit);
}
} // namespace dom
diff --git a/src/cobalt/dom/performance_timing.cc b/src/cobalt/dom/performance_timing.cc
index 910eb03..c0cf211 100644
--- a/src/cobalt/dom/performance_timing.cc
+++ b/src/cobalt/dom/performance_timing.cc
@@ -18,16 +18,13 @@
namespace dom {
PerformanceTiming::PerformanceTiming(
- const scoped_refptr<base::BasicClock>& clock,
- base::TimeTicks time_origin)
- : navigation_start_(time_origin),
+ const scoped_refptr<base::BasicClock>& clock, uint64 navigation_start)
+ : navigation_start_(navigation_start),
navigation_start_clock_(new base::OffsetClock(clock, clock->Now())) {}
PerformanceTiming::~PerformanceTiming() {}
-uint64 PerformanceTiming::navigation_start() const {
- return static_cast<uint64>(navigation_start_.ToInternalValue());
-}
+uint64 PerformanceTiming::navigation_start() const { return navigation_start_; }
scoped_refptr<base::OffsetClock> PerformanceTiming::GetNavigationStartClock() {
return navigation_start_clock_;
diff --git a/src/cobalt/dom/performance_timing.h b/src/cobalt/dom/performance_timing.h
index 184d92d..a0a761c 100644
--- a/src/cobalt/dom/performance_timing.h
+++ b/src/cobalt/dom/performance_timing.h
@@ -29,7 +29,7 @@
// Performance::Mark and Performance::Measure.
public:
explicit PerformanceTiming(const scoped_refptr<base::BasicClock>& clock,
- base::TimeTicks time_origin);
+ uint64 navigation_start);
// This attribute must return the time immediately after the user agent
// finishes prompting to unload the previous document. If there is no previous
@@ -50,7 +50,7 @@
~PerformanceTiming();
// The navigation start time relative to January 1, 1970.
- base::TimeTicks navigation_start_;
+ uint64 navigation_start_;
scoped_refptr<base::OffsetClock> navigation_start_clock_;
DISALLOW_COPY_AND_ASSIGN(PerformanceTiming);
diff --git a/src/cobalt/dom/window_event_handlers.idl b/src/cobalt/dom/window_event_handlers.idl
index 186e1ad..ba91797 100644
--- a/src/cobalt/dom/window_event_handlers.idl
+++ b/src/cobalt/dom/window_event_handlers.idl
@@ -18,4 +18,6 @@
interface WindowEventHandlers {
attribute EventHandler onunload;
attribute EventHandler onbeforeunload;
+ attribute EventHandler onoffline;
+ attribute EventHandler ononline;
};
diff --git a/src/cobalt/extension/extension_test.cc b/src/cobalt/extension/extension_test.cc
index ef159a7..43b4925 100644
--- a/src/cobalt/extension/extension_test.cc
+++ b/src/cobalt/extension/extension_test.cc
@@ -22,6 +22,7 @@
#include "cobalt/extension/installation_manager.h"
#include "cobalt/extension/javascript_cache.h"
#include "cobalt/extension/media_session.h"
+#include "cobalt/extension/memory_mapped_file.h"
#include "cobalt/extension/platform_service.h"
#include "cobalt/extension/updater_notification.h"
#include "cobalt/extension/url_fetcher_observer.h"
@@ -328,5 +329,25 @@
<< "Extension struct should be a singleton";
}
+TEST(ExtensionTest, MemoryMappedFile) {
+ typedef CobaltExtensionMemoryMappedFileApi ExtensionApi;
+ const char* kExtensionName = kCobaltExtensionMemoryMappedFileName;
+
+ const ExtensionApi* extension_api =
+ static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
+ if (!extension_api) {
+ return;
+ }
+
+ EXPECT_STREQ(extension_api->name, kExtensionName);
+ EXPECT_EQ(extension_api->version, 1u);
+ EXPECT_NE(extension_api->MemoryMapFile, nullptr);
+
+ const ExtensionApi* second_extension_api =
+ static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
+ EXPECT_EQ(second_extension_api, extension_api)
+ << "Extension struct should be a singleton";
+}
+
} // namespace extension
} // namespace cobalt
diff --git a/src/cobalt/extension/memory_mapped_file.h b/src/cobalt/extension/memory_mapped_file.h
new file mode 100644
index 0000000..7c1c4bb
--- /dev/null
+++ b/src/cobalt/extension/memory_mapped_file.h
@@ -0,0 +1,58 @@
+// Copyright 2021 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_EXTENSION_MEMORY_MAPPED_FILE_H_
+#define COBALT_EXTENSION_MEMORY_MAPPED_FILE_H_
+
+#include <stdint.h>
+
+#include "starboard/memory.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define kCobaltExtensionMemoryMappedFileName \
+ "dev.cobalt.extension.MemoryMappedFile"
+
+typedef struct CobaltExtensionMemoryMappedFileApi {
+ // Name should be the string |kCobaltExtensionMemoryMappedFileName|.
+ // This helps to validate that the extension API is correct.
+ const char* name;
+
+ // This specifies the version of the API that is implemented.
+ uint32_t version;
+
+ // The fields below this point were added in version 1 or later.
+
+ // Memory maps a file at the specified |address| starting at |file_offset|
+ // and mapping |size| bytes. The |address| argument can be NULL in which
+ // case new memory buffer will be allocated. If a non NULL |address| is
+ // passed the memory should be resreved in advance through |SbMemoryMap|.
+ // To release the memory call |SbMemoryUnmap|.
+ // The |file_offset| must be a multiple of |kSbMemoryPageSize|.
+ // Returns NULL or error.
+ void* (*MemoryMapFile)(void* address, const char* path,
+ SbMemoryMapFlags flags, int64_t file_offset,
+ int64_t size);
+
+} CobaltExtensionMemoryMappedFileApi;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // COBALT_EXTENSION_MEMORY_MAPPED_FILE_H_
diff --git a/src/cobalt/h5vcc/dial/dial_http_response.cc b/src/cobalt/h5vcc/dial/dial_http_response.cc
index 6531a3e..3fcd329 100644
--- a/src/cobalt/h5vcc/dial/dial_http_response.cc
+++ b/src/cobalt/h5vcc/dial/dial_http_response.cc
@@ -13,6 +13,7 @@
// limitations under the License.
#include <memory>
+#include <utility>
#include "cobalt/h5vcc/dial/dial_http_response.h"
@@ -24,7 +25,7 @@
namespace dial {
DialHttpResponse::DialHttpResponse(const std::string& path,
const std::string& method)
- : path_(path), method_(method), response_code_(0) {}
+ : path_(path), method_(method), response_code_(500) {}
void DialHttpResponse::AddHeader(const std::string& header,
const std::string& value) {
diff --git a/src/cobalt/media/base/playback_statistics.cc b/src/cobalt/media/base/playback_statistics.cc
index b5001ec..30527b1 100644
--- a/src/cobalt/media/base/playback_statistics.cc
+++ b/src/cobalt/media/base/playback_statistics.cc
@@ -128,13 +128,16 @@
"", "The error message of the media pipeline error.") {}
PlaybackStatistics::~PlaybackStatistics() {
- SbAtomicNoBarrier_Increment(&s_active_instances, -1);
+ if (has_active_instance_) {
+ DCHECK(SbAtomicAcquire_Load(&s_active_instances) > 0);
+ SbAtomicNoBarrier_Increment(&s_active_instances, -1);
+ }
}
void PlaybackStatistics::UpdateVideoConfig(
const VideoDecoderConfig& video_config) {
- if (is_initial_config_) {
- is_initial_config_ = false;
+ if (!has_active_instance_) {
+ has_active_instance_ = true;
SbAtomicNoBarrier_Increment(&s_active_instances, 1);
diff --git a/src/cobalt/media/base/playback_statistics.h b/src/cobalt/media/base/playback_statistics.h
index 78808b3..7507b31 100644
--- a/src/cobalt/media/base/playback_statistics.h
+++ b/src/cobalt/media/base/playback_statistics.h
@@ -54,7 +54,7 @@
base::CVal<bool> is_video_eos_written_;
base::CVal<PipelineStatus> pipeline_status_;
base::CVal<std::string> error_message_;
- bool is_initial_config_ = true;
+ bool has_active_instance_ = false;
bool is_first_audio_buffer_written_ = false;
bool is_first_video_buffer_written_ = false;
};
diff --git a/src/cobalt/media/base/sbplayer_pipeline.cc b/src/cobalt/media/base/sbplayer_pipeline.cc
index 5a9b541..3fa6b43 100644
--- a/src/cobalt/media/base/sbplayer_pipeline.cc
+++ b/src/cobalt/media/base/sbplayer_pipeline.cc
@@ -904,7 +904,7 @@
// TODO: Check |suspended_| here as the pipeline can be suspended before the
// player is created. In this case we should delay creating the player as the
// creation of player may fail.
-
+ std::string error_message;
{
base::AutoLock auto_lock(lock_);
LOG(INFO) << "Creating StarboardPlayer with url: " << source_url;
@@ -916,6 +916,7 @@
SetPlaybackRateTask(playback_rate_);
SetVolumeTask(volume_);
} else {
+ error_message = player_->GetPlayerCreationErrorMessage();
player_.reset();
LOG(INFO) << "Failed to create a valid StarboardPlayer.";
}
@@ -933,8 +934,9 @@
}
CallSeekCB(DECODER_ERROR_NOT_SUPPORTED,
- "SbPlayerPipeline::CreateUrlPlayer failed: "
- "player_->IsValid() is false.");
+ "SbPlayerPipeline::CreateUrlPlayer failed to create a valid "
+ "StarboardPlayer:" +
+ (error_message.empty() ? "" : " Error: " + error_message));
}
void SbPlayerPipeline::SetDrmSystem(SbDrmSystem drm_system) {
@@ -990,6 +992,7 @@
video_stream_->video_decoder_config());
}
+ std::string error_message;
{
base::AutoLock auto_lock(lock_);
SB_DCHECK(!player_);
@@ -1008,6 +1011,7 @@
SetPlaybackRateTask(playback_rate_);
SetVolumeTask(volume_);
} else {
+ error_message = player_->GetPlayerCreationErrorMessage();
player_.reset();
LOG(INFO) << "Failed to create a valid StarboardPlayer.";
}
@@ -1032,8 +1036,9 @@
}
CallSeekCB(DECODER_ERROR_NOT_SUPPORTED,
- "SbPlayerPipeline::CreatePlayer failed: "
- "player_->IsValid() is false.");
+ "SbPlayerPipeline::CreatePlayer failed to create a valid "
+ "StarboardPlayer:" +
+ (error_message.empty() ? "" : " Error: " + error_message));
}
void SbPlayerPipeline::OnDemuxerInitialized(PipelineStatus status) {
diff --git a/src/cobalt/media/base/starboard_player.cc b/src/cobalt/media/base/starboard_player.cc
index 7d19612..47ad52b 100644
--- a/src/cobalt/media/base/starboard_player.cc
+++ b/src/cobalt/media/base/starboard_player.cc
@@ -554,6 +554,8 @@
bool has_audio = audio_codec != kSbMediaAudioCodecNone;
+ is_creating_player_ = true;
+
#if SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
SbPlayerCreationParam creation_param = {};
@@ -592,6 +594,8 @@
#endif // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
+ is_creating_player_ = false;
+
if (!SbPlayerIsValid(player_)) {
return;
}
@@ -856,6 +860,19 @@
}
}
+bool StarboardPlayer::TryToSetPlayerCreationErrorMessage(
+ const std::string& message) {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ if (is_creating_player_) {
+ player_creation_error_message_ = message;
+ return true;
+ }
+ LOG(INFO) << "TryToSetPlayerCreationErrorMessage() "
+ "is called when |is_creating_player_| "
+ "is false. Error message is ignored.";
+ return false;
+}
+
// static
void StarboardPlayer::DecoderStatusCB(SbPlayer player, void* context,
SbMediaType type,
@@ -880,6 +897,13 @@
void StarboardPlayer::PlayerErrorCB(SbPlayer player, void* context,
SbPlayerError error, const char* message) {
StarboardPlayer* helper = static_cast<StarboardPlayer*>(context);
+ if (player == kSbPlayerInvalid) {
+ // TODO: Simplify by combining the functionality of
+ // TryToSetPlayerCreationErrorMessage() with OnPlayerError().
+ if (helper->TryToSetPlayerCreationErrorMessage(message)) {
+ return;
+ }
+ }
helper->task_runner_->PostTask(
FROM_HERE, base::Bind(&StarboardPlayer::CallbackHelper::OnPlayerError,
helper->callback_helper_, player, error,
diff --git a/src/cobalt/media/base/starboard_player.h b/src/cobalt/media/base/starboard_player.h
index 588ca42..6e40ac4 100644
--- a/src/cobalt/media/base/starboard_player.h
+++ b/src/cobalt/media/base/starboard_player.h
@@ -118,6 +118,15 @@
// Need to be removed with media refactor.
void Resume(SbWindow window);
+ // These functions help the pipeline report an error message on a player
+ // creation error. TryToSetPlayerCreationErrorMessage() will set
+ // |player_creation_error_message_| and return true when called while
+ // |is_creating_player_| is true, else it will do nothing and return false.
+ bool TryToSetPlayerCreationErrorMessage(const std::string& message);
+ std::string GetPlayerCreationErrorMessage() const {
+ return player_creation_error_message_;
+ }
+
SbDecodeTarget GetCurrentSbDecodeTarget();
SbPlayerOutputMode GetSbPlayerOutputMode();
@@ -256,6 +265,10 @@
// A string of video maximum capabilities.
std::string max_video_capabilities_;
+ // Keep track of errors during player creation.
+ bool is_creating_player_ = false;
+ std::string player_creation_error_message_;
+
#if SB_HAS(PLAYER_WITH_URL)
const bool is_url_based_;
#endif // SB_HAS(PLAYER_WITH_URL)
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontConfigParser_cobalt.cc b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontConfigParser_cobalt.cc
index 4890e72..67fe50a 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontConfigParser_cobalt.cc
+++ b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontConfigParser_cobalt.cc
@@ -324,6 +324,10 @@
LOG(ERROR) << "---- Invalid fallback priority [" << value << "]";
NOTREACHED();
}
+ } else if (name_len == 15 &&
+ strncmp("disable_caching", name, name_len) == 0) {
+ family->disable_caching =
+ strcmp("true", value) == 0 || strcmp("1", value) == 0;
} else {
LOG(ERROR) << "---- Unsupported family attribute [" << name << "]";
NOTREACHED();
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.cc b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.cc
index 8d92c16..6862a5e 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.cc
+++ b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.cc
@@ -91,6 +91,7 @@
}
character_map_ = base::MakeRefCounted<font_character_map::CharacterMap>();
+ disable_character_map_ = family_info.disable_caching;
family_name_ = family_info.names[0];
SkTHashMap<SkString, int> styles_index_map;
@@ -392,10 +393,12 @@
<< "(" << style_entry->font_style.weight() << ", "
<< style_entry->font_style.width() << ", "
<< style_entry->font_style.slant() << ")";
+ scoped_refptr<font_character_map::CharacterMap> map =
+ disable_character_map_ ? NULL : character_map_;
style_entry->typeface.reset(new SkTypeface_CobaltStreamProvider(
stream_provider, style_entry->face_index, style_entry->font_style,
style_entry->face_is_fixed_pitch, family_name_,
- style_entry->disable_synthetic_bolding, character_map_));
+ style_entry->disable_synthetic_bolding, map));
} else {
LOG(ERROR) << "Failed to scan font: "
<< style_entry->font_file_path.c_str();
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.h b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.h
index 33ec970..774a90f 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.h
+++ b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.h
@@ -135,6 +135,9 @@
SkLanguage language_;
font_character_map::PageRanges page_ranges_;
+ // Used when the styles in the styleset have different character mappings.
+ bool disable_character_map_;
+
// NOTE: The following characters require locking when being accessed.
bool is_character_map_generated_;
scoped_refptr<font_character_map::CharacterMap> character_map_;
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontUtil_cobalt.h b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontUtil_cobalt.h
index 422276c..6314e5a 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontUtil_cobalt.h
+++ b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontUtil_cobalt.h
@@ -164,7 +164,8 @@
// determine that a family cannot support a character, without needing to
// generate a full mapping of the family's characters.
struct FontFamilyInfo {
- FontFamilyInfo() : is_fallback_family(true), fallback_priority(0) {}
+ FontFamilyInfo()
+ : is_fallback_family(true), fallback_priority(0), disable_caching(0) {}
SkTArray<SkString> names;
SkTArray<FontFileInfo> fonts;
@@ -172,6 +173,7 @@
bool is_fallback_family;
int fallback_priority;
font_character_map::PageRanges page_ranges;
+ bool disable_caching;
};
#endif // COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_PORTS_SKFONTUTIL_COBALT_H_
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.cc b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.cc
index 8f9cce8..a116c2c 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.cc
+++ b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.cc
@@ -13,6 +13,7 @@
// limitations under the License.
#include <memory>
+#include <utility>
#include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.h"
@@ -44,16 +45,18 @@
SkGlyphID SkTypeface_Cobalt::characterMapGetGlyphIdForCharacter(
SkUnichar character) const {
- CHECK(character_map_);
-
- // Check whether the character is cached in the character map.
- font_character_map::Character c = character_map_->Find(character);
- if (c.is_set) return c.id;
+ if (character_map_) {
+ // Check whether the character is cached in the character map.
+ font_character_map::Character c = character_map_->Find(character);
+ if (c.is_set) return c.id;
+ }
// If the character isn't there, look it up with FreeType, then cache it.
SkGlyphID glyphs[1] = {0};
SkTypeface_FreeType::onCharsToGlyphs(&character, 1, glyphs);
- character_map_->Insert(character, glyphs[0]);
+ if (character_map_) {
+ character_map_->Insert(character, glyphs[0]);
+ }
return glyphs[0];
}
@@ -119,7 +122,6 @@
*face_index = face_index_;
return std::unique_ptr<SkFileMemoryChunkStream>(
stream_provider_->OpenStream());
- ;
}
size_t SkTypeface_CobaltStreamProvider::GetStreamLength() const {
diff --git a/src/cobalt/site/docs/codelabs/cobalt_extensions/codelab.md b/src/cobalt/site/docs/codelabs/cobalt_extensions/codelab.md
new file mode 100644
index 0000000..8fc180c
--- /dev/null
+++ b/src/cobalt/site/docs/codelabs/cobalt_extensions/codelab.md
@@ -0,0 +1,793 @@
+---
+layout: doc
+title: "Cobalt Extensions codelab"
+---
+
+The Cobalt Extension framework provides a way to add optional, platform-specific
+features to the Cobalt application. A Cobalt Extension is an optional interface
+that porters can implement for their platforms if, and as, they wish.
+
+This tutorial uses coding exercises to guide you through the process of creating
+a simple example of a Cobalt Extension. By the end you should have a firm
+understanding of what Cobalt Extensions are, when to use them instead of
+alternatives, how to write them, and how to work with the Cobalt team to
+contribute them to the repository.
+
+## Prerequisites
+
+Because it's helpful to build and run Cobalt during the exercises, you'll first
+want to set up your environment and make sure you can build Cobalt. You can
+follow <a href="/development/setup-linux.html">Set up your environment -
+Linux</a> to do this if you're a Linux user. Please note that the exercise
+solutions assume you're using Linux but should be comparable to implementations
+for other platforms.
+
+Also note that while this codelab doesn't require it, you'll need to
+<a href="/starboard/porting.html">Port Cobalt to your platform</a> before you
+can actually use a Cobalt Extension to customize it for your platform.
+
+Finally, the exercises assume the ability to program in C and C++.
+
+### Exercise 0: Run Cobalt and inspect logs
+
+Assuming you've already built Cobalt, please now run Cobalt and pay special
+attention to a message it logs when it starts up. This message will be the focus
+of subsequent exercises.
+
+```
+$ out/linux-x64x11_debug/cobalt 2>/dev/null | grep "Starting application"
+```
+
+## Background
+
+Situated below Cobalt is Starboard. Starboard, which is a porting layer and OS
+abstraction, contains a minimal set of APIs to encapsulate the platform-specific
+functionalities that Cobalt uses. Each Starboard module (memory, socket, thread,
+etc.) defines functions that must be implemented on a porter's platform,
+imposing an implementation and maintenance cost on all porters. With this cost
+in mind the Cobalt team tries to keep the Starboard APIs stable and only adds a
+new API **when some functionality is required by Cobalt but the implementation
+depends on the platform**.
+
+A Starboard API can be made optional, though, by the introduction of an
+accompanying API that asks platforms whether they support the underlying feature
+and enables Cobalt to check for the answer at runtime. For example,
+`SbWindowOnScreenKeyboardIsSupported` is used so that only platforms that
+support an on screen keyboard need implement the related functions in
+`starboard/window.h`. To spare porters uninterested in the functionality, the
+Cobalt team chooses to make a Starboard API optional **when some Cobalt
+functionality is optional and the implementation is platform-dependent**.
+
+Finally, a nonobvious point explains why even an optional Starboard API may
+sometimes be too cumbersome: other applications beyond Cobalt are able to be run
+on top of Starboard. If a feature is needed by Cobalt but not by all Starboard-
+based applications or by Starboard itself, adding a Starboard API for it may add
+unnecessary size and complexity to the porting layer. **And here we arrive at
+the sweet spot for Cobalt Extensions: when the desired functionality is
+Cobalt-specific, optional in Cobalt, and has platform-dependent
+implementation.** Also, because Cobalt Extensions are lightweight and, as you'll
+see below, added without any changes to the Starboard layer, they're the
+preferred way for porters to add new, custom features to Cobalt.
+
+To summarize:
+
+<table>
+ <tr>
+ <th colspan="1">Tool</th>
+ <th colspan="1">Use case</th>
+ <th colspan="1">Ecosystem cost</th>
+ </tr>
+ <tr>
+ <td>Starboard API</td>
+ <td>Feature is <strong>required</strong> but implementation is
+ platform-dependent</td>
+ <td>High</td>
+ </tr>
+ <tr>
+ <td>Optional Starboard API</td>
+ <td>Feature is <strong>optional</strong> and implementation is
+ platform-dependent</td>
+ <td>Medium</td>
+ </tr>
+ <tr>
+ <td>Cobalt Extension</td>
+ <td>Feature is <strong>optional and specific to Cobalt</strong> and
+ implementation is platform-dependent</td>
+ <td>Low</td>
+ </tr>
+</table>
+
+As a caveat, please note that for all three of these abstractions the interface
+is in Cobalt's open-source repository and therefore visible to other porters.
+The implementation, on the other hand, is written and built by porters and so
+may be kept private.
+
+Finally, in addition to the alternatives mentioned, porters have in some cases
+made local changes to Cobalt, above the Starboard layer, to achieve some
+customization or optimization. This has been discouraged by the Cobalt team
+because it makes rebasing to future versions of Cobalt more difficult but has
+been possible because porters have historically built **both** Cobalt and
+Starboard. However, Cobalt is moving toward Evergreen
+(<a href="https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/starboard/doc/evergreen/cobalt_evergreen_overview.md">overview</a>),
+an architecture that enables automatic Cobalt updates on devices by separating a
+Google-built, Cobalt core shared library from the partner-built Starboard layer
+and Cobalt loader app. Because Cobalt core code is built by Google, custom
+changes to it are no longer possible for partners using Evergreen.
+
+## Anatomy of a Cobalt Extension
+
+### Extension structures
+
+Cobalt uses a structure to describe the interface for an extension and organizes
+the structures in headers under `cobalt/extension/`. The header for a "foo"
+extension should be named `foo.h` and the first version of it should contain the
+following content, as well as any additional members that provide the "foo"
+functionality.
+
+```
+#ifndef COBALT_EXTENSION_FOO_H_
+#define COBALT_EXTENSION_FOO_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define kCobaltExtensionFooName "dev.cobalt.extension.Foo"
+
+typedef struct CobaltExtensionFooApi {
+ // Name should be the string |kCobaltExtensionFooName|.
+ // This helps to validate that the extension API is correct.
+ const char* name;
+
+ // This specifies the version of the API that is implemented.
+ uint32_t version;
+
+ // The fields below this point were added in version 1 or later.
+
+} CobaltExtensionFooApi;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // COBALT_EXTENSION_FOO_H_
+```
+
+Please note a few important points about this structure:
+
+* The first two members must be, in order:
+ * A `const char* |name|`, storing the extension's name.
+ * A `uint32_t |version|`, storing the version number of the extension.
+ Extension versioning is discussed later on in this codelab.
+* The following members can be any C types (including custom structures) that
+ are useful. Often, these are function pointers.
+
+### Extension access in Cobalt
+
+The `SbSystemGetExtension` function from Starboard's `system` module allows
+Cobalt to query for an extension by name. It returns a pointer to the constant,
+global instance of the structure implementing the extension with the given name
+if it exists, otherwise `NULL`. This function is the only mechanism Cobalt has
+to get an extension; the Starboard interface intentionally doesn't have any
+functions related to the specific extensions.
+
+The caller in Cobalt must static cast the `const void*` returned by
+`SbSystemGetExtension` to a `const CobaltExtensionFooApi*`, or pointer of
+whatever type the extension structure type happens to be, before using it. Since
+the caller can't be sure whether a platform implements the extension or, if it
+does, implements it correctly, it's good defensive programming to check that the
+resulting pointer is not `NULL` and that the `name` member in the pointed-to
+structure has the same value as `kCobaltExtensionFooName`.
+
+### Extension implementation
+
+Because Cobalt Extensions are platform-dependent, the implementations of an
+extension belong in Starboard ports. A Starboard port implements an extension by
+defining a constant, global instance of the structure and implementing the
+`SbSystemGetExtension` function to return a pointer to it. For our "foo"
+extension, an implementation for `custom_platform`'s Starboard port could look
+as follows.
+
+`starboard/custom_platform/foo.h` declares a `GetFooApi` accessor for the
+structure instance.
+
+```
+#ifndef STARBOARD_CUSTOM_PLATFORM_FOO_H_
+#define STARBOARD_CUSTOM_PLATFORM_FOO_H_
+
+namespace starboard {
+namespace custom_platform {
+
+const void* GetFooApi();
+
+} // namespace custom_platform
+} // namespace starboard
+
+#endif // STARBOARD_CUSTOM_PLATFORM_FOO_H_
+```
+
+`starboard/custom_platform/foo.cc`, then, defines `GetFooApi`.
+
+```
+#include "starboard/custom_platform/foo.h"
+
+#include "cobalt/extension/foo.h"
+
+namespace starboard {
+namespace custom_platform {
+
+namespace {
+
+// Definitions of any functions included as components in the extension
+// are added here.
+
+const CobaltExtensionFooApi kFooApi = {
+ kCobaltExtensionFooName,
+ 1, // API version that's implemented.
+ // Any additional members are initialized here.
+};
+
+} // namespace
+
+const void* GetFooApi() {
+ return &kFooApi;
+}
+
+} // namespace custom_platform
+} // namespace starboard
+```
+
+Finally, `starboard/custom_platform/system_get_extension.cc` defines
+`SbSystemGetExtension` to wire up the extensions for the platform.
+
+```
+#include "starboard/system.h"
+
+#include "cobalt/extension/foo.h"
+#include "starboard/common/string.h"
+#include "starboard/custom_platform/foo.h"
+
+const void* SbSystemGetExtension(const char* name) {
+ if (strcmp(name, kCobaltExtensionFooName) == 0) {
+ return starboard::custom_platform::GetFooApi();
+ }
+ // Other conditions here should handle other implemented extensions.
+
+ return NULL;
+}
+```
+
+Please feel free to browse existing extension implementations in the repository.
+For example, the reference Raspberry Pi port implements the `Graphics` extension
+across the following files.
+
+* `starboard/raspi/shared/graphics.h`
+* `starboard/raspi/shared/graphics.cc`
+* `starboard/raspi/shared/system_get_extensions.cc`
+
+### Exercise 1: Write and use your first extension
+
+Now that you've seen the anatomy of a Cobalt Extension it's your turn to write
+one of your own. In Exercise 0 we saw that Cobalt logs "Starting application"
+when it's started. Please write a `Pleasantry` Cobalt Extension that has a
+member of type `const char*` and name `greeting` and make any necessary changes
+in `cobalt/browser/main.cc` so that the extension can be used to log a custom
+greeting directly after the plain "Starting application." Implement the
+extension for Linux, or whichever other platform you'd like, and confirm that
+the greeting is logged.
+
+#### Solution to Exercise 1
+
+Click the items below to expand parts of a solution. The `git diff`s are between
+the solution and the `master` branch.
+
+<details>
+ <summary style="display:list-item">Contents of new
+ `cobalt/extension/pleasantry.h` file.</summary>
+
+```
+#ifndef COBALT_EXTENSION_PLEASANTRY_H_
+#define COBALT_EXTENSION_PLEASANTRY_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define kCobaltExtensionPleasantryName "dev.cobalt.extension.Pleasantry"
+
+typedef struct CobaltExtensionPleasantryApi {
+ // Name should be the string |kCobaltExtensionPleasantryName|.
+ // This helps to validate that the extension API is correct.
+ const char* name;
+
+ // This specifies the version of the API that is implemented.
+ uint32_t version;
+
+ // The fields below this point were added in version 1 or later.
+ const char* greeting;
+
+} CobaltExtensionPleasantryApi;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // COBALT_EXTENSION_PLEASANTRY_H_
+```
+
+</details>
+
+<details>
+ <summary style="display:list-item">Contents of new
+ `starboard/linux/shared/pleasantry.h` file.</summary>
+
+```
+#ifndef STARBOARD_LINUX_SHARED_PLEASANTRY_H_
+#define STARBOARD_LINUX_SHARED_PLEASANTRY_H_
+
+namespace starboard {
+namespace shared {
+
+const void* GetPleasantryApi();
+
+} // namespace shared
+} // namespace starboard
+
+#endif // STARBOARD_LINUX_SHARED_PLEASANTRY_H_
+```
+
+</details>
+
+<details>
+ <summary style="display:list-item">Contents of new
+ `starboard/linux/shared/pleasantry.cc` file.</summary>
+
+```
+#include "starboard/linux/shared/pleasantry.h"
+
+#include "cobalt/extension/pleasantry.h"
+
+namespace starboard {
+namespace shared {
+
+namespace {
+
+const char *kGreeting = "Happy debugging!";
+
+const CobaltExtensionPleasantryApi kPleasantryApi = {
+ kCobaltExtensionPleasantryName,
+ 1,
+ kGreeting,
+};
+
+} // namespace
+
+const void* GetPleasantryApi() {
+ return &kPleasantryApi;
+}
+
+} // namespace shared
+} // namespace starboard
+```
+
+</details>
+
+<details>
+ <summary style="display:list-item">`git diff
+ starboard/linux/shared/starboard_platform.gypi`</summary>
+
+```
+@@ -38,6 +38,8 @@
+ '<(DEPTH)/starboard/linux/shared/netlink.cc',
+ '<(DEPTH)/starboard/linux/shared/netlink.h',
+ '<(DEPTH)/starboard/linux/shared/player_components_factory.cc',
++ '<(DEPTH)/starboard/linux/shared/pleasantry.cc',
++ '<(DEPTH)/starboard/linux/shared/pleasantry.h',
+ '<(DEPTH)/starboard/linux/shared/routes.cc',
+ '<(DEPTH)/starboard/linux/shared/routes.h',
+ '<(DEPTH)/starboard/linux/shared/system_get_connection_type.cc',
+```
+
+</details>
+
+<details>
+ <summary style="display:list-item">`git diff
+ starboard/linux/shared/system_get_extensions.cc`</summary>
+
+```
+@@ -16,12 +16,14 @@
+
+ #include "cobalt/extension/configuration.h"
+ #include "cobalt/extension/crash_handler.h"
++#include "cobalt/extension/pleasantry.h"
+ #include "starboard/common/string.h"
+ #include "starboard/shared/starboard/crash_handler.h"
+ #if SB_IS(EVERGREEN_COMPATIBLE)
+ #include "starboard/elf_loader/evergreen_config.h"
+ #endif
+ #include "starboard/linux/shared/configuration.h"
++#include "starboard/linux/shared/pleasantry.h"
+
+ const void* SbSystemGetExtension(const char* name) {
+ #if SB_IS(EVERGREEN_COMPATIBLE)
+@@ -41,5 +43,8 @@ const void* SbSystemGetExtension(const char* name) {
+ if (strcmp(name, kCobaltExtensionCrashHandlerName) == 0) {
+ return starboard::common::GetCrashHandlerApi();
+ }
++ if (strcmp(name, kCobaltExtensionPleasantryName) == 0) {
++ return starboard::shared::GetPleasantryApi();
++ }
+ return NULL;
+ }
+```
+
+</details>
+
+<details>
+ <summary style="display:list-item">`git diff cobalt/browser/main.cc`
+ </summary>
+
+```
+@@ -18,7 +18,9 @@
+ #include "cobalt/base/wrap_main.h"
+ #include "cobalt/browser/application.h"
+ #include "cobalt/browser/switches.h"
++#include "cobalt/extension/pleasantry.h"
+ #include "cobalt/version.h"
++#include "starboard/system.h"
+
+ namespace {
+
+@@ -77,6 +79,14 @@ void StartApplication(int argc, char** argv, const char* link,
+ return;
+ }
+ LOG(INFO) << "Starting application.";
++ const CobaltExtensionPleasantryApi* pleasantry_extension =
++ static_cast<const CobaltExtensionPleasantryApi*>(
++ SbSystemGetExtension(kCobaltExtensionPleasantryName));
++ if (pleasantry_extension &&
++ strcmp(pleasantry_extension->name, kCobaltExtensionPleasantryName) == 0 &&
++ pleasantry_extension->version >= 1) {
++ LOG(INFO) << pleasantry_extension->greeting;
++ }
+ #if SB_API_VERSION >= 13
+ DCHECK(!g_application);
+ g_application = new cobalt::browser::Application(quit_closure,
+```
+
+</details>
+
+## Extension versioning
+
+Cobalt Extensions are themselves extensible, but care must be taken to ensure
+that the extension interface in Cobalt and implementation in a platform's port,
+which may be built separately, are consistent.
+
+The `version` member, which is always the second member in an extension
+structure, indicates which version of the interface the structure describes. In
+other words, a `version` of the extension structure corresponds to a specific,
+invariant list of members. By convention, the first version of a Cobalt
+Extension is version `1` (i.e., one-based indexing, not zero-based).
+
+A new version of the extension can be introduced in the structure declaration by
+adding additional members to the end of the declaration and adding a comment to
+delineate, e.g., "The fields below this point were added in version 2 or later."
+To maintain compatibility and enable Cobalt to correctly index into instances of
+the structure, it's important that members are always added at the end of the
+structure declaration and that members are never removed. If a member is
+deprecated in a later version, this fact should simply be noted with a comment
+in the structure declaration.
+
+To implement a new version of the extension, a platform's port should then set
+the `version` member to the appropriate value when creating the instance of the
+structure, and also initialize all members required for the version.
+
+Finally, any code in Cobalt that uses the extension should guard references to
+members with version checks.
+
+### Exercise 2: Version your extension
+
+Add a second version of the `Pleasantry` extension that enables porters to also
+log a polite farewell message when the Cobalt application is stopped. To allow
+platforms more flexibility, add the new `farewell` member as a pointer to a
+function that takes no parameters and returns a `const char*`. Update
+`cobalt/browser/main.cc` so that Cobalt, if the platform implements version 2 of
+this extension, replaces the "Stopping application." message with a polite
+farewell provided by the platform.
+
+To keep things interesting, have the platform's implementation pseudo-randomly
+return one of several messages. And, once you've made the changes, build Cobalt
+and run it a few times to confirm that the feature behaves as expected.
+
+#### Solution to Exercise 2
+
+Click the items below to expand parts of a solution. The `git diff` is between
+the solution and the `master` branch.
+
+<details>
+ <summary style="display:list-item">Updated contents of
+ `cobalt/extension/pleasantry.h`.</summary>
+
+```
+#ifndef COBALT_EXTENSION_PLEASANTRY_H_
+#define COBALT_EXTENSION_PLEASANTRY_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define kCobaltExtensionPleasantryName "dev.cobalt.extension.Pleasantry"
+
+typedef struct CobaltExtensionPleasantryApi {
+ // Name should be the string |kCobaltExtensionPleasantryName|.
+ // This helps to validate that the extension API is correct.
+ const char* name;
+
+ // This specifies the version of the API that is implemented.
+ uint32_t version;
+
+ // The fields below this point were added in version 1 or later.
+ const char* greeting;
+
+ // The fields below this point were added in version 2 or later.
+ const char* (*GetFarewell)();
+
+} CobaltExtensionPleasantryApi;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // COBALT_EXTENSION_PLEASANTRY_H_
+```
+
+</details>
+
+<details>
+ <summary style="display:list-item">Updated contents of
+ `starboard/linux/shared/pleasantry.cc`.</summary>
+
+```
+#include "starboard/linux/shared/pleasantry.h"
+
+#include <stdlib.h>
+
+#include "cobalt/extension/pleasantry.h"
+#include "starboard/system.h"
+#include "starboard/time.h"
+
+namespace starboard {
+namespace shared {
+
+namespace {
+
+const char* kGreeting = "Happy debugging!";
+
+const char* kFarewells[] = {
+ "Farewell",
+ "Take care",
+ "Thanks for running Cobalt",
+};
+
+const char* GetFarewell() {
+ srand (SbTimeGetNow());
+ int pseudo_random_index = rand() % SB_ARRAY_SIZE_INT(kFarewells);
+ return kFarewells[pseudo_random_index];
+}
+
+const CobaltExtensionPleasantryApi kPleasantryApi = {
+ kCobaltExtensionPleasantryName,
+ 2,
+ kGreeting,
+ &GetFarewell,
+};
+
+} // namespace
+
+const void* GetPleasantryApi() {
+ return &kPleasantryApi;
+}
+
+} // namespace shared
+} // namespace starboard
+```
+
+</details>
+
+<details>
+ <summary style="display:list-item">`git diff cobalt/browser/main.cc`
+ </summary>
+
+```
+@@ -18,7 +18,9 @@
+ #include "cobalt/base/wrap_main.h"
+ #include "cobalt/browser/application.h"
+ #include "cobalt/browser/switches.h"
++#include "cobalt/extension/pleasantry.h"
+ #include "cobalt/version.h"
++#include "starboard/system.h"
+
+ namespace {
+
+@@ -54,6 +56,14 @@ bool CheckForAndExecuteStartupSwitches() {
+ return g_is_startup_switch_set;
+ }
+
++// Get the Pleasantry extension if it's implemented.
++const CobaltExtensionPleasantryApi* GetPleasantryApi() {
++ static const CobaltExtensionPleasantryApi* pleasantry_extension =
++ static_cast<const CobaltExtensionPleasantryApi*>(
++ SbSystemGetExtension(kCobaltExtensionPleasantryName));
++ return pleasantry_extension;
++}
++
+ void PreloadApplication(int argc, char** argv, const char* link,
+ const base::Closure& quit_closure,
+ SbTimeMonotonic timestamp) {
+@@ -77,6 +87,12 @@ void StartApplication(int argc, char** argv, const char* link,
+ return;
+ }
+ LOG(INFO) << "Starting application.";
++ const CobaltExtensionPleasantryApi* pleasantry_extension = GetPleasantryApi();
++ if (pleasantry_extension &&
++ strcmp(pleasantry_extension->name, kCobaltExtensionPleasantryName) == 0 &&
++ pleasantry_extension->version >= 1) {
++ LOG(INFO) << pleasantry_extension->greeting;
++ }
+ #if SB_API_VERSION >= 13
+ DCHECK(!g_application);
+ g_application = new cobalt::browser::Application(quit_closure,
+@@ -96,7 +112,14 @@ void StartApplication(int argc, char** argv, const char* link,
+ }
+
+ void StopApplication() {
+- LOG(INFO) << "Stopping application.";
++ const CobaltExtensionPleasantryApi* pleasantry_extension = GetPleasantryApi();
++ if (pleasantry_extension &&
++ strcmp(pleasantry_extension->name, kCobaltExtensionPleasantryName) == 0 &&
++ pleasantry_extension->version >= 2) {
++ LOG(INFO) << pleasantry_extension->GetFarewell();
++ } else {
++ LOG(INFO) << "Stopping application.";
++ }
+ delete g_application;
+ g_application = NULL;
+ }
+```
+
+</details>
+
+`starboard/linux/shared/pleasantry.h`,
+`starboard/linux/shared/starboard_platform.gypi`, and
+`starboard/linux/shared/system_get_extensions.cc` should be unchanged from the
+Exercise 1 solution.
+
+## Extension testing
+
+Each Cobalt Extension has a test in `cobalt/extension/extension_test.cc` that
+tests whether the extension is wired up correctly for the platform Cobalt
+happens to be built for.
+
+Since some platforms may not implement a particular extension, these tests begin
+by checking whether `SbSystemGetExtension` simply returns `NULL` for the
+extension's name. For our `foo` extension, the first few lines may contain the
+following.
+
+```
+TEST(ExtensionTest, Foo) {
+ typedef CobaltExtensionFooApi ExtensionApi;
+ const char* kExtensionName = kCobaltExtensionFooName;
+
+ const ExtensionApi* extension_api =
+ static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
+ if (!extension_api) {
+ return;
+ }
+
+ // Verifications about the global structure instance, if implemented.
+}
+```
+
+If `SbSystemGetExtension` does not return `NULL`, meaning the platform does
+implement the extension, the tests generally verify a few details about the
+structure:
+
+* It has the expected name.
+* Its version is in the range of possible versions for the extension.
+* For whichever version is implemented, any members required for that version
+ are present.
+* It's a singleton.
+
+### Exercise 3: Test your extension
+
+You guessed it! Add a test for your new extension to
+`cobalt/extension/extension_test.cc`.
+
+Once you've written your test you can execute it to confirm that it passes.
+`cobalt/extension/extension.gyp` configures an `extension_test` target to be
+built from our `extension_test.cc` source file. We can build that target for our
+platform and then run the executable to run the tests.
+
+```
+$ cobalt/build/gyp_cobalt linux-x64x11
+```
+
+```
+$ ninja -C out/linux-x64x11_devel all
+```
+
+```
+$ out/linux-x64x11_devel/extension_test
+```
+
+Tip: because the `extension_test` has type `<(gtest_target_type)`, we can use
+`--gtest_filter` to filter the tests that are run. For example, you can run just
+your newly added test with `--gtest_filter=ExtensionTest.Pleasantry`.
+
+#### Solution to Exercise 3
+
+<details>
+ <summary style="display:list-item">Click here to see a solution for the new
+ test.</summary>
+
+```
+TEST(ExtensionTest, Pleasantry) {
+ typedef CobaltExtensionPleasantryApi ExtensionApi;
+ const char* kExtensionName = kCobaltExtensionPleasantryName;
+
+ const ExtensionApi* extension_api =
+ static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
+ if (!extension_api) {
+ return;
+ }
+
+ EXPECT_STREQ(extension_api->name, kExtensionName);
+ EXPECT_GE(extension_api->version, 1u);
+ EXPECT_LE(extension_api->version, 2u);
+
+ EXPECT_NE(extension_api->greeting, nullptr);
+
+ if (extension_api->version >= 2) {
+ EXPECT_NE(extension_api->GetFarewell, nullptr);
+ }
+
+ const ExtensionApi* second_extension_api =
+ static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
+ EXPECT_EQ(second_extension_api, extension_api)
+ << "Extension struct should be a singleton";
+}
+```
+
+</details>
+
+You'll also want to include the header for the extension, i.e., `#include
+"cobalt/extension/pleasantry.h"`.
+
+## Contributing a Cobalt Extension
+
+Thanks for taking the time to complete the codelab!
+
+**If you'd like to contribute an actual Cobalt Extension to Cobalt in order to
+add some useful functionality for your platform, we encourage you to start a
+discussion with the Cobalt team before you begin coding.** To do so, please
+[file a feature request](https://issuetracker.google.com/issues/new?component=181120)
+for the extension and include the following information:
+
+* The name of the Cobalt Extension.
+* A description of the extension.
+* Why a Cobalt Extension is the right tool, instead of some alternative.
+* The fact that you'd like to contribute the extension (i.e., write the code)
+ rather than rely on the Cobalt team to prioritize, plan, and implement it.
+
+Please file this feature request with the appropriate priority and the Cobalt
+team will review the proposal accordingly. If the Cobalt team approves of the
+use case and design then a member of the team will assign the feature request
+back to you for implementation. At this point, please follow the
+<a href="/contributors/index.html">Contributing to Cobalt</a> guide to ensure
+your code is compliant and can be reviewed and submitted.
diff --git a/src/cobalt/site/docs/development/setup-linux.md b/src/cobalt/site/docs/development/setup-linux.md
index 9e40a3e..014394d 100644
--- a/src/cobalt/site/docs/development/setup-linux.md
+++ b/src/cobalt/site/docs/development/setup-linux.md
@@ -63,8 +63,8 @@
```
$ cd cobalt
-$ git mv src/* ./
-$ git mv src/.* ./
+$ mv src/* ./
+$ mv src/.* ./
```
Once you do that, you'll be able to follow the following two steps to have C++
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/branching.md b/src/cobalt/site/docs/gen/cobalt/doc/branching.md
new file mode 100644
index 0000000..c3b9cd9
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/branching.md
@@ -0,0 +1,98 @@
+---
+layout: doc
+title: "Cobalt Branching"
+---
+# Cobalt Branching
+
+*(This document assumes you are already familiar
+with [Cobalt Versioning][versioning] practices.)*
+
+The Cobalt project uses git branches for two main purposes:
+
+ 1. To solidify a release as it is hardened for production.
+ 2. To isolate `master` branch developers from risky or disruptive work.
+
+
+## Release Branches
+
+A "Cobalt release" is an official, tested version of Cobalt that is intended to
+be deployable to production. We branch for releases to allow development to
+continue on the `master` branch while stabilizing and finalizing a set of sources
+for release.
+
+
+### Release Timeline
+
+ 1. Feature work is done in the `master` branch.
+
+ 2. Once all feature work is completed, a release branch is created. The branch
+ will be named "[[Feature Year](versioning.md#Feature-Year)].[[Purpose](versioning.md#Purpose)].[[Update Number](versioning.md#Update-Number)]+".
+ Note that while very similar to the structure of the Cobalt
+ [version](versioning.md), it features a `+` symbol at the end, indicating
+ that the branch may eventually contain multiple release updates,
+ all greater than or equal to the specified update number. In particular, a
+ single branch may host multiple releases/updates. Should another release
+ branch be cut from master with a pre-existing (feature year, purpose)
+ pair, the new branch will have an update number equivalent to the most
+ recently released update number, plus one. Note that we expect it to be
+ rare that we will need a branch other than the `1+` branch.
+
+ An example release branch name is `19.lts.1+`.
+
+ An RC announcement will be made to
+ [cobalt-dev@googlegroups.com][cobalt-dev].
+
+ Note that a release branch implies that code on that branch is being
+ stabilized, not that it is ready for release. Versions of Cobalt that
+ are ready for release will have a dedicated `*.stable` branch pointing to
+ them, and will be discussed later.
+
+ 3. As bugs are discovered and feedback received from partners, fixes will be
+ cherry-picked into the release candidate branch. These cherry-picks should
+ not be considered stable again until the `*.stable` branch is updated.
+
+ 4. As time goes on, the number of cherry-picks will decrease in number and
+ scope.
+
+ 5. Once a commit on the branch is deemed to be feature-complete and stable, it
+ will be tagged with the current [version](versioning.md) for that branch,
+ and the version will be incremented for all subsequent commits. A special
+ branch that acts more like a "moving tag" named "[[Feature Year](versioning.md#Feature-Year)].[[Purpose](versioning.md#Purpose)].stable"
+ will be created to point to the newly released version. Should a
+ subsequent update be made for the given feature year and purpose, the
+ `*.stable` branch will be updated to point to the newest update.
+
+ An example stable branch name is `19.lts.stable`.
+
+ Some example release tags are:
+ - `19.lts.1`
+ - `19.lts.2`
+ - `20.lts.1`
+
+ A release announcement will be made
+ to [cobalt-dev@googlegroups.com][cobalt-dev].
+
+
+## Work Branches
+
+If a set of work is deemed to be particularly risky or disruptive, or if a
+serious contributor wants a sandbox to prepare an extensive patch, a work branch
+may be created to facilitate such development.
+
+Work branch names are of the form `work_<topic>`, where `<topic>` is the purpose
+for which the branch was created. Work branches are generally in use by a
+specific and limited set of people, and may disappear at any time.
+
+
+## Older branching schemes
+
+Older branches have been following different branch naming schemes, and for
+a description of those schemes, the version of this branching.md file within
+those branches should be consulted.
+
+## Other Reading
+
+ * [Cobalt Versioning][versioning]
+
+[cobalt-dev]: https://groups.google.com/forum/#!forum/cobalt-dev "cobalt-dev@googlegroups.com"
+[versioning]: versioning.md "Cobalt Versioning"
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/clients_performance_guide.md b/src/cobalt/site/docs/gen/cobalt/doc/clients_performance_guide.md
new file mode 100644
index 0000000..29c3984
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/clients_performance_guide.md
@@ -0,0 +1,172 @@
+---
+layout: doc
+title: "Cobalt Clients Performance Guide"
+---
+# Cobalt Clients Performance Guide
+
+This document contains a list of hints and tricks for using web technologies
+that when employed will result in improved performance of Cobalt client apps.
+
+[TOC]
+
+## Avoid large opacity animations of DOM subtrees.
+
+Be careful when applying the CSS opacity property to DOM subtrees. When
+applying opacity to a DOM leaf node, the renderer can usually easily render the
+single element the way it normally would, except with an opacity parameter set.
+When rendering a non-trivial multi-subnode DOM subtree though, in order for
+the results to appear correct, the renderer has no choice but to create an
+offscreen surface, render to that surface *without* opacity, and then finally
+render the offscreen surface onto the onscreen surface *with* the set opacity
+applied.
+
+For some examples, suppose we have the following CSS:
+
+```
+<head>
+ <style>
+ .rectangle {
+ position: absolute;
+ width: 100px;
+ height: 100px;
+ }
+ .red {
+ background-color: red;
+ }
+ .green {
+ background-color: green;
+ transform: translate(25px, 25px);
+ }
+ .blue {
+ background-color: blue;
+ transform: translate(50px, 50px);
+ }
+ .half-opacity {
+ opacity: 0.5;
+ }
+ </style>
+</head>
+```
+
+Then when applying opacity to a subtree of 3 cascading rectangles,
+```
+<body>
+ <div class="half-opacity">
+ <div class="rectangle red"></div>
+ <div class="rectangle green"></div>
+ <div class="rectangle blue"></div>
+ </div>
+</body>
+```
+the results will look like this:
+
+![Opacity applied to subtree](resources/clients_performance_guide/opacity_on_subtree.png)
+
+which requires the browser to produce an offscreen surface the size of all three
+rectangles, which can be expensive for performance and memory.
+
+For comparison, when opacity is applied to leaf nodes individually,
+```
+<body>
+ <div>
+ <div class="rectangle red half-opacity"></div>
+ <div class="rectangle green half-opacity"></div>
+ <div class="rectangle blue half-opacity"></div>
+ </div>
+</body>
+```
+the results will look like this:
+
+![Opacity to each element of subtree](resources/clients_performance_guide/opacity_on_individuals.png)
+
+which is less expensive because each rectangle can be rendered directly with
+the specified opacity value.
+
+The problem in the first case where opacity is applied to the subtree is that
+switching render targets to and from an offscreen surface is time consuming
+for both the CPU and GPU, and can on some platforms noticeably slow down
+performance, likely manifesting as a lower framerate in animations. While it is
+possible that Cobalt may cache the result, it is not guaranteed, and may not be
+possible if the subtree is being animated. Additionally, the offscreen surface
+will of course consume memory that wouldn't have been required otherwise.
+
+### Similar situations
+
+While opacity tends to be the most common instigator of the behavior described
+above, there are other situations that can trigger offscreen surface usage.
+They are:
+
+ - Setting `overflow: hidden` on a rotated subtree parent element (e.g. via
+ `transform: rotate(...)`)
+ - Setting `overflow: hidden` on a subtree parent element with rounded corners.
+
+## Explicitly set Image src attributes to '' when finished with them.
+
+Cobalt maintains an image cache with a preset capacity (e.g. default of 32MB on
+platforms with 1080p UIs, but it can be customized). When an image goes out
+of scope and is no longer needed, instead of leaving it up to the garbage
+collector to decide when an image should be destroyed and its resources
+released, it is recommended that Image objects have their `src` attribute
+explicitly cleared (i.e. set to `''`) when they are no longer needed, so
+that Cobalt can reclaim the image resources as soon as possible.
+
+## Be conservative with usage of the border-radius CSS property.
+
+While Cobalt has significant optimizations in place for handling the rendering
+of rounded corners, it still requires significantly more sophistication and
+processing than rendering a normal rectangle. This applies to a number of
+different scenarios, such as using rounded corners on elements with either
+background-color or background-image. Particularly expensive however would
+be to apply rounded corners on a parent node which has `overflow: hidden` set
+(as mentioned above), since this requires the creation of an offscreen surface.
+
+## Avoid large (e.g. fullscreen) divs
+
+The more screen area that is covered by DOM elements, the more work the GPU has
+to do, and so the lower the framerate will be. For example, if a background
+is desired, instead of creating a new fullscreen `<div>`, set the
+desired background color or image on the `<body>` element which will cover the
+display anyway. Otherwise, the `<body>` element will render its background, and
+then the `<div>` element will render over top of it (Cobalt is not smart enough
+to know if an element completely coveres another element), resulting in more
+pixels being touched than is necessary.
+
+This type of optimization is related to the concept of "overdraw" from computer
+graphics. A good definition for overdraw can be found at
+[https://developer.android.com/topic/performance/rendering/overdraw](https://developer.android.com/topic/performance/rendering/overdraw):
+
+> "Overdraw refers to the system's drawing a pixel on the screen multiple times
+> in a single frame of rendering. For example, if we have a bunch of stacked
+> UI cards, each card hides a portion of the one below it... It manifests
+> itself as a performance problem by wasting GPU time to render pixels that
+> don't contribute to what the user sees on the screen."
+
+The `<body>` element will always result in the display being filled with a
+color, which is `rgba(0, 0, 0, 0)` by default. Since `<body>` already
+guarantees a full screen draw, the most optimal way of specifying a
+background is to modify `<body>`'s background properties instead of adding
+a layer on top of it.
+
+## Blitter optimizations
+
+If the platform's user agent string contains "blitter", then the platform uses
+the Blitter API for rendering. This device is much more limited in what it can
+render natively, and many complex geometry will require software rendering.
+This means the CPU creates a texture and calculates the color of each pixel in
+that texture. The following things trigger the software rendering path (i.e.
+uses extra memory and is slow) on platforms using the Blitter API:
+
+ - Text.
+ - Rounded corners.
+ - Borders of different sizes. If borders are to be used, then all borders
+ should have the same properties. (And avoid rounded corners.)
+ - Linear gradients which are not exactly vertical or horizontal (i.e. gradients
+ at an angle).
+ - Radial gradients.
+ - Shadows.
+ - Multi-plane images. JPEG images tend to decode into multi-plane images.
+ Prefer using PNG images instead -- these tend to be decoded into RGBA which
+ blitter can handle natively.
+ - Using part of a background image. For example, using background-position may
+ result in extra memory usage, or using a background image inside an
+ `overflow: hidden` element that is shifted or has rounded corners.
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/device_authentication.md b/src/cobalt/site/docs/gen/cobalt/doc/device_authentication.md
new file mode 100644
index 0000000..f1513a9
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/device_authentication.md
@@ -0,0 +1,51 @@
+---
+layout: doc
+title: "Device Authentication"
+---
+# Device Authentication
+
+Starting in Cobalt 20, initial URL requests will now have query parameters
+appended to them signed by the platform's secret key. The key is provided during
+the certification process. The key must be stored in secure storage on the
+device.
+
+## Message
+
+When constructing the URL for the initial browse request, according to the
+logic in
+[cobalt/browser/device_authentication.cc](../browser/device_authentication.cc),
+it will fetch from the platform a "certification scope" string provided to
+the device during certification. The certification scope will be queried
+by a call to `SbSystemGetProperty(kSbSystemPropertyCertificationScope, ...)`,
+which the platform is expected to implement. Along with the current system
+time, this forms the message that must be signed by the device's secret key.
+
+## Signing
+
+The message defined above must be signed with the HMAC-SHA256 algorithm. The
+resulting digest (encoded as base64), alongside the unencrypted message
+contents, will be appended to the initial URL.
+
+Two choices exists for how platforms can expose the secret key to Cobalt.
+Cobalt will first attempt to have the platform sign the message, and if that
+functionality is not implemented Cobalt will query the platform for the secret
+key and sign the message itself. If neither choice is implemented, then Cobalt
+will log a warning and not append anything to the URL.
+
+### Platform signing
+
+Cobalt will first attempt to use the `SbSystemSignWithCertificationSecretKey()`
+function to sign the message using the secret key. This method is preferred
+since it enables implementations where the key exists only in secure hardware
+and never enters the system's main memory. A reference implementation, which
+depends on BoringSSL exists at
+[starboard/linux/x64x11/internal/system_sign_with_certification_secret_key.cc](../../starboard/linux/x64x11/internal/system_sign_with_certification_secret_key.cc).
+
+### Cobalt signing
+
+If the function `SbSystemSignWithCertificationSecretKey()` is unimplemented (e.g. it returns `false`, as is done in
+[starboard/shared/stub/system_sign_with_certification_secret_key.cc](../../starboard/shared/stub/system_sign_with_certification_secret_key.cc)),
+then Cobalt will instead attempt to retrieve the secret key from the system by
+a call to
+`SbSystemGetProperty(kSbSystemPropertyBase64EncodedCertificationSecret, ...)`,
+and use it to produce the HMAC-SHA256 digest of the message itself.
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/docker_build.md b/src/cobalt/site/docs/gen/cobalt/doc/docker_build.md
new file mode 100644
index 0000000..450693f
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/docker_build.md
@@ -0,0 +1,70 @@
+---
+layout: doc
+title: "Cobalt Docker builds"
+---
+# Cobalt Docker builds
+
+Cobalt includes [Docker image][docker.com](https://www.docker.com/)
+definitions for simplifying managing build environments.
+
+The instructions below assume Docker is installed and is able to run basic
+[`hello-world` verification](https://docs.docker.com/get-started/#test-docker-installation).
+`docker-compose` command is expected to be available as well.
+
+## Usage
+
+The simplest usage is:
+
+ `docker-compose run <platform>`
+
+By default, a debug build will be built, with `cobalt` as a target.
+You can override this with an environment variable, e.g.
+
+ `docker-compose run -e CONFIG=devel -e TARGET=nplb <platform>`
+
+where config is one of the four optimization levels, debug, devel, qa and gold,
+and target is the build target passed to `ninja`
+
+See [Cobalt README](../../README.md#build-types)
+for full details.
+
+Builds will be available in your `${COBALT_SRC}/out` directory.
+
+NB! Note that Docker runs processes as root user by default, hence output
+files in `src/out/<platform>` directory have `root` as file owner.
+
+## Customization
+
+To parametrize base operating system images used for the build, pass BASE_OS
+as an argument to docker-compose as follows:
+
+ `docker-compose build --build-arg BASE_OS="ubuntu:bionic" base`
+
+This parameter is defined in `docker/linux/base/Dockerfile` and is passed to
+Docker `FROM ...` statement.
+
+Available parameters for customizing container execution are:
+
+ - **BASE_OS**: passed to `base` image at build time to select a Debian-based
+ base os image and version. Defaults to Debian 9. `ubuntu:bionic` and
+ `ubuntu:xenial` are other tested examples.
+ - **PLATFORM**: Cobalt build platform, passed to GYP
+ - **CONFIG**: Cobalt build config, passed to GYP. Defaults to `debug`
+ - **TARGET**: Build target, passed to `ninja`
+
+The `docker-compose.yml` contains the currently defined experimental build
+configurations. Edit or add new `service` entries as needed, to build custom
+configurations.
+
+## Pre-built images
+
+Note: Pre-built images from a public container registry are not yet available.
+
+## Troubleshooting
+
+To debug build issues, enter the shell of the corresponding build container by
+launching the bash shell, i.e.
+
+ `docker-compose run linux-x64x11 /bin/bash`
+
+and try to build cobalt [with the usual `gyp / ninja` flow](../../README.md#building-and-running-the-code).
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/lifecycle.md b/src/cobalt/site/docs/gen/cobalt/doc/lifecycle.md
new file mode 100644
index 0000000..6b22ee0
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/lifecycle.md
@@ -0,0 +1,244 @@
+---
+layout: doc
+title: "Application Lifecycle"
+---
+# Application Lifecycle
+
+In order to meet common needs of applications running on CE devices, Cobalt
+implements a well-defined web application lifecycle, managing resources and
+notifying the application as appropriate.
+
+## Summary of changes in Cobalt 22
+
+The application lifecycle has some changes from Cobalt 22:
+
+### States:
+
+* The *Paused* state is renamed to *Blurred*.
+* The *Suspended* state is replaced by *Concealed* and *Frozen*.
+* The *Preloading* state is removed, and *Concealed* is used instead.
+ Note: The corresponding attribute value 'prerender' for
+ document.visibilityState is also removed.
+
+The new *Concealed* state is used for applications that are not visible but may
+use CPU or network resources. This state is used to both replace the
+*Preloading* state, and as an intermediate state between *Blurred* and
+*Frozen*.
+
+The *Frozen* state most closely resembles the previous *Suspended* state,
+during which applications do not have network access.
+
+### State Changes:
+
+* The *Pause* event is renamed to *Blur*.
+* The *Unpause* event is renamed to *Focus*.
+* The *Suspend* event is replaced by *Conceal* and *Freeze*.
+* The *Resume* event is replaced by *Unfreeze* and *Reveal*.
+
+Most platforms should only need to replace 'Pause' with 'Blur', 'Unpause' with
+'Focus', 'Suspend' with 'Freeze', and 'Resume' with 'Reveal'.
+
+Since there is no longer a special *Preloading* state, applications should no
+longer use the *Start* event when a preloaded application is brought to the
+foreground. Instead, the same event(s) used for backgrounded applications
+(*Concealed* or *Frozen*) should be used.
+
+### Application 'Backgrounding' and 'Foregrounding'.
+
+To signal that the application is being 'backgrounded', the use of *Suspend*
+should be replaced with *Freeze*.
+
+To signal that the application is being 'foregrounded', the use of *Unpause*
+should be replaced with *Focus*.
+
+Note: If a platform is using *Resume* (*Reveal*) to signal that an application
+is being 'foregrounded', then that may result in unexpected application
+behavior, unless a subsequent *Unpause* (*Focus*) is also used when the
+application receives input focus.
+
+More details about lifecycle states and state changes can be found in
+`src/starboard/event.h`.
+
+### Deprecated `SbEventType` values.
+
+The `SbEventType` enum is defined in `src/starboard/event.h`.
+
+* The `kSbEventTypePause` value is renamed to `kSbEventTypeBlur`.
+* The `kSbEventTypeUnpause` value is renamed to `kSbEventTypeFocus`.
+* The `kSbEventTypeSuspend` value is replaced by `kSbEventTypeConceal` and
+ `kSbEventTypeFreeze`.
+* The `kSbEventTypeResume` value is replaced by `kSbEventTypeUnfreeze` and
+ `kSbEventTypeReveal`.
+
+The corresponding helper functions in
+`starboard::shared::starboard::Application` (implemented in
+`starboard/shared/starboard/application.cc`) that inject events with these
+values have been updated correspondingly:
+
+* The `Pause()` method is renamed to `Blur()`.
+* The `Unpause()` method is renamed to `Focus()`.
+* The `Suspend()` method is replaced by `Conceal()` and
+ `Freeze()`.
+* The `Resume()` method is replaced by `Unfreeze()` and
+ `Reveal()`.
+
+Platforms that inject events themselves should be updated to use renamed event
+type values, and platforms that use the helper functions should be updated to
+call the corresponding renamed helper functions.
+
+### Deprecated `SbSystemRequest` functions.
+
+The `SbSytemRequest` functions are declared in `src/starboard/system.h`
+
+* The `SbSystemRequestPause` event is renamed to `SbSystemRequestBlur`
+* The `SbSystemRequestUnpause` event is renamed to `SbSystemRequestFocus`
+* The `SbSystemRequestSuspend` event is replaced by `SbSystemRequestConceal`
+ and `SbSystemRequestFreeze`
+* The `SbSystemRequestResume` event is replaced by `SbSystemRequestUnfreeze`
+ and `SbSystemRequestReveal`
+
+## Application States
+
+Starboard Application State | Page Visibility State | Window Focused
+:-------------------------- | :-------------------- | :-------------
+*Started* | visible | true
+*Blurred* | visible | false
+*Concealed* | hidden | false
+*Frozen* | hidden | false
+
+When transitioning between *Concealed* and *Frozen*, the document.onfreeze and
+document.onresume events from the Page LifeCycle Web API will be dispatched.
+
+### Started
+
+The application is running, visible, and interactive. The normal foreground
+application state. May be the start state, or can be entered from *Blurred*.
+
+May only transition to *Blurred*. In Linux desktop, this happens anytime the
+top-level Cobalt X11 window loses focus. Linux transition back to *Started*
+when the top-level Cobalt X11 window gains focus again.
+
+### Blurred
+
+The application may be fully visible, partially visible, or completely
+obscured, but it has lost input focus, so will receive no input events. It has
+been allowed to retain all its resources for a very quick return to *Started*,
+and the application is still running. May be entered from or transition to
+*Started* or *Concealed* at any time.
+
+### Concealed
+
+The application is not visible and will receive no input, but is running. Can
+be entered as the start state. May be entered from or transition to *Blurred*
+or *Frozen* at any time. The application may be terminated in this state
+without notification.
+
+Upon entering, all graphics resources will be revoked until revealed, so the
+application should expect all images to be lost, and all caches to be cleared.
+
+#### Expectations for the web application
+
+The application should **shut down** playback, releasing resources. On resume,
+all resources need to be reloaded, and playback should be reinitialized where
+it left off, or at the nearest key frame.
+
+### Frozen
+
+The application is not visible and will receive no input, and, once *Frozen*,
+will not run any code. May be entered from or transition to *Concealed* at any
+time. The application may be terminated in this state without notification.
+
+Upon entering, all graphics and media resources will be revoked until resumed,
+so the application should expect all images to be lost, all caches to be
+cleared, and all network requests to be aborted.
+
+#### Expectations for the porter
+
+Currently, Cobalt does not manually stop JavaScript execution when it goes into
+the *Frozen* state. In Linux desktop, it expects that a `SIGSTOP` will be
+raised, causing all the threads not to get any more CPU time until resumed.
+This will be fixed in a future version of Cobalt.
+
+### Application Startup Expectations for the porter
+
+The starboard application lifecycle, with descriptions of the states and the
+state changes can be found in `src/starboard/event.h`.
+
+For applications that can be preloaded, the platform should send
+`kSbEventTypePreload` as the first Starboard event instead of
+`kSbEventTypeStart`. Subclasses of
+`src/starboard/shared/starboard/application.cc` can opt-in to use the already
+implemented support for the `--preload` command-line switch.
+
+If started with `kSbEventTypePreload`, the platform can at any time send
+`kSbEventTypeFocus` when the application brought to the foreground.
+In Linux desktop (linux-x64x11), this can be done by sending a `SIGCONT` to the
+process that is in the *Preloading* state (see
+`starboard/shared/signal/suspend_signals.cc`)
+
+If the platform wants to only give applications a certain amount of time to
+preload, they can send `SbSystemRequestFreeze` to halt preloading and move to
+the *Frozen* state. In Linux desktop, this can be done by sending SIGUSR1 to
+the process that is in the *Preloading* state.
+
+## Implementing the Application Lifecycle (for the porter)
+
+The platform Starboard implementation **must always** send events in the
+prescribed order - meaning, for example, that it should never send a
+`kSbEventTypeConceal` event unless in the *Blurred* state.
+
+Most porters will want to subclass either `starboard::shared::Application` (in
+`src/starboard/shared/starboard/application.cc`) or
+`starboard::shared::QueueApplication` (in
+`src/starboard/shared/starboard/queue_application.cc`), as these are reference
+classes that rigorously implement the Starboard application lifecycle. They are
+optional, and platforms can directly dispatch events to SbEventHandle(), but it
+is then up to them to ensure that events are **always** sent in the correct
+state as specified in the Starboard documentation.
+
+`starboard::shared::Application` (in
+`starboard/shared/starboard/application.cc`) guarantees the correct ordering by
+implementing a small state machine that ignores invalid application state
+transitions, and inserts any necessary transitions to make them valid. For
+example, you can call `starboard::shared::Application::Conceal()`, and if you
+are in *Blurred*, it will just dispatch a `kSbEventTypeConceal` event. But if
+you call `Conceal()` in the *Started* state, it will first dispatch
+`kSbEventTypeBlur`, followed by a `kSbEventTypeConceal` event. If you call
+`Conceal()` in the *Concealed* state, it just does nothing.
+
+This behavior can be ensured by only dispatching events to SbEventHandle()
+using `Application::DispatchAndDelete()` either directly, or indirectly such
+as by using `Application::RunLoop()` with the default implementation of
+`Application::DispatchNextEvent()`.
+
+To control starting up in the *Concealed* state for preloading, `Application`
+subclasses must override two functions:
+
+``` c++
+class MyApplication : public shared::starboard::QueueApplication {
+ // [ ... ]
+ bool IsStartImmediate() override;
+ bool IsPreloadImmediate() override;
+ // [ ... ]
+}
+```
+
+To start up in the *Concealed* state, `IsStartImmediate()` should return
+`false` and `IsPreloadImmediate()` should return `true`.
+
+To start up in the *Starting* state (which is the default), `IsStartImmediate()`
+should return `true` and `IsPreloadImmediate()` will not be called.
+
+To delay starting up until some later event, `IsStartImmediate()` and
+`IsPreloadImmediate()` should both return `false`. No initial event will be
+automatically sent to the application, and it is then up to the porter to
+dispatch a `kSbEventTypeStart` or `kSbEventTypePreload` event as the first
+event. This is useful if you need to wait for an asynchronous system activity to
+complete before starting Cobalt.
+
+To support the `--preload` command-line argument:
+
+``` c++
+ bool IsStartImmediate() override { return !HasPreloadSwitch(); }
+ bool IsPreloadImmediate() override { return HasPreloadSwitch(); }
+```
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/memory_tuning.md b/src/cobalt/site/docs/gen/cobalt/doc/memory_tuning.md
new file mode 100644
index 0000000..a053b40
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/memory_tuning.md
@@ -0,0 +1,329 @@
+---
+layout: doc
+title: ""
+---
+# Memory Tuning #
+
+Cobalt is designed to choose sensible parameters for memory-related options and
+parameters through a system called "AutoMem".
+
+On startup, AutoMem will print a memory table to the output console detailing
+the memory allocations that will be assigned to the various subsystems in
+cobalt.
+
+As an example, at the cost of performance you can reduce CPU memory on your
+platform by 5MB and GPU memory usage on your platform by 10MB using these
+command line flags:
+
+`cobalt --reduce_cpu_memory_by=5MB --reduce_gpu_memory_by=10MB`
+
+Some settings will be "fixed" while others will be "flexible" so that their
+memory consumption will scale down for memory constrained platforms.
+
+Read on for more information.
+
+**IMPORTANT**
+*Setting `--max_cobalt_cpu_usage` and `--max_cobalt_gpu_usage` on the
+command line is a beta feature. When reducing memory, please use
+`--reduce_cpu_memory_by` and `--reduce_gpu_memory_by`.*
+
+### Memory Settings Table ###
+
+A table similar to the one below, will be printed on startup.
+
+~~~
+AutoMem:
+
+ SETTING NAME VALUE TYPE SOURCE
+ ________________________________________________________________________________
+| | | | | |
+| image_cache_size_in_bytes | 33554432 | 32.0 MB | GPU | AutoSet |
+|______________________________________|_____________|__________|______|_________|
+| | | | | |
+| javascript_gc_threshold_in_bytes | 8388608 | 8.0 MB | CPU | Build |
+|______________________________________|_____________|__________|______|_________|
+| | | | | |
+| misc_cobalt_cpu_size_in_bytes | 124780544 | 119.0 MB | CPU | AutoSet |
+|______________________________________|_____________|__________|______|_________|
+| | | | | |
+| misc_cobalt_gpu_size_in_bytes | 25165824 | 24.0 MB | GPU | AutoSet |
+|______________________________________|_____________|__________|______|_________|
+| | | | | |
+| remote_typeface_cache_size_in_bytes | 4194304 | 4.0 MB | CPU | Build |
+|______________________________________|_____________|__________|______|_________|
+| | | | | |
+| skia_atlas_texture_dimensions | 4096x8192x2 | 64.0 MB | GPU | Build |
+|______________________________________|_____________|__________|______|_________|
+| | | | | |
+| skia_cache_size_in_bytes | 4194304 | 4.0 MB | GPU | Build |
+|______________________________________|_____________|__________|______|_________|
+| | | | | |
+| software_surface_cache_size_in_bytes | N/A | N/A | N/A | N/A |
+|______________________________________|_____________|__________|______|_________|
+
+~~~
+This table shows the breakdown of how much memory is being allocated to each
+sub-system, the type, and where it came from.
+
+**SETTING NAME:** This is the name of the memory setting. If a setting can be
+manually set through the command line or the build system, then it will be
+accessible by using this name. For example adding the command line argument
+`--image_cache_size_in_bytes=25165824` will manually set the Image Cache Size to
+24 megabytes. Also note that this is also equivalent:
+`--image_cache_size_in_bytes=24MB`. Note that the numerical value can include
+the suffix kb/mb/gb to specify kilo/mega/giga-bytes. The numerical value can
+be a floating point value. For example `--image_cache_size_in_bytes=.1GB` is
+equivalent to `--image_cache_size_in_bytes=100MB`.
+
+**VALUE:** This two column value has a first setting that describes what the
+actual value is, and the second column is the amount of memory that the setting
+consumes. This first setting gives hints on what kind of values the
+setting can be set to via the command line. For example,
+`skia_atlas_texture_dimensions` accepts texture sizes on the command line, such
+as: `--skia_atlas_texture_dimensions=2048x4096x2`
+
+**TYPE:** This specifies whether the setting consumes GPU or CPU memory.
+For example, the Image Cache will decode images to buffers to the GPU memory
+and therefore it is the classified as the GPU memory type.
+
+**SOURCE:** This specifies where the memory setting came from. It will either
+be set from a specific place or automatically generated from Cobalt.
+ * Values for **SOURCE**:
+ * `Starboard API`
+ * The value used was reported by the result of a Starboard API function call.
+ * Example: `SbSystemGetUsedCPUMemory()`
+ * `Build`
+ * Specified by the platform specific `*.gyp(i)` build file.
+ * For example: see `image_cache_size_in_bytes` in [`build/config/base.gypi`](../build/config/base.gypi)
+ * `CmdLine`
+ * Read the memory setting value from the command line.
+ * For example: `cobalt --image_cache_size_in_bytes=24MB`.
+ * `AutoSet`
+ * No value was specified and therefore Cobalt calculated the default value
+ automatically based on system parameters. For example many caches
+ will be chosen proportionally to the size of the UI resolution.
+ * `AutoSet (Constrained)`
+ * This value was AutoSet to a default value, but then was reduced in
+ response to `max_cobalt_cpu_usage` or `max_cobalt_gpu_usage being` set too low.
+ This will also trigger in response to `reduce_cpu_memory_by` or
+ `reduce_cpu_memory_by` being set. See "Memory Scaling" section below.
+
+### Maximum Memory Table ###
+
+This second table is also printed at startup and details the sum of memory and
+maximum memory limits as reported by cobalt.
+
+~~~
+ MEMORY SOURCE TOTAL SETTINGS CONSUME
+ ____________________________________________________________________
+| | | | |
+| max_cobalt_cpu_usage | Starboard API | 256.0 MB | 131.0 MB |
+|______________________|_______________|__________|__________________|
+| | | | |
+| max_cobalt_gpu_usage | Starboard API | 768.0 MB | 124.0 MB |
+|______________________|_______________|__________|__________________|
+~~~
+
+This table shows the limits for CPU and GPU memory consumption and also how
+much memory is being consumed for each memory type.
+
+**MEMORY**: This is the name of the memory limit. If you want to change this
+setting manually then use the name on the command line. For example
+`--max_cobalt_cpu_usage=150MB` will set Cobalt to 150MB limit for CPU
+memory. If the sum of CPU memory exceeds this limit then memory settings of the
+same type will reduce their memory usage.
+
+**SOURCE**: This value indicates where the value came from.
+ * `Starboard API`
+ * `max_cobalt_cpu_usage`: This value was found from SbSystemGetTotalCPUMemory().
+ * `max_cobalt_gpu_usage`: This value was found from SbSystemGetTotalGPUMemory().
+ * `CmdLine`
+ * `max_cobalt_cpu_usage`: --max_cobalt_cpu_usage was used as a command argument.
+ * `max_cobalt_gpu_usage`: --max_cobalt_gpu_usage was used as a command argument.
+ * `Build`
+ * `max_cobalt_cpu_usage`: max_cobalt_cpu_usage was specified in a platform gyp file.
+ * `max_cobalt_gpu_usage`: max_cobalt_gpu_usage was specified in a platform gyp file.
+
+**TOTAL**: Represents the maximum available memory for settings. This value
+came from **SOURCE**.
+
+**SETTINGS CONSUME**: This value indicates the consumption of memory for the
+current memory type.
+
+For `max_cobalt_cpu_usage`, `Starboard API` indicates that this value came from
+`SbSystemGetTotalCPUMemory()` If this source value is `Starboard API` then this
+value came from `SbSystemGetTotalCPUMemory()` (for CPU) or
+`SbSystemGetTotalGPUMemory()` for GPU).
+
+If the available memory for the Cobalt is less than the amount of memory
+consumed by the settings, then any settings that are AutoSet AND adjustable
+will reduce their memory consumption. When this happens, look for the string
+*`AutoSet (Constrained)`* in the first table.
+
+## Setting Maximum Memory Values ##
+
+The max cpu and gpu memory of the system can be set either by command line or
+by modifying the gyp build file.
+
+Command Line:
+ * `--max_cobalt_cpu_usage=160MB`
+ * `--max_cobalt_gpu_usage=160MB`
+
+Build settings:
+ * `starboard/<PLATFORM>/gyp_configuration.gypi`
+ * `max_cobalt_cpu_usage`
+ * `max_cobalt_gpu_usage`
+
+Command Line settings will override build settings.
+
+### Memory Scaling ###
+
+There are two primary ways in which the memory consumption settings will scale down.
+One is by specifying `--max_cobalt_cpu_usage` (or `max_cobalt_gpu_usage`) to a
+particular value (e.g. `--max_cobalt_cpu_usage=160MB`).
+
+`--max_cobalt_cpu_usage` (and `--max_cobalt_gpu_usage`) will trigger the memory
+to scale down whenever the memory settings memory consumption exceed the maximum
+**TOTAL** value. The memory settings will be scaled down until their consumption is
+less than or equal the maximum allowed value **TOTAL**. See also **SETTINGS CONSUME**.
+
+Another way to scale down the memory size is by passing the flags
+`--reduce_cpu_memory_by=XX` and `--reduce_gpu_memory_by=XX` which will:
+1) Ignore the `--max_cobalt_cpu_usage` and `--max_cobalt_gpu_usage`.
+2) Use the current memory consumption of the settings and then reduce that by
+ the amount.
+
+For example, if cobalt uses 160MB of CPU memory then passing in
+`--reduce_cpu_memory_by=10MB` to the command line will attempt to reduce the
+footprint of cobalt by 10MB to 150MB. Note that this reduction is an an attempt,
+and it's possible this attempt will fail if the memory reduction is too aggressive
+or if memory settings have been explicitly set via the build or command line.
+
+*Forcing a Memory Setting to be flexible*
+
+If a memory setting is set via a build setting, then it's possible to make it
+flexible via the command line by setting the value to "autoset". For example,
+ `--image_cache_size_in_bytes=auto` will allow `image_cache_size_in_bytes` to be
+flexible by disabling the value being set by a build setting.
+
+### Memory Warnings ###
+
+Cobalt will periodically check to see if the memory consumed by the application
+is less than the `--max_cobalt_cpu_usage` and `--max_cobalt_gpu_usage` amount.
+If the cpu/gpu exceeds this maximum value then an error message will be logged
+once to stdout for cpu and/or gpu memory systems.
+
+
+### Example 1 - Configuring for a memory restricted platform ###
+
+Let's say that we are configuring platform called "XXX":
+
+We will configure XXX such that:
+ * `image_cache_size_in_bytes` will be set to 32MB in the build settings.
+ * `skia_atlas_texture_dimensions` will be set to `2048x2048x2` in the build settings.
+ * `max_cobalt_cpu_usage` will be set to 160MB on the command line.
+
+**Configuring `image_cache_size_in_bytes` to be 32MB:**
+ * in `starboard\<PLATFORM>\gyp_configuration.gypi`
+ * add `'image_cache_size_in_bytes': 32 * 1024 * 1024,`
+
+**Configuring `skia_atlas_texture_dimensions` to be 2048x2048x2:**
+
+ * in `src\starboard\XXX\gyp_configuration.gypi`
+ * add `'skia_glyph_atlas_width': '2048'`
+ * add `'skia_glyph_atlas_height': '2048'`
+ * (note that the third dimension is assumed)
+
+**Configuring `max_cobalt_cpu_usage` to be 160MB:**
+
+ * `cobalt --max_cobalt_cpu_usage=160MB`
+
+### Example 2 - Configuring for a memory-plentiful platform ###
+
+The following command line will give a lot of memory to image cache and give
+500MB to `max_cobalt_cpu_usage` and `max_cobalt_gpu_usage`.
+
+~~~
+cobalt --max_cobalt_cpu_usage=500MB --max_cobalt_gpu_usage=500MB
+--image_cache_size_in_bytes=80MB
+~~~
+
+## API Reference ##
+
+#### Memory System API ####
+
+ * `max_cobalt_cpu_usage`
+ * This setting will set the maximum cpu memory that the app will consume.
+ CPU Memory settings will scale down their consumption in order to stay under
+ the `max_cobalt_cpu_usage`. If memory consumption exceeds this value during
+ runtime then a memory warning will be printed to stdout.
+ * Set via command line or else build system or else starboard.
+ * starboard value will bind to `SbSystemGetTotalCPUMemory()`.
+ * `max_cobalt_gpu_usage`
+ * This setting will set the maximum gpu memory that the app will consume.
+ GPU Memory settings will scale down their consumption in order to stay under
+ the `max_cobalt_gpu_usage`. If memory consumption exceeds this value during
+ runtime then a memory warning will be printed to stdout.
+ * Set via command line or else build system or else starboard.
+ * starboard value will bind to `SbSystemGetTotalGPUMemory()`.
+ * Note that `SbSystemGetTotalGPUMemory()` is optional. If no value exists
+ for `max_cobalt_gpu_usage` in build/commandline/starboard settings then no
+ GPU memory checking is performed.
+ * `reduce_cpu_memory_by`
+ * This setting will trigger CPU memory consumption to be reduced by the amount
+ specified. *This overrides the memory scaling behavior of `max_cobalt_cpu_usage`*.
+ But this will not affect memory checking of `max_cobalt_cpu_usage` otherwise.
+ * Set via command line or else the platform gyp build file.
+ * `reduce_cpu_memory_by`
+ * This setting will trigger GPU memory consumption to be reduced by the amount
+ specified. *This overrides the memory scaling behavior of `max_cobalt_gpu_usage`*.
+ But this will not affect memory checking of `max_cobalt_gpu_usage` otherwise.
+ * Set via command line or else the platform gyp build file.
+
+#### Memory Setting API ####
+
+ * `image_cache_size_in_bytes`
+ * See documentation *Image cache capacity* in `performance_tuning.md` for what
+ this setting does.
+ * Set via command line, or else build system, or else automatically by Cobalt.
+ * `javascript_gc_threshold_in_bytes`
+ * See documentation *Garbage collection trigger threshold* in `performance_tuning.md`
+ for what this setting does.
+ * Set via command line, or else build system, or else automatically by Cobalt.
+ * `remote_typeface_cache_size_in_bytes`
+ * Determines the capacity of the remote typefaces cache which manages all typefaces
+ downloaded from a web page.
+ * Set via command line, or else build system, or else automatically by Cobalt.
+ * `skia_atlas_texture_dimensions`
+ * Determines the size in pixels of the glyph atlas where rendered glyphs are
+ cached. The resulting memory usage is 2 bytes of GPU memory per pixel.
+ When a value is used that is too small, thrashing may occur that will
+ result in visible stutter. Such thrashing is more likely to occur when CJK
+ language glyphs are rendered and when the size of the glyphs in pixels is
+ larger, such as for higher resolution displays.
+ The negative default values indicates to the Cobalt that these settings
+ should be automatically set.
+ * Set via command line, or else build system, or else automatically by Cobalt.
+ * Note that in the gyp build system, this setting is represented as two values:
+ * `skia_glyph_atlas_width` and
+ * `skia_glyph_atlas_height`
+ * `skia_cache_size_in_bytes`
+ * See documentation *Glyph atlas size* in `performance_tuning.md` for what this
+ setting does.
+ * Set via command line, or else build system or else automatically by Cobalt.
+ * `software_surface_cache_size_in_bytes`
+ * See documentation *Scratch Surface cache capacity* in `performance_tuning.md`
+ for what this setting does.
+ * Set via command line, or else build system, or else automatically by Cobalt.
+
+#### Units for Command Line Settings ####
+
+Memory values passed into Cobalt via command line arguments support units such
+kb, mb, and gb for kilo-byte, megabyte, gigabytes. These units are case insensitive.
+
+For example, these are all equivalent on the command line:
+
+`--image_cache_size_in_bytes=67108864`
+`--image_cache_size_in_bytes=65536kb`
+`--image_cache_size_in_bytes=64mb`
+`--image_cache_size_in_bytes=.0625gb`
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/net_log.md b/src/cobalt/site/docs/gen/cobalt/doc/net_log.md
new file mode 100644
index 0000000..17410f7
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/net_log.md
@@ -0,0 +1,34 @@
+---
+layout: doc
+title: "Cobalt NetLog"
+---
+# Cobalt NetLog
+
+Chromium has a very useful network diagnostic tool called the NetLog and Cobalt
+is hooked up to use it. It's the main tool to track network traffic and debug
+network code.
+
+### Activate the NetLog
+
+The following command line switch will activate the NetLog and store net log
+record to the specified location.
+`./cobalt --net_log=/PATH/TO/YOUR_NETLOG_NAME.json`
+The output json file will be stored at the file location you choose.
+
+
+### Read the NetLog records
+
+The produced json file is not human-friendly, use the
+[NetLog Viewer](https://netlog-viewer.appspot.com/#import)
+
+Cobalt's net_log can not enable some features in the web viewer, but all the
+network traffic is recorded in the event tab.
+
+
+### Add NetLog entries
+
+To Add NetLog entry, get the NetLog instance owned by NetworkModule to where you
+want to add entries and start/end your entry according to the NetLog interface.
+
+A NetLog object is created at each NetworkModule initialization and is passed
+into Chromium net through URLRequestContext.
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/performance_tuning.md b/src/cobalt/site/docs/gen/cobalt/doc/performance_tuning.md
new file mode 100644
index 0000000..72118e7
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/performance_tuning.md
@@ -0,0 +1,393 @@
+---
+layout: doc
+title: "Performance Tuning"
+---
+# Performance Tuning
+
+Cobalt is designed to choose sensible parameters for all performance-related
+options and parameters, however sometimes these need to be explicitly set
+to allow Cobalt to run optimally for a specific platform. This document
+discusses some of the tweakable parameters in Cobalt that can have an
+affect on performance.
+
+A number of tweaks are listed below in no particular order. Each item
+has a set of tags keywords to make it easy to search for items related
+to a specific type of performance metric (e.g. "framerate").
+
+Many of the tweaks involve adding a new gyp variable to your platform's
+`gyp_configuration.gypi` file. The default values for these variables are
+defined in either
+[`base_configuration.gypi`](../../starboard/build/base_configuration.gypi) or
+[`cobalt_configuration.gypi`](../build/cobalt_configuration.gypi).
+
+### Use a Release Build
+
+Cobalt has a number of different build configurations (e.g. "debug", "devel",
+"qa" and "gold" in slowest-to-fastest order), with varying degrees of
+optimizations enabled. For example, while "devel" has compiler optimizations
+enabled, it does not disable DCHECKS (debug assertions) which can decrease
+Cobalt's performance. The "qa" build is most similar to "gold", but it still
+has some debug features enabled (such as the debug console which can consume
+memory, and decrease performance while it is visible). For the best
+performance, build Cobalt in the "gold" configuration.
+
+**Tags:** *framerate, startup, browse-to-watch, cpu memory, input latency.*
+
+
+### Framerate throttling
+
+If you're willing to accept a lower framerate, there is potential that
+JavaScript execution can be made to run faster (which can improve startup
+time, browse-to-watch time, and input latency). Without any special
+settings in place, the renderer will attempt to render each frame as fast
+as it can, limited only by the display's refresh rate, which is usually 60Hz.
+By artificially throttling this rate to a lower value, like 30Hz, CPU
+resources can be freed to work on other tasks. You can enable framerate
+throttling by setting a value for `cobalt_minimum_frame_time_in_milliseconds`
+in your platform's `gyp_configuration.gypi` file. Setting it to 33, for
+example, will throttle Cobalt's renderer to 30 frames per second.
+
+**Tags:** *gyp_configuration.gypi, framerate, startup, browse-to-watch,
+ input latency.*
+
+
+### Image cache capacity
+
+Cobalt's image cache is used to cache decoded image data. The image data
+in the image cache is stored as a texture, and so it will occupy GPU memory.
+The image cache capacity dictates how long images will be kept resident in
+memory even if they are not currently visible on the web page. By reducing
+this value, you can lower GPU memory usage, at the cost of having Cobalt
+make more network requests and image decodes for previously seen images.
+Cobalt will automatically set the image cache capacity to a reasonable value,
+but if you wish to override this, you can do so by setting the
+`image_cache_size_in_bytes` variable in your `gyp_configuration.gypi` file. For
+the YouTube web app, we have found that at 1080p, 32MB will allow around
+5 thumbnail shelves to stay resident at a time, with 720p and 4K resolutions
+using proportionally less and more memory, respectively.
+
+**Tags:** *gyp_configuration.gypi, cpu memory, gpu memory.*
+
+
+### Image cache capacity multiplier during video playback
+
+Cobalt provides a feature where the image cache capacity will be reduced
+as soon as video playback begins. This can be useful for reducing peak
+GPU memory usage, which usually occurs during video playback. The
+downside to lowering the image cache during video playback is that it
+may need to evict some images when the capacity changes, and so it is
+more likely that Cobalt will have to re-download and decode images after
+returning from video playback. Note that this feature is not well tested.
+The feature can be activated by setting
+`image_cache_capacity_multiplier_when_playing_video` to a value between
+`0.0` and `1.0` in your `gyp_configuration.gypi` file. The image cache
+capacity will be multiplied by this value during video playback.
+
+**Tags:** *gyp_configuration.gypi, gpu memory.*
+
+
+### Scratch Surface cache capacity
+
+This only affects GLES renderers. While rasterizing a frame, it is
+occasionally necessary to render to a temporary offscreen surface and then
+apply that surface to the original render target. Offscreen surface
+rendering may also need to be performed multiple times per frame. The
+scratch surface cache will keep allocated a set of scratch textures that
+will be reused (within and across frames) for offscreen rendering. Reusing
+offscreen surfaces allows render target allocations, which can be expensive
+on some platforms, to be minimized. However, it has been found that some
+platforms (especially those with tiled renderers, like the Raspberry Pi's
+Broadcom VideoCore), reading and writing again and again to the same texture
+can result in performance degradation. Memory may also be potentially saved
+by disabling this cache, since when it is enabled, if the cache is filled, it
+may be occupying memory that it is not currently using. This setting can
+be adjusted by setting `surface_cache_size_in_bytes` in your
+`gyp_configuration.gypi` file. A value of `0` will disable the surface cache.
+
+**Tags:** *gyp_configuration.gypi, gpu memory, framerate.*
+
+
+### Glyph atlas size
+
+This only affects GLES renderers. Skia sets up glyph atlases to which
+it software rasterizes glyphs the first time they are encountered, and
+from which the glyphs are used as textures for hardware accelerated glyph
+rendering to the render target. Adjusting this value will adjust
+GPU memory usage, but at the cost of performance as text glyphs will be
+less likely to be cached already. Note that if experimenting with
+modifications to this setting, be sure to test many languages, as some
+are more demanding (e.g. Chinese and Japanese) on the glyph cache than
+others. This value can be adjusted by changing the values of
+the `skia_glyph_atlas_width` and `skia_glyph_atlas_height` variables in your
+`gyp_configuration.gypi` file. Note that by default, these will be
+automatically configured by Cobalt to values found to be optimal for
+the application's resolution.
+
+**Tags:** *gyp_configuration.gypi, gpu memory, input latency, framerate.*
+
+
+### Software surface cache capacity
+
+This only affects Starboard Blitter API renderers. The Starboard Blitter API
+has only limited support for rendering special effects, so often Cobalt will
+have to fallback to a software rasterizer for rendering certain visual
+elements (most notably, text). In order to avoid expensive software
+renders, the results are cached and re-used across frames. The software
+surface cache is crucial to achieving an acceptable framerate on Blitter API
+platforms. The size of this cache is specified by the
+`software_surface_cache_size_in_bytes` variable in `gyp_configuration.gypi`.
+
+**Tags:** *gyp_configuration.gypi, gpu memory, framerate.*
+
+
+### Toggle Just-In-Time JavaScript Compilation
+
+Just-in-time (JIT) compilation of JavaScript is well known to significantly
+improve the speed of JavaScript execution. However, in the context of Cobalt
+and its web apps (like YouTube's HTML5 TV application), JITting may not be
+the best or fastest thing to do. Enabling JIT can result in Cobalt using
+more memory (to store compiled code) and can also actually slow down
+JavaScript execution (e.g. time must now be spent compiling code). It is
+recommended that JIT support be left disabled, but you can experiment with
+it by implementing the CobaltExtensionConfigurationApi method
+`CobaltEnableJit()` to return `true` to enable JIT, or `false` to disable it.
+
+**Tags:** *gyp_configuration.gypi, startup, browse-to-watch, input latency,
+ cpu memory.*
+
+
+### Ensure that you are not requesting Cobalt to render unchanging frames
+
+Some platforms require that the display buffer is swapped frequently, and
+so in these cases Cobalt will render the scene every frame, even if it is
+not changing, which consumes CPU resources. If the platform needs a new frame
+submitted periodically implement the Cobalt Extension
+"dev.cobalt.extension.Graphics" and report the maximum frame interval via
+`GetMaximumFrameIntervalInMilliseconds`.
+
+See `SbSystemGetExtension` and
+[`CobaltExtensionGraphicsApi`](../extension/graphics.h).
+
+Every `cobalt_minimum_frame_time_in_milliseconds`, this function will be queried
+to determine if a new frame should be presented even if the scene has not
+changed.
+
+**Tags:** *configuration_public.h, startup, browse-to-watch, input latency,
+ framerate.*
+
+
+### Try enabling rendering only to regions that change
+
+If you set the
+[`CobaltConfigurationExtensionApi`](../extension/configuration.h) function
+`CobaltRenderDirtyRegionOnly` to return `true`, then Cobalt will invoke logic
+to detect which part of the frame has been affected by animations and can be
+configured to only render to that region. However, this feature requires
+support from the driver for GLES platforms. In particular, `eglChooseConfig()`
+will first be called with `EGL_SWAP_BEHAVIOR_PRESERVED_BIT` set in its
+attribute list. If this fails, Cobalt will call eglChooseConfig() again
+without `EGL_SWAP_BEHAVIOR_PRESERVED_BIT` set and dirty region rendering will
+be disabled. By having Cobalt render only small parts of the screen,
+CPU (and GPU) resources can be freed to work on other tasks. This can
+especially affect startup time since usually only a small part of the
+screen is updating (e.g. displaying an animated spinner). Thus, if
+possible, ensure that your EGL/GLES driver supports
+`EGL_SWAP_BEHAVIOR_PRESERVED_BIT`. Note that it is possible (but not
+necessary) that GLES drivers will implement this feature by allocating a new
+offscreen buffer, which can significantly affect GPU memory usage. If you are
+on a Blitter API platform, enabling this functionality will result in the
+allocation and blit of a fullscreen "intermediate" back buffer target.
+
+**Tags:** *startup, framerate, gpu memory.*
+
+
+### Ensure that thread priorities are respected
+
+Cobalt makes use of thread priorities to ensure that animations remain smooth
+even while JavaScript is being executed, and to ensure that JavaScript is
+processed (e.g. in response to a key press) before images are decoded. Thus
+having support for priorities can improve the overall performance of the
+application. To enable thread priority support, you should set the value
+of `kSbHasThreadPrioritySupport` to `true` in your `configuration_constants.h`
+file, and then also ensure that your platform's implementation of
+`SbThreadCreate()` properly forwards the priority parameter down to the
+platform.
+
+**Tags:** *configuration_public.h, framerate, startup, browse-to-watch,
+ input latency.*
+
+
+### Tweak compiler/linker optimization flags
+
+Huge performance improvements can be obtained by ensuring that the right
+optimizations are enabled by your compiler and linker flag settings. You
+can set these up within `gyp_configuration.gypi` by adjusting the list
+variables `compiler_flags` and `linker_flags`. See also
+`compiler_flags_gold` and `linker_flags_gold` which describe flags that
+apply only to gold builds where performance is critical. Note that
+unless you explicitly set this up, it is unlikely that compiler/linker
+flags will carry over from external shell environment settings; they
+must be set explicitly in `gyp_configuration.gypi`.
+
+**Tags:** *framerate, startup, browse-to-watch, input latency*
+
+#### Optimize for size vs speed
+
+For qa and gold configs, different compiler flags can be used for gyp targets
+which should be optimized for size vs speed. This can be used to reduce the
+executable size with minimal impact on performance. On top of the base
+`compiler_flags_qa` and `compiler_flags_gold`, the gyp variables
+`compiler_flags_qa_size`, `compiler_flags_qa_speed`, `compiler_flags_gold_size`,
+and `compiler_flags_gold_speed` will be used. Performance-critical gyp targets
+specify `optimize_target_for_speed`: 1, and these will use compiler flags
+`compiler_flags_<config>` + `compiler_flags_<config>_speed`; other gyp targets
+will use `compiler_flags_<config>` + `compiler_flags_<config>_size`.
+
+**Tags:** *cpu memory, package size*
+
+#### Link Time Optimization (LTO)
+If your toolchain supports it, it is recommended that you enable the LTO
+optimization, as it has been reported to yield significant performance
+improvements in many high profile projects.
+
+**Tags:** *framerate, startup, browse-to-watch, input latency*
+
+
+### Close "Stats for Nerds" when measuring performance
+
+The YouTube web app offers a feature called "Stats for Nerds" that enables
+a stats overlay to appear on the screen during video playback. Rendering
+this overlay requires a significant amount of processing, so it is
+recommended that all performance evaluation is done without the
+"Stats for Nerds" overlay active. This can greatly affect browse-to-watch
+time and potentially affect the video frame drop rate.
+
+**Tags:** *browse-to-watch, framerate, youtube.*
+
+
+### Close the debug console when measuring performance
+
+Cobalt provides a debug console in non-gold builds to allow the display
+of variables overlayed on top of the application. This can be helpful
+for debugging issues and keeping track of things like app lifetime, but
+the debug console consumes significant resources when it is visible in order
+to render it, so it should be hidden when performance is being evaluated.
+
+**Tags:** *framerate, startup, browse-to-watch, input latency.*
+
+
+### Toggle between dlmalloc and system allocator
+
+Cobalt includes dlmalloc and can be configured to use it to handle all
+memory allocations. It should be carefully evaluated however whether
+dlmalloc performs better or worse than your system allocator, in terms
+of both memory fragmentation efficiency as well as runtime performance.
+To use dlmalloc, you should adjust your starboard_platform.gyp file to
+use the Starboard [`starboard/memory.h`](../../starboard/memory.h) function
+implementations defined in
+[`starboard/shared/dlmalloc/`](../../starboard/shared/dlmalloc). To use
+your system allocator, you should adjust your starboard_platform.gyp file
+to use the Starboard [`starboard/memory.h`](../../starboard/memory.h) function
+implementations defined in
+[`starboard/shared/iso/`](../../starboard/shared/iso).
+
+**Tags:** *framerate, startup, browse-to-watch, input latency, cpu memory.*
+
+
+### Media buffer allocation strategy
+
+During video playback, memory is reserved by Cobalt to contain the encoded
+media data (separated into video and audio), and we refer to this memory
+as the media buffers. By default, Cobalt pre-allocates the memory and
+wraps it with a custom allocator, in order to avoid fragmentation of main
+memory. However, depending on your platform and your system allocator,
+overall memory usage may improve if media buffer allocations were made
+normally via the system allocator instead. This can be achieved by setting
+`cobalt_media_buffer_initial_capacity` and `cobalt_media_buffer_allocation_unit`
+to 0 in gyp_configuration.gypi. Note also that if you choose to pre-allocate
+memory, for 1080p video it has been found that 24MB is a good media buffer size.
+The pre-allocated media buffer capacity size can be adjusted by modifying the
+value of `cobalt_media_buffer_initial_capacity` mentioned above.
+
+**Tags:** *configuration_public.h, cpu memory.*
+
+
+### Adjust media buffer size settings
+
+Many of the parameters around media buffer allocation can be adjusted in your
+gyp_configuration.gypi file. The variables in question are the family of
+`cobalt_media_*` variables, whose default values are specified in
+[`cobalt_configuration.gypi`](../build/cobalt_configuration.gypi). In
+particular, if your maximum video output resolution is less than 1080, then you
+may lower the budgets for many of the categories according to your maximum
+resolution.
+
+**Tags:** *cpu memory*
+
+
+### Avoid using a the YouTube web app FPS counter (i.e. "?fps=1")
+
+The YouTube web app is able to display a Frames Per Second (FPS) counter in the
+corner when the URL parameter "fps=1" is set. Unfortunately, activating this
+timer will cause Cobalt to re-layout and re-render the scene frequently in
+order to update the FPS counter. Instead, we recommend instead to either
+measure the framerate in the GLES driver and periodically printing it, or
+hacking Cobalt to measure the framerate and periodically print it. In order to
+hack in an FPS counter, you will want to look at the
+`HardwareRasterizer::Impl::Submit()` function in
+[`cobalt/renderer/rasterizer/skia/hardware_rasterizer.cc`](../renderer/rasterizer/skia/hardware_rasterizer.cc).
+The work required to update the counter has the potential to affect many
+aspects of performance. TODO: Cobalt should add a command line switch to
+enable printing of the framerate in gold builds.
+
+**Tags:** *framerate, startup, browse-to-watch, input latency,*
+
+
+### Implement hardware image decoding
+
+The Starboard header file [`starboard/image.h`](../../starboard/image.h) defines
+functions that allow platforms to implement hardware-accelerated image
+decoding, if available. In particular, if `SbImageIsDecodeSupported()` returns
+true for the specified mime type and output format, then instead of using the
+software-based libpng or libjpeg libraries, Cobalt will instead call
+`SbImageDecode()`. `SbImageDecode()` is expected to return a decoded image as
+a `SbDecodeTarget` option, from which Cobalt will extract a GL texture or
+Blitter API surface object when rendering. If non-CPU hardware is used to
+decode images, it would alleviate the load on the CPU, and possibly also
+increase the speed at which images can be decoded.
+
+**Tags:** *startup, browse-to-watch, input latency.*
+
+
+### Use Chromium's about:tracing tool to debug Cobalt performance
+
+Cobalt has support for generating profiling data that is viewable through
+Chromium's about:tracing tool. This feature is available in all Cobalt
+configurations except for "gold" ("qa" is the best build to use for performance
+investigations here). There are currently two ways to tell Cobalt
+to generate this data:
+
+1. The command line option, "--timed_trace=XX" will instruct Cobalt to trace
+ upon startup, for XX seconds (e.g. "--timed_trace=25"). When completed,
+ the output will be written to the file `timed_trace.json`.
+2. Using the debug console (hit CTRL+O on a keyboard once or twice), type in
+ the command "h5vcc.traceEvent.start()" and hit enter. Cobalt will begin a
+ trace. After some time has passed (and presumably you have performed some
+ actions), you can open the debug console again and type
+ "h5vcc.traceEvent.stop()" again to end the trace.
+ The trace output will be written to the file `h5vcc_trace_event.json`.
+
+The directory the output files will be placed within is the directory that the
+Starboard function `SbSystemGetPath()` returns with a `path_id` of
+`kSbSystemPathDebugOutputDirectory`, so you may need to check your
+implementation of `SbSystemGetPath()` to discover where this is.
+
+Once the trace file is created, it can be opened in Chrome by navigating to
+`about:tracing` or `chrome://tracing`, clicking the "Load" button near the top
+left, and then opening the JSON file created earlier.
+
+Of particular interest in the output view is the `MainWebModule` thread where
+JavaScript and layout are executed, and `Rasterizer` where per-frame rendering
+takes place.
+
+**Tags:** *framerate, startup, browse-to-watch, input latency.*
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/platform_services.md b/src/cobalt/site/docs/gen/cobalt/doc/platform_services.md
new file mode 100644
index 0000000..309b578
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/platform_services.md
@@ -0,0 +1,111 @@
+---
+layout: doc
+title: "Cobalt Platform Services"
+---
+# Cobalt Platform Services
+
+_NOTE: The Cobalt Platform Services API replaces the deprecated Cobalt Custom Web API Extensions_
+
+## Overview
+
+The Cobalt Platform Services API aims to provide Cobalt users the ability to
+extend the web application functionality of Cobalt. This is done using runtime
+extensions provided by the Starboard layer without having to make any
+modifications to the common Cobalt code.
+
+Web applications running on Cobalt may want to implement a feature to have
+direct access to platform-specific services, on platforms where they are
+available.
+
+For example, a Cobalt implementation may want to enable the web application to:
+
+* Communicate directly with a service that is available on the platform
+* Surface platform-level status messages
+
+The Cobalt Platform Services API is an RPC interface and makes assumptions that
+communication with the service is in-process and 100% reliable, unlike sockets
+or HTTP. Out-of-process communications can be implemented as a layer on top of
+the interface.
+
+## Interface Definition
+
+The Cobalt Platform Services API is an RPC interface allowing for bidirectional
+communication between the web application and platform service. The interface
+is intentionally minimal, to avoid as much as possible the need to make changes
+to common Cobalt code. There will be two parallel interfaces, one between the
+web app and Cobalt specified via IDL, and another between Cobalt and the
+Starboard implementation specified via a Starboard interface header file.
+
+The interface provides a method of querying for services by name, where a name
+is some arbitrary string (Java naming convention recommended). The platform
+should maintain a registry mapping names to services and return the appropriate
+service for the given name. Once the application has obtained a handle to a
+service, it can send messages to the service using a `send()` function, which
+optionally may return immediate results. In addition, it can receive
+asynchronous incoming messages from the service via a receive callback
+registered when the service is opened. The `send()` function may fail, either
+because the service has already been closed by the application, or because of
+some state of the service and platform. When `send()` fails, it will raise an
+`kInvalidStateErr` exception, which may be caught & handled by the application.
+
+Any functionality in addition to the necessities provided by the interface must
+be implemented within the service’s protocol. For example, services may push a
+“version” message to the application immediately upon being opened in order to
+implement versioning.
+
+### IDL Interface
+
+The Platform Services extension is exposed to the web app via the following IDL:
+
+* [src/cobalt/h5vcc/h5vcc\_platform\_service.idl](../h5vcc/h5vcc_platform_service.idl)
+
+The entrypoint for defined Platform Services extensions will be accessible in
+the `H5vccPlatformService` object. Note that ArrayBuffers are chosen to
+represent arbitrary message data in order to leave open the possibility of
+passing binary data.
+
+### Starboard Interface
+
+Implementing the Starboard layer of Platform Service extension support uses the
+following interface in parallel with the IDL interface:
+
+* [src/cobalt/extension/platform\_service.h](../extension/platform_service.h)
+
+`CobaltExtensionPlatformServiceApi` is the main interface for the Starboard
+layer.
+
+### Naming Conventions for Service Names
+
+In order to guard against namespace pollution, the Java package naming
+convention is used for Platform Services.
+
+For example, some services names could be:
+
+* `com.google.android.CobaltPlatformService`
+* `com.<PARTNER>.<PLATFORM>.CobaltPlatformService`
+
+## Using a Cobalt Platforms Service Extension
+
+Assuming that the implementation work is completed for the IDL and
+complimentary Starboard interface, an example usage of an extension from the
+web application could look like the following:
+
+```
+var myCobaltPlatformService = "com.google.android.CobaltPlatformService";
+
+// checks if a platform has the specified service available
+H5vccPlatformService.has(myCobaltPlatformService);
+
+// attempting to open the specified service
+service = H5vccPlatformService.open(myCobaltPlatformService,
+ (service, data) => { console.log("do something") };
+
+// send some data
+var data = new ArrayBuffer(16);
+var view = new DataView(data);
+view.setInt32(0, 0x01234567);
+service.send(data);
+
+// close the service when we are done
+service.close();
+```
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/resources/clients_performance_guide/opacity_on_individuals.png b/src/cobalt/site/docs/gen/cobalt/doc/resources/clients_performance_guide/opacity_on_individuals.png
new file mode 100644
index 0000000..17116be
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/resources/clients_performance_guide/opacity_on_individuals.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/resources/clients_performance_guide/opacity_on_subtree.png b/src/cobalt/site/docs/gen/cobalt/doc/resources/clients_performance_guide/opacity_on_subtree.png
new file mode 100644
index 0000000..b3b1656
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/resources/clients_performance_guide/opacity_on_subtree.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/resources/devtools-overlay-console-modes.png b/src/cobalt/site/docs/gen/cobalt/doc/resources/devtools-overlay-console-modes.png
new file mode 100644
index 0000000..5103358
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/resources/devtools-overlay-console-modes.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/resources/webapi_extension_example.jpg b/src/cobalt/site/docs/gen/cobalt/doc/resources/webapi_extension_example.jpg
new file mode 100644
index 0000000..e9b43d1
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/resources/webapi_extension_example.jpg
Binary files differ
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/spherical_video.md b/src/cobalt/site/docs/gen/cobalt/doc/spherical_video.md
new file mode 100644
index 0000000..b82de1e
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/spherical_video.md
@@ -0,0 +1,76 @@
+---
+layout: doc
+title: "Enabling Spherical Video in Cobalt"
+---
+# Enabling Spherical Video in Cobalt
+
+Cobalt supports playback of 360 spherical videos. Cobalt does not expose
+this support to web applications through WebGL (which is currently
+unimplemented in Cobalt), but rather through a custom `map-to-mesh` CSS
+filter and custom [`window.camera3D` Web API](../dom/camera_3d.idl). Support
+for spherical video in Cobalt requires a GLES rasterizer (i.e. it is not
+supported for the Starboard Blitter API), and Starboard platform support for
+the player
+[decode-to-texture output mode](../../starboard/doc/howto_decode_to_texture.md).
+
+## Enabling spherical video support
+
+Spherical video support requires `map-to-mesh` support, which is enabled by
+default. You can explicitly disable it either through the command line switch
+`--disable_map_to_mesh` or by implementing the CobaltExtensionGraphicsApi
+function `IsMapToMeshEnabled()` to return `false`.
+
+When `map-to-mesh` is supported, Cobalt will make the `map-to-mesh` CSS filter
+parseable. The web app can then detect whether the browser, Cobalt, supports
+spherical video by evaluating the following JavaScript:
+
+```
+function checkForMapToMeshSupport() {
+ return 'CSS' in window && 'supports' in window.CSS &&
+ CSS.supports(
+ 'filter',
+ 'map-to-mesh(url(p.msh), 100deg 60deg,' +
+ 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1),' +
+ 'monoscopic)');
+}
+```
+
+It is required that your platform provides
+[decode-to-texture support](../../starboard/doc/howto_decode_to_texture.md).
+
+## Input
+
+Cobalt currently supports input mappings from the following keys (defined in [starboard/key.h](../../starboard/key.h)):
+
+ - `kSbKeyLeft`
+ - `kSbKeyUp`
+ - `kSbKeyRight`
+ - `kSbKeyDown`
+ - `kSbKeyGamepadDPadUp`
+ - `kSbKeyGamepadDPadDown`
+ - `kSbKeyGamepadDPadLeft`
+ - `kSbKeyGamepadDPadRight`
+ - `kSbKeyGamepadLeftStickUp`
+ - `kSbKeyGamepadLeftStickDown`
+ - `kSbKeyGamepadLeftStickLeft`
+ - `kSbKeyGamepadLeftStickRight`
+ - `kSbKeyGamepadRightStickUp`
+ - `kSbKeyGamepadRightStickDown`
+ - `kSbKeyGamepadRightStickLeft`
+ - `kSbKeyGamepadRightStickRight`
+
+Additionally, if your platform generates `kSbInputEventTypeMove` (from
+[starboard/input.h](../../starboard/input.h)) events with
+`SbInputData::position` set to values in the range `[-1, 1]`, for the following
+keys,
+
+ - `kSbKeyGamepadLeftStickUp`
+ - `kSbKeyGamepadLeftStickDown`
+ - `kSbKeyGamepadLeftStickLeft`
+ - `kSbKeyGamepadLeftStickRight`
+ - `kSbKeyGamepadRightStickUp`
+ - `kSbKeyGamepadRightStickDown`
+ - `kSbKeyGamepadRightStickLeft`
+ - `kSbKeyGamepadRightStickRight`
+
+then they will be treated as analog inputs when controlling the camera.
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/splash_screen.md b/src/cobalt/site/docs/gen/cobalt/doc/splash_screen.md
new file mode 100644
index 0000000..16651c3
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/splash_screen.md
@@ -0,0 +1,144 @@
+---
+layout: doc
+title: "Cobalt Splash Screen"
+---
+# Cobalt Splash Screen
+
+## Startup splash screen sequence
+
+There can be up to three splash screens shown when launching web applications on
+Cobalt:
+
+ * one from the system
+ * one from Cobalt
+ * one from the web application itself
+
+The system splash screen is often a transition from the application icon
+on the home screen to a static asset dictated by the platform (which is outside
+of Cobalt's control). The Cobalt splash screen is shown as soon as Cobalt can
+render until the web application is loaded. The web application splash screen is
+the HTML content shown immediately upon loading the web application (this may
+resemble a typical splash screen, but it really can be whatever the application
+chooses to show on starting).
+
+## Cobalt splash screen priority order
+
+The Cobalt splash screen must be specified as a URL to a document. The document
+must be either self-contained or all of its references must be local. That means
+the document should not reference any external CSS, JavaScript, or image files,
+for example. This simplifies the caching process so that only a single document
+must be cached without tracing references. All fallback splash screens must
+refer to local documents. This is so the fallback splash screen can be shown
+without latency and even when there is no network available. Specifically, the
+fallback splash screen URL and its references should start with either
+`file:///` or `h5vcc-embedded://`. Additionally `none` can be used to specify
+that no Cobalt splash screen should be constructed; the system splash sequence
+transitions directly into the application splash sequence once the page is
+loaded.
+
+The Cobalt splash screen is one of the following, in order of precedence:
+
+ 1. **Web cached splash screen:** If a splash screen specified by a web
+ application is cached from a previous instance of Cobalt, it will be loaded
+ at startup. The key for the cache splash screen is based on host & path of
+ the initial URL with no query or hash. If network connectivity is available
+ at startup, when the initial web application URL is processed, a custom
+ `rel="splashscreen"` attribute of the link element is used to specify and
+ cache the splashscreen URL for future runs.
+
+ 2. **Command line fallback splash screen:** This is specified as a command
+ line argument `--fallback_splash_screen_url` via the system and used when
+ cache is unavailable. This is the case when there is no local cache
+ storage, cache has been cleared, or the application is started for the
+ first time.
+
+ 3. **Build-time fallback splash screen:** If a web cached splash screen is
+ unavailable and command line parameters are not passed by the system,
+ a CobaltExtensionConfigurationApi fallback splash screen may be used.
+ Porters should set the `CobaltFallbackSplashScreenUrl` value in
+ `configuration.cc` to the splash screen URL.
+
+ 4. **Default splash screen:** If no web cached splash screen is available, and
+ command line and CobaltExtensionConfigurationApi fallbacks are not set, a
+ default splash screen will be used. This is set in
+ `configuration_defaults.cc` to refer to a black splash screen.
+
+## Web-updatability
+
+Since Cobalt parses the link element's `rel="splashscreen"` attribute for the
+splash screen URL in the content fetched from the initial URL, an application
+developer may update the splash screen by changing that attribute in the link
+element. On the next load of the application, the new splash screen will be
+cached, and on the subsequent load of the application, the new cached splash
+screen will be shown.
+
+For example, the document at the initial URL could contain
+```
+<link rel="splashscreen" href="https://www.example.com/self-contained.html">
+```
+where `"https://www.example.com/self-contained.html"` is the address of some
+self-contained splash screen document. The document must not violate the Content
+Security Policy. The splash screen is treated as a script resource by the CSP.
+
+### Caching implementation requirements
+
+In order to cache the application-provided splash screen, Cobalt will attempt
+to create directories and write files into the directory returned from a call to
+`SbSystemGetPath(kSbSystemPathCacheDirectory, ...)`. Cobalt will expect the
+data that it writes into that directory to persist across process instances.
+Cobalt will also need to read the cached splash screen from the cache directory
+when starting up.
+
+## Topic-specific splash screens
+
+It is possible to specify multiple splash screens for a given Cobalt-based
+application, using a start-up 'topic' to select between the available splash
+screens. This can be useful when an application has multiple entry points that
+require different splash screens. The topic may be specified in the start-up url
+or deeplink as a query parameter. For example,
+`https://www.example.com/path?topic=foo`. If a splash-screen has been specified
+for topic 'foo', it will be used. Otherwise, the topic is ignored. Topic values
+should be URL encoded and limited to alphanumeric characters, hyphens,
+underscores, and percent signs.
+
+There are three ways to specify topic-specific splash screens. These methods mirror
+the types of splash screens listed above, and unless specified, the rules here
+are the same as for non-topic-based splash screens.
+
+ 1. **Web cached splash screen:** A custom `rel="<topic>_splashscreen"`
+ attribute on a link element is used to specify a topic-specific splash
+ screen. There can be any number of these elements with different topics, in
+ addition to the topic-neutral `rel="splashscreen"`.
+
+ 2. **Command line fallback splash screen:** The command line argument
+ `--fallback_splash_screen_topics` can be used if the cache is unavailable.
+ The argument accepts a list of topic/file parameters. If a file is not a
+ valid URL path, then it will be used as a filename at the path specified by
+ `--fallback_splash_screen_url`. For example,
+ `foo_topic=file:///foo.html&bar=bar.html`.
+
+ 3. **Build-time fallback splash screen:** If a web cached splash screen is
+ unavailable and command line parameters are not passed by the system, a
+ CobaltExtensionConfigurationApi fallback splash screen may be used. Porters
+ should set the `CobaltFallbackSplashScreenTopics` value in
+ `configuration.cc` and this value should look like the command line option.
+
+## Application-specific splash screens
+
+On systems that plan to support multiple Cobalt-based applications, an
+application developer may wish to use the command line arguments for the
+fallback splash screen to display different Cobalt splash screens for different
+applications. The logic for passing in these different command line arguments to
+the Cobalt binary must be handled by the system.
+
+Alternatively, an application developer may use the default black splash screen
+whenever a cached splash screen is not available and rely on the web application
+to specify an application-specific cached splash screen otherwise.
+
+## Provided embedded resource splash screens
+For convenience, we currently provide the following splash screens as embedded
+resources:
+
+ * `h5vcc-embedded://black_splash_screen.html` - a black splash screen
+ * `h5vcc-embedded://cobalt_splash_screen.html` - a splash screen showing the
+ Cobalt logo
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/versioning.md b/src/cobalt/site/docs/gen/cobalt/doc/versioning.md
new file mode 100644
index 0000000..020d607
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/versioning.md
@@ -0,0 +1,82 @@
+---
+layout: doc
+title: "Cobalt Versioning"
+---
+# Cobalt Versioning
+
+Cobalt versions, as they appear in the user agent, have the following structure:
+
+**[Feature Year]**.**[Purpose]**.**[Update Number]**.**[Build ID]**
+
+The meansions of these components are described below.
+
+Example Cobalt versions would be:
+
+ * `19.lts.1.40455`
+ * `19.lts.2.53047`
+ * `20.lts.1.64553`
+
+## Feature Year
+
+Cobalt features are tied to a yearly release cycle and this number indicates
+the yearly feature set that this version of Cobalt supports. It is the last
+two digits of the year of the target feature set. For example for the 2019
+feature set, this value will be `19`.
+
+## Purpose
+
+The purpose of this build, usually named after the reason that a branch is cut.
+On the master branch it will be `master`, and on LTS branches for example it
+will be `lts`.
+
+## Update Number
+
+The current update revision number (e.g. release number) for a given pair of
+values above. This will always be `0` on the master branch. When a release
+branch is cut, will be modified to start at `1`, and be incremented each time a
+release or update is released. It is possible that multiple updates are
+released off of the same release branch, if new bugs are discovered and fixed.
+
+## Build ID
+
+The Cobalt Build ID represents **fine-grained** information about the state of
+the source tree for a given build. An internal Cobalt build server generates a
+monotonically increasing number for each unique set of sources that it
+sees. When an open-source release is published,
+a [`src/cobalt/build/build.id`](../build/build.id) file is included that
+specifies the build ID of that source release. The Cobalt team can reproduce the
+exact sources for a given Build ID.
+
+Note that since the Build ID always increases with time, it means that the
+latest version of an older Cobalt release can have a higher Build ID than the
+latest version of a new Cobalt release. An example from above: Cobalt `4.16134`
+was produced earlier than Cobalt `3.16138`, thus has a lower Build ID.
+
+## Older Cobalt versioning scheme
+
+A Cobalt version consists of two components: The Release Number and the Build
+ID. Some real historical Cobalt version examples:
+
+ * `2.15147`
+ * `3.16138`
+ * `4.16134`
+ * `6.18971`
+
+You get the idea. The number before the dot is the "Release Number." The number
+after the dot is the "Build ID."
+
+### Release Number
+
+In older Cobalt versioning schemes, a "Cobalt release" is an official, tested
+version of Cobalt that is intended to be deployable to production. The
+"Release Number" is a single counting number, starting at "1" for our first
+release, and increasing by one for every release thereafter. This number is
+checked into [`src/cobalt/version.h`](../version.h), and represents **coarse**
+information about the state of the source tree when we decided to do a release.
+
+It is important to note that there are no point releases, or major or minor
+releases. Each release gets its own unique counting number.
+
+## Other Reading
+
+ * [Cobalt Branching](branching.md)
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/voice_search.md b/src/cobalt/site/docs/gen/cobalt/doc/voice_search.md
new file mode 100644
index 0000000..f5d54a2
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/voice_search.md
@@ -0,0 +1,69 @@
+---
+layout: doc
+title: "Enabling voice search in Cobalt"
+---
+# Enabling voice search in Cobalt
+
+Cobalt enables voice search through either:
+
+1. A subset of the [MediaRecorder Web API](https://www.w3.org/TR/mediastream-recording/#mediarecorder-api).
+2. A subset of the [Speech Recognition Web API](https://w3c.github.io/speech-api/#speechreco-section)
+
+Only one or the other can be used, and we recommend that the MediaRecorder API
+is followed, as we are considering deprecating the Speech Recognition API.
+
+**The Speech Recognition API is deprecated as of Starboard 13.**
+
+In both approaches, in order to check whether to enable voice control or not,
+web apps will call the [MediaDevices.enumerateDevices()](https://www.w3.org/TR/mediacapture-streams/#dom-mediadevices-enumeratedevices%28%29)
+Web API function within which Cobalt will in turn call a subset of the
+[Starboard SbMicrophone API](../../starboard/microphone.h).
+
+## MediaRecorder API
+
+To enable the MediaRecorder API in Cobalt, the complete
+[SbMicrophone API](../../starboard/microphone.h) must be implemented, and
+`SbSpeechRecognizerIsSupported()` must return `false`.
+
+## Speech Recognition API - Deprecated
+
+**The Speech Recognition API is deprecated as of Starboard 13.**
+
+In order to provide support for using this API, platforms must implement the
+[Starboard SbSpeechRecognizer API](../../starboard/speech_recognizer.h) as well
+as a subset of the [SbMicrophone API](../../starboard/microphone.h).
+
+### Specific instructions to enable voice search
+
+1. Implement `SbSpeechRecognizerIsSupported()` to return `true`, and implement
+ the [SbSpeechRecognizer API](../../starboard/speech_recognizer.h).
+2. Implement the following subset of the
+ [SbMicrophone API](../../starboard/microphone.h):
+ - `SbMicrophoneGetAvailable()`
+ - `SbMicrophoneCreate()`
+ - `SbMicrophoneDestroy()`
+
+ In particular, SbMicrophoneCreate() must return a valid microphone. It is
+ okay to stub out the other functions, e.g. have `SbMicrophoneOpen()`
+ return `false`.
+3. The YouTube app will display the mic icon on the search page when it detects
+ valid microphone input devices using `MediaDevices.enumerateDevices()`.
+4. With `SbSpeechRecognizerIsSupported()` implemented to return `true`, Cobalt
+ will use the platform's
+ [Starboard SbSpeechRecognizer API](../../starboard/speech_recognizer.h)
+ implementation, and it will not actually read directly from the microphone
+ via the [Starboard SbMicrophone API](../../starboard/microphone.h).
+
+### Differences from versions of Cobalt <= 11
+
+In previous versions of Cobalt, there was no way to dynamically disable
+speech support besides modifying common Cobalt code to dynamically stub out the
+Speech Recognition API when the platform does not support microphone input.
+This is no longer necessary, web apps should now rely on
+`MediaDevices.enumerateDevices()` to determine whether voice support is enabled
+or not.
+
+### Speech Recognition API is deprecated in Starboard 13 ###
+
+Web applications are expected to use the MediaRecorder API. This in turn relies
+on the SbMicrophone API as detailed above.
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/web_debugging.md b/src/cobalt/site/docs/gen/cobalt/doc/web_debugging.md
new file mode 100644
index 0000000..eb46b28
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/web_debugging.md
@@ -0,0 +1,292 @@
+---
+layout: doc
+title: "Cobalt Web Debugging"
+---
+# Cobalt Web Debugging
+
+## Overview
+
+Cobalt includes the [Chrome
+DevTools](https://developers.google.com/web/tools/chrome-devtools/) frontend for
+debugging web apps. It's available in the **20.lts.1+** and newer branches of
+Cobalt.
+
+Cobalt only supports a subset of what DevTools can do, but we make a point of
+hiding UI elements that don't work so everything you see in the UI should work.
+As we get more implemented in the backend the respective UI will be enabled in
+the frontend.
+
+The following panels are supported:
+
+* **Elements** - view the DOM tree and CSS styles
+* **Console** - JavaScript "command line" and logging output
+* **Sources** - interactive JavaScript debugging
+* **Performance** - profile JavaScript execution
+
+## Using DevTools
+
+The DevTools frontend is loaded in Chrome from a small HTTP server built into
+**non-gold** Cobalt. Even though it looks mostly the same as Chrome's inspector
+(it's built from the same source code), Cobalt's DevTools is a separate app,
+and Cobalt is *not* a remote target that you can debug with Chrome's built-in
+debugger.
+
+After building and running Cobalt as usual, use Chrome on your desktop to load
+the start page from port 9222 on the target device where Cobalt is running.
+Click through to the only inspectable page shown on the start page.
+
+> If you have trouble connecting:
+> * Ensure you have an IP route from your desktop to the target device that
+> allows traffic on the debugging port (default 9222).
+> * If you are running Cobalt locally on your desktop, then use
+> http://localhost:9222 since the Linux build only listens to the loopback
+> network interface by default.
+
+If you're not sure what IP address to use, look in the terminal log output for a
+message telling you the URL of Cobalt's DevTools (which you may be able to open
+with a ctrl-click in many terminal programs):
+
+```
+---------------------------------
+ Connect to the web debugger at:
+ http://192.168.1.1:9222
+---------------------------------
+```
+
+### Wait for web debugger
+
+If you're debugging the initial page as it's loading you need use the
+`--wait_for_web_debugger` switch to tell Cobalt to wait until you attach
+DevTools before actually loading the initial URL:
+
+```
+out/linux-x64x11_devel/cobalt --wait_for_web_debugger --url="http://test.example.com"
+```
+
+When this switch is specified, Cobalt will appear to hang with just a black
+window until you load DevTools. In the terminal log output you'll see that
+Cobalt is waiting with message like:
+
+```
+-------------------------------------
+ Waiting for web debugger to connect
+-------------------------------------
+```
+
+If you're debugging a page in a series of redirects, you can specify a number to
+make Cobalt wait before loading the Nth page. If no number is specified with the
+switch, the default value is 1 to wait before the initial page load. For
+example:
+
+```
+out/linux-x64x11_devel/cobalt --wait_for_web_debugger=2 --url="http://test.example.com"
+```
+
+## Panels
+
+### Elements
+
+The Elements panel displays the DOM as a tree with expandable nodes to dig into
+it. The right side bar shows the CSS styles affecting the selected node in the
+DOM. The *Styles* tab shows matching rules, inherited rules, and inline style.
+The *Computed* tab shows the computed style for the selected node. The box model
+properties are shown graphically in both the *Styles* and *Computed* tabs.
+
+> Cobalt currently only supports a read-only view of the DOM and CSS.
+
+Chrome docs:
+
+* https://developers.google.com/web/tools/chrome-devtools/dom/
+* https://developers.google.com/web/tools/chrome-devtools/css/
+
+### Console
+
+Cobalt has two types of consoles:
+
+* Overlay Console: shown at runtime of Cobalt. It has multiple mode that it
+ can cycle between as well:
+ * HUD
+ * HUD & Debug Console
+ * Media Console
+* Remote Console: shown in a connected devtools session.
+
+Both console UIs show messages logged from JavaScript (with `console.log()`,
+etc.), and have a command line to evaluate arbitrary JavaScript in the context
+of the page being debugged.
+
+#### Overlay Console
+
+The overlay console also shows non-JavaScript logging from Cobalt itself, which
+is mostly interesting to Cobalt developers rather than web app developers.
+
+The various modes of the overlay console are accessed by repeatedly pressing
+"`F1`" or "`Ctrl+O`". They cycle in order between: none, HUD, HUD & Debug, and
+Media. Alternatively, initial console state can be set with the
+`--debug_console=off|hud|debug|media` command-line switch (`--debug_console=on`
+is accepted as a legacy option and maps to "debug" setting).
+
+![Overlay Console mode switching](resources/devtools-overlay-console-flow.png)
+
+##### HUD overlay
+
+This brings up an overlay panel which does not block sending input to the
+underlying Cobalt app. It serves to display real-time statistics (e.g. memory
+usage) and configuration values (e.g. disabled codecs) of the Cobalt app in a
+compact string.
+
+##### Debug Console overlay
+
+This overlay is interactive and it shows messages from Cobalt, along with logs
+from Javacript `console.log()`. While it is active, you cannot interact directly
+with the underlying page.
+
+Additionally, it can act as a JS interpreter that will evaluate arbitrary
+expressions on the page being debugged. The output from these JS commands will
+also be printed to the Debug console.
+
+Finally, it has some special debug commands which can be listed by calling
+`d.help()`. They are provided by a debug helper object and the list of functions
+are invoked by prepending either "`debug`" or "`d`". For example, you can
+disable the vp9 codec manually for all future played videos in this session of
+Cobalt by sending `debug.disable_media_codecs("vp9")` to the console.
+
+Note: you can clear the disabled media codecs by sending
+`debug.disable_media_codecs("")`. The command takes a semicolon separated list
+of codecs as the input list of codecs to disable.
+
+##### Media Console overlay
+
+The media console is a specialized console of the debug overlay system, for
+playback and media related tasks. The current list of implemented features are:
+
+* Reading the play/pause state of the primary video
+* Reading the current time and duration of the primary video
+* Reading the playback rate of the primary video
+* Reading the currently disabled codecs for the player
+* Toggling between playing and pausing the primary video
+* Setting the current playback rate between various presets for the primary
+ video
+* Toggling the enabled/disabled state of the available codecs
+
+While the media console is shown, it is not possible to interact with the page
+below it directly.
+
+Additionally, the console does not show any meaningful information or
+interactions when no video is currently playing (all the readouts are blank or
+undefined). A status message of “No primary video.” indicates there is no valid
+player element on the current page.
+
+In the case of multiple videos playing (such as picture in picture), only the
+primary (fullscreen) video’s information is shown and the controls are only
+enabled for the primary video.
+
+The list of hotkeys and commands are dynamically generated as they are found to
+be available on app startup.
+
+Basic always-enabled commands are (case-sensitive):
+
+* "`p`" Toggle the play/pause state
+* "`]`" Increase the playback rate
+* "`[`" Decrease the playback rate
+
+The above commands will take effect instantly for the currently playing video.
+They have no effect if there is no video playing.
+
+The following commands are dynamically loaded based on the capability of the
+system:
+
+* "`CTRL+NUM`" Enable/disable specific video codec
+* "`ALT+NUM`" Enable/disable specific audio codec
+
+**Important:** Media Console cannot be used to directly select a specific codec for
+playback. See the section below for rough outline of steps to work around this.
+
+The list of available codecs for any video is chosen based on the decoders on
+the platform, and what formats YouTube itself serves. As a result, the only way
+to get a particular codec to play is to disable all the options until the
+desired codec is the one that is picked. Simply do the following procedure:
+
+* Pick the video you want to play.
+* Enable “stats for nerds” (See [help page for
+ instructions](https://support.google.com/youtube/answer/7519898)).
+* Write down the codecs that are chosen when playing the video, without any
+ codecs disabled (one for video, and one for audio).
+* Disable the default codecs.
+* Replay the same video from the browse screen.
+* Repeat until you identify all codecs that are available for the video, until
+ the video is unable to be played.
+* Use the above knowledge to disable the codecs to force the player into
+ choosing a particular codec, by process of elimination.
+
+**Important:** Disabled codecs only take effect when a video starts playing.
+When you play a video, the current list of disabled codecs is used to select an
+arbitrary enabled format. When you seek in the video, the disabled codecs list
+does not take effect. Only when you exit the player and re-enter by playing a
+video will any toggled codecs be affected.
+
+**Important:** Disabled codecs list is persistent for the app-run. If you
+disable “av01”, then until you re-enable it, “av01” formats will never be
+chosen.
+
+**Important:** If you disable all the available codecs, no video codec can be
+selected and an error dialog will be shown. This means that YouTube does not
+have the video in any other formats, outside of the codecs that are disabled.
+The player reports that it cannot play the video in any of the available formats
+so playback will fail here, which is intended.
+
+#### Remote Console
+
+The console in DevTools is a richer UI that can show evaluated objects with an
+expander so you can dig in to their properties. Logging from JavaScript with
+`console.log()` can show objects and exceptions as well, in contrast to the
+text-only messages shown in the console overlay.
+
+Chrome docs:
+
+* https://developers.google.com/web/tools/chrome-devtools/console/
+
+### Sources
+
+Source-level JavaScript debugging can be done on the Sources panel. You can
+inspect sources, set breakpoints, see call stacks and scoped variables, add
+watch expressions, and all that good stuff.
+
+> Source debugging only works when Cobalt is built with V8.
+
+Chrome docs:
+
+* https://developers.google.com/web/tools/chrome-devtools/javascript/
+
+### Performance
+
+The Performance panel allows you to record a profile of sampled call stacks
+while Cobalt is running your JavaScript code. The recorded profile is displayed
+in a flame chart showing the relationship and timing of function calls.
+
+> Performance profiling only works when Cobalt is built with V8, and the
+> platform implements the `SbThreadSampler` Starboard API.
+
+> The profiler can't currently identify which is the main thread, but you can
+> easily see it as the one with the most events.
+
+Chrome docs:
+
+* https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/
+
+## Tips
+
+* You can make Cobalt reload the current page by pressing F5 in the Cobalt
+ window, or ctrl-R in the remote DevTools. This may be useful for debugging
+ startup code in the web app. It may also help in case some source file is
+ not appearing in the DevTools Sources panel.
+
+* The DevTools frontend remembers your breakpoints, so if you need to restart
+ Cobalt completely you can just kill it with ctrl-C in the terminal where you
+ launched it and re-run it. Then click the *Reconnect DevTools* button shown
+ in the DevTools UI or refresh the page to reload the DevTools UI.
+
+* You can use the `--remote_debugging_port` command line switch to specify a
+ remote debugging port other than the default 9222.
+
+* You can use the `--dev_servers_listen_ip` command line switch to change
+ which network interface the remote debugging server is listening to.
diff --git a/src/cobalt/site/docs/gen/cobalt/doc/webapi_extension.md b/src/cobalt/site/docs/gen/cobalt/doc/webapi_extension.md
new file mode 100644
index 0000000..f3c7b42
--- /dev/null
+++ b/src/cobalt/site/docs/gen/cobalt/doc/webapi_extension.md
@@ -0,0 +1,113 @@
+---
+layout: doc
+title: "Cobalt Web Extension Support"
+---
+# Cobalt Web Extension Support
+
+## Deprecation
+Please note that Web Extension support is deprecated. Please use Platform
+Services (cobalt/doc/platform_services.md) instead. This is an effort to move
+away from injecting compile-time modules into the Cobalt layer in favor of
+using runtime extensions provided by the Starboard layer.
+
+## Overview
+Cobalt provides a facility for extending the JavaScript Web API. This allows
+custom web apps running on Cobalt to make calls through a custom API to
+C++ Cobalt code defined per Starboard platform. This can allow for closer
+integration between the web app hosted by Cobalt and the system on which that
+web app is running.
+
+The Cobalt Web Extension support will allow you to attach an instance of a
+custom class to the JavaScript `window` global object so that it can be
+referenced from a web app in JavaScript as in the following example:
+
+```
+window.myInterface.RunMyFunction()
+```
+
+## Build-level modifications
+
+In order to extend the interface, one should add the following lines to the
+`variables` section of `<platform-directory>/cobalt/configuration.gypi` (see
+Starboard's
+[Application Customization](../../starboard/doc/building.md#application-customization)
+for more information):
+
+1. `cobalt_webapi_extension_source_idl_files`
+ This should be a list of [IDL files](https://en.wikipedia.org/wiki/Web_IDL)
+ that define the collection of new interfaces introduced by your extensions.
+ One of these new interfaces can be selected to be injected into the `window`
+ element (see 3. `cobalt_webapi_extension_gyp_target` for information on how
+ to do this). Each IDL file listed here simultaneously defines a JavaScript
+ and a C++ interface. For each IDL file, you will be expected to also provide
+ a header file in the same directory that re-declares (in C++) the interface
+ declared in the IDL file, as well as an implementation of all the methods
+ within it (either inline in the header file or in a corresponding source
+ file).
+2. `cobalt_webapi_extension_generated_header_idl_files`
+ This is a list of all files that may result in automatic header file
+ generation that might be referenced from other C++ code. An example of
+ this is the definition of `enum`s that may then be referenced as types in
+ a file from 1. `cobalt_webapi_extension_source_idl_files`.
+3. `cobalt_webapi_extension_gyp_target`
+ This is the gyp target that will provide the IDL interface implementations,
+ as well as any necessary auxiliary code. It will be added as a dependency of
+ [browser/cobalt.gyp:cobalt](../browser/cobalt.gyp). It is expected that
+ this target will implement the interface defined in
+ [browser/webapi_extension.h](../browser/webapi_extension.h), which let you
+ name the injected window property, and provide a function to instantiate it
+ (i.e. to let you select which IDL object is the "entry point").
+
+The first two lists get included by
+[cobalt/browser/browser_bindings_gen.gyp](cobalt/browser/browser_bindings_gen.gyp),
+where you can look to see many examples of existing Cobalt IDL files that define
+the Web API available through Cobalt. For each of these, you can also
+examine their corresponding `.h` files and in most cases their `.cc` files as
+well.
+
+An example configuration for these variables is available at
+[starboard/shared/test_webapi_extension/test_webapi_extension.gypi](../../starboard/shared/test_webapi_extension/test_webapi_extension.gypi), which
+contains the following variable definitions:
+
+```
+'cobalt_webapi_extension_source_idl_files': [
+ 'my_new_interface.idl'
+],
+'cobalt_webapi_extension_generated_header_idl_files': [
+ 'my_new_enum.idl'
+],
+'cobalt_webapi_extension_gyp_target':
+ '<(DEPTH)/starboard/shared/test_webapi_extension/webapi_extension.gyp:cobalt_test_webapi_extension',
+```
+
+## Implementing the [webapi_extension.h](../browser/webapi_extension.h) interface
+
+As discussed above in 3. `cobalt_webapi_extension_gyp_target`, you must provide
+an implementation of the two functions declared in
+[browser/webapi_extension.h](../browser/webapi_extension.h).
+
+### `GetWebAPIExtensionObjectPropertyName()`
+You should implement `GetWebAPIExtensionObjectPropertyName()` to return the name
+of the injected `window` property. For example, in the example from the
+beginning of this document, `window.myInterface.RunMyFunction()`, we would have
+the function return `std::string("myInterface")`. If you return `nullopt` from
+this function, it is assumed that you do not wish to extend the web interface.
+
+Note that you should NOT name your `window` property the same as your class name
+as described in the IDL file, it will result in a name collision in the
+JavaScript environment.
+
+### `CreateWebAPIExtensionObject()`
+This function should instantiate and return the object to be accessed from
+`window`. The object must be defined by an IDL file.
+
+## Debugging
+You may find the Cobalt debug console to be particularly useful for debugging
+IDL additions and changes. In it, you can enter arbitrary JavaScript and then
+hit enter to execute it. You can toggle it open by hitting either CTRL+O or
+F1, and you may have to hit the key twice to skip past the HUD mode.
+
+Here is an example of an example interface being exercised through the
+debug console:
+
+![Debug console web extension example](resources/webapi_extension_example.jpg)
diff --git a/src/cobalt/site/docs/gen/starboard/build/doc/gn_migrate_stub_to_platform.md b/src/cobalt/site/docs/gen/starboard/build/doc/gn_migrate_stub_to_platform.md
new file mode 100644
index 0000000..f717d32
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/build/doc/gn_migrate_stub_to_platform.md
@@ -0,0 +1,132 @@
+---
+layout: doc
+title: "Stub to Platform GN Migration"
+---
+# Stub to Platform GN Migration
+
+This document outlines a step by step process for converting the stub platform's
+GN files to GN files that will be able to be built for your platform. It assumes
+you have an already working port of Starboard using GYP.
+
+## Steps to Migrate Stub Files to your platform's GN Files
+
+This is **one** way for migrating your platform from GYP to GN. The benefit of
+following this is that you can have regular checkpoints to see if your migration
+is going correctly, rather than trying to do the entire migration at once where
+it's uncertain how much progress is being made. \
+Here are the steps to do your migration:
+
+1. [Copy stub files over to your platform and build them](#copy-stub-files-over-to-your-platform-and-build-them).
+2. [Replace stub toolchain with your platform's toolchain](#replace-stub-toolchain-with-your-platforms-toolchain).
+3. [Replace stub configuration with your platform's configuration](#replace-stub-configuration-with-your-platforms-configuration).
+4. [Replace stubbed starboard_platform target sources with your platform's
+ sources](#replace-stubbed-starboardplatform-sources-with-your-platforms-sources).
+
+After each step, you should be able to build the starboard_platform target.
+For example, you would build raspi2 starboard_platform target with the following
+commands:
+```
+$gn gen out/raspi-2gn_devel --args='target_platform="raspi-2" build_type="devel"'
+$ninja -C out/raspi-2gn_devel/ starboard
+```
+
+### Copy Stub Files Over to Your Platform and Build Them
+
+Here is a list of steps outlining which files to copy over and how to build
+those files:
+
+1. Copy over files from the stub implementation to the platform folder. This
+ list gives you an example of which files to copy over for your platform.
+ This is an example for files to be copied over for your platform's port at
+ starboard/YOUR_PLATFORM
+ * starboard/stub/BUILD.gn > starboard/YOUR_PLATFORM/BUILD.gn
+ * starboard/stub/platform_configuration/BUILD.gn >
+ starboard/YOUR_PLATFORM/platform_configuration/BUILD.gn
+ * starboard/stub/platform_configuration/configuration.gni >
+ starboard/YOUR_PLATFORM/platform_configuration/configuration.gni
+ * starboard/stub/toolchain/BUILD.gn >
+ starboard/YOUR_PLATFORM/toolchain/BUILD.gn
+2. Add your platform path to starboard/build/platforms.gni as referenced
+ [here](../migrating_gyp_to_gn.md#adding-your-platform-to-starboard)
+3. Resolve any errors which come up for missing/incorrect file paths. Then, you
+ should be able to build your platform target with the stubbed out files
+ suggested in the above section.
+
+### Replace Stub Toolchain with Your Platform's Toolchain
+
+Follow instructions [here](../migrating_gyp_to_gn.md#migrating-a-toolchain) for
+migrating the toolchain. Resolve errors and build the starboard_platform target
+with the stubbed files.
+
+### Replace Stub Configuration with Your Platform's Configuration
+
+This involves migrating the compiler flags and build variables as referenced
+[here](../migrating_gyp_to_gn.md#migrating-a-platform).
+
+> **Highly recommended** \
+> It’s good to turn off the `treat_warnings_as_errors flag` until you can compile
+> the starboard_platform target with the platform files.
+> If this flag is not disabled you might run into a lot of
+> warnings turned errors and it might take time to solve all those errors.
+> Meanwhile you won't be in a buildable state which might make it uncertain as to
+> how much progress you are actually making.
+> For disabling the flag you can pass that as an argument to gn.
+> Here's an example for disabling the flag for raspi2:
+> ```
+> $gn gen out/raspi-2gn_devel --args='target_platform="raspi-2" build_type="devel" treat_warnings_as_errors=false'
+> ```
+
+Resolve errors and build the starboard_platform target with the stubbed files.
+
+### Replace Stubbed starboard_platform Sources with Your Platform's Sources
+
+This involves adding files for the starboard_platform target as suggested
+[here](../migrating_gyp_to_gn.md#migrating-a-platform).
+
+While building any target, follow the recommendation above of building the
+target with `treat_warnings_as_errors=false`.
+
+Once you can build your platform files, you can remove the
+`treat_warnings_as_errors=false` flag and resolve the warning errors.
+
+## FAQ
+
+1. **I’m getting a build error! What should I do?** \
+ Some common questions to ask yourself:
+
+ * Is the same target building with GYP + ninja (as GN + Ninja)?
+
+ > For example if the `nplb` target is not being built by GN, check first
+ > if it can be built with GYP. If GYP cannot build it, this indicates
+ > that some flags are missing in GYP itself so it might be prudent to
+ > solve that first before migrating to GN.
+
+ * Am I missing a config/dependency to include the missing file?
+
+ > [gn check](https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/reference.md#cmd_check)
+ > can help point out missing dependencies.
+
+ * Is the same file being included in the build by GYP?
+
+ > Add a preprocessor directive like #error "This file is included" in
+ > that file and see if GYP + Ninja prints out that error message.
+
+ * Is the same code path being followed by GYP + ninja ?
+
+ > Use the same method as above.
+
+ * Are the compiler flags for this file the same as in GYP ?
+
+ > To compare flags for GYP vs GN refer
+ > [section](../migrating_gyp_to_gn.md#validating-a-target). To check if
+ > the variables/flags you are compiling have changed since GYP, refer
+ > [page](../migration_changes.md).
+
+ * Have you passed in the default arguments for your platform correctly?
+
+ > Default variables such as `target_cpu`, `target_os` and others can be
+ > overridden by passing arguments to gn while building. Here's an
+ > example of passing the default argument `target_cpu` for raspi2:
+ > ```
+ > $gn gen out/raspi-2gn_devel --args='target_platform="raspi-2" build_type="devel" target_cpu="arm"'
+ > ```
diff --git a/src/cobalt/site/docs/gen/starboard/build/doc/migrating_gyp_to_gn.md b/src/cobalt/site/docs/gen/starboard/build/doc/migrating_gyp_to_gn.md
new file mode 100644
index 0000000..07b4968
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/build/doc/migrating_gyp_to_gn.md
@@ -0,0 +1,262 @@
+---
+layout: doc
+title: "Migrating GYP to GN"
+---
+# Migrating GYP to GN
+
+Cobalt is currently in the process of migrating from our current build system
+which uses [GYP][gyp_home] to an updated one with
+[Generate Ninja (GN)][gn_home]. This allows us to remove our dependencies on
+Python 2.
+
+## Getting Started with GN
+
+### Getting the Binary
+
+There are a few ways to get a binary. Follow the instructions for whichever way
+you prefer [here][gn_getting_a_binary].
+
+### Read the Docs
+
+Most of the documentation for GN is located [here][gn_doc_home].
+
+* For a hands-on example with GN, check out the
+ [Quick Start Guide][gn_quick_start] and walk through the example.
+
+* To learn more about the language and coding in it, read through the
+ [Language page][gn_language] and the [Style Guide][gn_style_guide].
+
+* For a full reference of the language, run `gn help` or use the
+ [Reference page][gn_reference].
+
+If you're familiar with GYP but not with GN, it may be helpful to read
+Chromium's [GYP->GN Conversion Cookbook][gyp_to_gn_cookbook]. Keep in mind we
+don't want to follow everything that's recommended here—much of the advice is
+specific to Chromium. In particular:
+
+* Whenever possible, avoid using a `source_set`. Instead, use a
+ `static_library`.
+* Many of the flags under [Variable Mappings][gyp_to_gn_variable_mappings] do
+ not apply to Cobalt.
+* Cobalt code is not Chromium code by default, so you can ignore
+ [that section][gyp_to_gn_chromium_code].
+
+### Know the Tools
+
+The flow of GN is fairly similar to that of GYP: you'll configure a build then
+actually build it (using ninja). Here's how to build `nplb` target for
+`stub_debug`:
+
+```
+$ gn gen out/stub_debug --args='target_platform="stub" build_type="debug"'
+$ ninja -C out/stub_debug nplb
+```
+
+You can change the directory argument to `gn gen` (`out/stub_debug`) if you'd
+like; unlike GYP, we can put the build root wherever we want.
+
+There are some additional important tools: `gn format`, which is a code
+formatter for GN, and `gn check`, which checks that build dependencies are
+correctly set. See the documentation for [gn format][gn_format_tool] and
+[gn check][gn_check_tool] for how to use both. The full list of commands GN
+supports can be found on the [reference page][gn_reference].
+
+## Migrating a Single Target
+
+GYP and GN are very similar within the scope of a single target. The GYP->GN
+Conversion Cookbook is a good reference for this, particularly
+[this section][gyp_to_gn_typical_modifications]. The GYP syntax stays very
+similar in general, though configuration will differ: in GN, you should create a
+`config` targets and have your target add that to their list of configs:
+
+```
+config("foo_config") {
+ cflags = ...
+}
+
+static_library("foo") {
+ sources = ...
+ deps = ...
+
+ configs += [ ":foo_config" ]
+}
+```
+
+You also may need to remove default configs. The default configs are listed in
+[BUILDCONFIG.gn](../config/BUILDCONFIG.gn). You remove a config like so:
+
+```
+static_library("foo") {
+ configs -= [ "//full/path/to/config:config_name" ]
+}
+```
+
+## Migrating a Platform
+
+When porting your platform with GYP following
+[the porting guide][cobalt_porting_guide], we expected a few build files to be
+present under your starboard path:
+
+* `gyp_configuration.py`
+* `gyp_configuration.gypi`
+* `starboard_platform.gyp`
+
+These contain your toolchain, your compilation flags, your platform-specific
+build variables, and your definition of the `starboard_platform` target. This
+maps to the GN files needed to port your platform:
+
+* Your toolchain: `toolchain/BUILD.gn`
+* Your compilation flags: `platform_configuration/BUILD.gn`
+* Your platform-specific build variables:
+ `platform_configuration/configuration.gni`
+* Your definition of the `starboard_platform` target: `BUILD.gn`
+
+Some of these files need to define certain targets:
+
+* `toolchain/BUILD.gn`
+
+ The toolchain implementation is discussed in more detail
+ [below](#migrating-a-toolchain).
+
+ ```
+ toolchain("host") {
+ ...
+ }
+
+ toolchain("target") {
+ ...
+ }
+ ```
+
+* `platform_configuration/BUILD.gn`
+
+ ```
+ config("platform_configuration") {
+ # Set the flags that were in gyp_configuration.gypi.
+ }
+ ```
+
+* `BUILD.gn`
+
+ ```
+ static_library("starboard_platform") {
+ # Largely the same as the current starboard_platform.gyp.
+ }
+ ```
+
+### Adding Your Platform to Starboard
+
+Instead of implicitly searching directories for certain files like GYP did, we
+explicitly enumerate our ports and their locations.
+[platforms.gni](../platforms.gni) contains all of this information, and you'll
+need to add your platform to that list following the same format.
+
+### Migrating a Family of Platforms
+
+Cobalt's reference platforms when implemented in GYP mainly used variables to
+share sources and dependencies. In GN, we prefer putting shared sources and
+dependencies in a static_library that we depend on in the final
+`starboard_platform` `static_library` target. This means that configurations to
+particular files should be in the same `static_library` that files are in.
+
+### Migrating a Toolchain
+
+Cobalt expects you to set a target and a host toolchain for your build like so:
+
+```
+toolchain("host") {
+ ...
+}
+
+toolchain("target") {
+ ...
+}
+```
+
+You may define a toolchain from scratch following the [reference][gn_toolchain],
+or you can use the
+[gcc/clang templates](../../../build/toolchain/gcc_toolchain.gni) provided.
+Almost all of the reference platforms use these templates, so look to those as
+examples for how to use it correctly. Here's the linux-x64x11
+[toolchain/BUILD.gn file](../../linux/x64x11/toolchain/BUILD.gn).
+
+## Checking Your Migration
+
+There are a few different ways to ensure you've migrated a target successfully.
+You'll of course want to make sure you can build things after you've migrated
+them.
+
+### Validating a Target
+
+If you're migrating a single target, it's simple to check: just configure the
+build using the the necessary arguments then build that target with `ninja`,
+i.e.:
+
+```
+static_library("new_target") { ... }
+```
+
+```
+$ gn gen out/stub_debug --args='target_platform="stub" build_type="debug"'
+$ gn check out/stub_debug
+$ ninja -C out/stub_debug new_target
+```
+
+If this was equivalent to a GYP target, you can compare the ninja compilation
+databases by using [format_ninja.py](../../../tools/format_ninja.py) and a
+comparison tool, i.e. [meld](https://meldmerge.org/). This will allow you to see
+any changes in commands, i.e. with flags or otherwise.
+
+The following differences for ninja flags between GYP and GN don't cause any
+issues:
+
+1. The name of the intermediate .o, .d files is different in both cases: Here is
+ an example while compiling the same source file
+ ```
+ starboard/common/new.cc
+ ```
+ GYP generates:
+ ```
+ obj/starboard/common/common.new.cc.o
+ ```
+ GN generates:
+ ```
+ obj/starboard/common/common/new.o
+ ```
+2. The `-x` flag for specifying language is not present in GN migration.
+ For example GYP specifies `-x c` flag while building c language files for
+ certain targets. This flag is not specified while building any GN targets.
+
+### Validating a Platform
+
+Checking that an entire platform has been migrated successfully is slightly more
+involved. It can be easiest to start by copying provided stub implementation and
+continuously migrating it over, checking that it builds as you go along. If you
+don't go this route, you can instead start by building a small target (with few
+dependencies) then work your way up to building the `all` target.
+
+You can use the same comparison method of using `format_ninja.py` as discussed
+[in the section above](#validating-a-target).
+
+### Step by Step Stub to Your Platform Migration Guide
+
+This [document](../gn_migrate_stub_to_platform.md) outlines a step by step
+process for converting the stub platform's GN files to GN files that will be
+able to be built for your platform.
+
+[cobalt_porting_guide]: https://cobalt.dev/starboard/porting.html
+[gn_check_tool]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/reference.md#cmd_check
+[gn_doc_home]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs
+[gn_format_tool]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/reference.md#cmd_format
+[gn_getting_a_binary]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/#getting-a-binary
+[gn_home]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/
+[gn_language]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/language.md
+[gn_reference]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/reference.md
+[gn_style_guide]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/style_guide.md
+[gn_toolchain]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/reference.md#func_toolchain
+[gn_quick_start]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/quick_start.md
+[gyp_home]: https://gyp.gsrc.io/index.md
+[gyp_to_gn_chromium_code]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/cookbook.md#chromium-code
+[gyp_to_gn_cookbook]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/cookbook.md
+[gyp_to_gn_typical_modifications]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/cookbook.md#typical-sources-and-deps-modifications
+[gyp_to_gn_variable_mappings]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/cookbook.md#variable-mappings
diff --git a/src/cobalt/site/docs/gen/starboard/build/doc/migration_changes.md b/src/cobalt/site/docs/gen/starboard/build/doc/migration_changes.md
new file mode 100644
index 0000000..38d8477
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/build/doc/migration_changes.md
@@ -0,0 +1,72 @@
+---
+layout: doc
+title: "GYP to GN Migration Changes"
+---
+# GYP to GN Migration Changes
+
+This file tracks changes to configuration meta build configuration variables in
+the GYP to GN migration. Reference the table below to find the correct GN
+equivalent to a changed variable, deprecated GYP variables not in GN, and added
+variables.
+
+## Variable Changes
+
+*GYP* | *GN* | *GN import*
+:---------------------------------------- | :--------------------------------------------------- | :----------
+`OS` ("starboard"/other) | `is_starboard` (true/false) | (global)
+`clang` (0/1) | `is_clang` (true/false) | (global)
+`has_input_events_filter` | `is_internal_build` (true/false) | (global)
+`has_drm_system_extension` | `is_internal_build` (true/false) | (global)
+`has_cdm` | `is_internal_build` (true/false) | (global)
+`has_private_system_properties` | `is_internal_build` (true/false) | (global)
+`sb_deploy_output_dir` | `sb_install_output_dir` | `//starboard/build/config/base_configuration.gni`
+`sb_evergreen` (0/1) | `sb_is_evergreen` (true/false) | `//starboard/build/config/base_configuration.gni`
+`sb_evergreen_compatible` (0/1) | `sb_is_evergreen_compatible` (true/false) | `//starboard/build/config/base_configuration.gni`
+`sb_evergreen_compatible_libunwind` (0/1) | `sb_evergreen_compatible_use_libunwind` (true/false) | `//starboard/build/config/base_configuration.gni`
+`sb_evergreen_compatible_lite` (0/1) | `sb_evergreen_compatible_enable_lite` (true/false) | `//starboard/build/config/base_configuration.gni`
+`sb_disable_cpp14_audit` | (none) |
+`sb_disable_microphone_idl` | (none) |
+`starboard_path` | (none) |
+`tizen_os` | (none) |
+`includes_starboard` | (none) |
+(none) | `has_platform_tests` (true/false) | `//starboard/build/config/base_configuration.gni`
+(none) | `has_platform_targets` (true/false) | `//starboard/build/config/base_configuration.gni`
+(none) | `install_target_path` (true/false) | `//starboard/build/config/base_configuration.gni`
+
+## Other Changes
+
+*GYP* | *GN* | *Notes* (see below)
+:------------------------------ | :---------------------------------------------------- | :------------------
+`'STARBOARD_IMPLEMENTATION'` | `"//starboard/build/config:starboard_implementation"` | Starboard Implementation
+`optimize_target_for_speed` (0) | `"//starboard/build/config:size"` | Optimizations
+`optimize_target_for_speed` (1) | `"//starboard/build/config:speed"` | Optimizations
+`compiler_flags_*_speed` | `speed_config_path` | Optimizations
+`compiler_flags_*_size` | `size_config_path` | Optimizations
+`sb_pedantic_warnings` | `pedantic_warnings_config_path` | Compiler Options
+`sb_pedantic_warnings` | `no_pedantic_warnings_config_path` | Compiler Options
+
+Notes:
+
+* *Starboard Implementation:* If your platform defined
+ `STARBOARD_IMPLENTATION` in its implementation, you would now add the above
+ config with `configs +=
+ ["//starboard/build/config:starboard_implementation"]`.
+
+* *Optimizations:* Cobalt defaults to building targets to optimize for size.
+ If you need to optimize a target for speed, remove the size config and add
+ the speed config with `configs -= [ "//starboard/build/config:size" ]` and
+ `configs += [ "//starboard/build/config:speed" ]`. You can define these
+ configurations for your platform by creating `config`s and pointing to the
+ correct ones for `speed_config_path` and `size_config_path` in your
+ platform's `platform_configuration/configuration.gni` file.
+
+* *Compiler Options:* Cobalt compiles some targets with stricter settings
+ than others, depending on the platform. Before these targets would opt into
+ the stricter settings by settings `sb_pedantic_warnings: 1` in their
+ `variables` section. Now they will add the appropriate config like so:
+ `configs += [ "//starboard/build/config:pedantic_warnings" ]` and remove
+ the default: `configs -= [ "//starboard/build/config:no_pedantic_warnings"
+ ]`. The additional config that is used to compile these targets is
+ specified with the `pedantic_warnings_config_path` and
+ `no_pedantic_warnings_config_path` variables in your platform's
+ `platform_configuration/configuration.gni` file.
diff --git a/src/cobalt/site/docs/gen/starboard/doc/abstract-toolchain.md b/src/cobalt/site/docs/gen/starboard/doc/abstract-toolchain.md
new file mode 100644
index 0000000..c60daa1
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/abstract-toolchain.md
@@ -0,0 +1,57 @@
+---
+layout: doc
+title: "Abstract Toolchain"
+---
+# Abstract Toolchain
+
+## Motivation
+
+The aim of implementing an Abstract Toolchain is to allow porters to add
+new toolchains or customize existing ones without the need of modifying
+common code.
+
+Initially all targets were defined in one common shared file,
+`src/tools/gyp/pylib/gyp/generator/ninja.py`.
+Modifications to this file were required for replacing any of the toolchain
+components, adding platform-specific tooling, adding new toolchains, or
+accomodating platform-specific flavor of reference tool. Doing this in a
+shared file does not scale with the number of ports.
+
+## Overview
+
+The solution implemented to solve toolchain abstraction consists of adding two
+new functions to the platform specific `gyp_configuration.py` file found under:
+
+`starboard/<PLATFORM>/gyp_configuration.py`
+
+The functions to implement are:
+
+`GetHostToolchain` and `GetTargetToolchain`
+
+## Example
+
+The simplest complete GCC based toolchain, where a target and host are the same,
+and all tools are in the PATH:
+
+ class ExamplePlatformConfig(starboard.PlatformConfig)
+ # ...
+
+ def GetTargetToolchain(self):
+ return [
+ starboard.toolchains.gnu.CCompiler(),
+ starboard.toolchains.gnu.CPlusPlusCompiler(),
+ starboard.toolchains.gnu.Assembler(),
+ starboard.toolchains.gnu.StaticLinker(),
+ starboard.toolchains.gnu.DynamicLinker(),
+ starboard.toolchains.gnu.Bison(),
+ starboard.toolchains.gnu.Stamp(),
+ starboard.toolchains.gnu.Copy(),
+ ]
+
+ def GetHostToolchain(self):
+ return self.GetTargetToolchain()
+
+You can find real examples of this in the Open Source repo:
+[Linux x8611](https://cobalt.googlesource.com/cobalt/+/refs/heads/21.lts.1+/src/starboard/linux/x64x11/gyp_configuration.py)
+
+[Raspberry Pi 2](https://cobalt.googlesource.com/cobalt/+/refs/heads/21.lts.1+/src/starboard/raspi/shared/gyp_configuration.py)
diff --git a/src/cobalt/site/docs/gen/starboard/doc/api_process.md b/src/cobalt/site/docs/gen/starboard/doc/api_process.md
new file mode 100644
index 0000000..0d699d2
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/api_process.md
@@ -0,0 +1,72 @@
+---
+layout: doc
+title: "Starboard API Review Process"
+---
+# Starboard API Review Process
+
+## Why do we need a process?
+The Starboard API is the contract between Starboard applications and
+implementors of the Starboard API. Changing existing APIs and adding new
+required APIs breaks that contract and increases the cost of implementors
+keeping their Starboard port up-to-date. Pushing a release to the Open Source
+repository signals to Starboard implementors that any non-experimental APIs in
+that version will not change for as long as that version of Starboard is
+supported by the Starboard applications. We cannot change those newly frozen
+APIs without causing a potentially significant disruption to any partners who
+have already implemented them, or are in the process of implementing them.
+
+While having a process may make it harder to add new things to Starboard, it is
+much harder to remove or change things that are already there.
+
+Thus we need to give special focus to changes to the Starboard API to ensure its
+consistency with existing APIs design principles. Unnecessary churn on the
+Starboard API creates more work for Starboard application developers and may
+discourage porters from keeping Starboard applications up-to-date on their
+platforms. This process is intended to save time and effort for both Starboard
+application developers and Starboard implementors in the long run, and
+illustrates the complexity of dealing with a wide variety of platforms
+simultaneously.
+
+## So you want to add a new API?
+Historically, we have done API review as a part of the Code Review process using
+Gerrit. This works well for small-ish changes. For larger changes, consider
+writing a design document up front before defining the new API.
+
+### Who does the review?
+Send a message to the public cobalt-dev group to request a review.
+
+### What is the process?
+Developers are strongly encouraged to create the interface and upload that to
+Gerrit for review before spending time on stubs and tests. Iteration on the
+interface will necessarily result in changes to the stubs and tests, which can
+result in more work for the implementer of a new API.
+
+1. Upload a .h file with Module Overview and (optionally) initial function
+ prototypes
+ * New APIs should be declared in the experimental version, as described in the
+ starboard versioning doc.
+2. Discuss the new API with whoever is performing the review, and address
+ comments.
+3. Iterate.
+ * As a part of the review process, the reviewer will work with you to ensure
+ that the new API adheres to the starboard principles.
+4. Finalize function declarations.
+5. Implement tests and stubs.
+ * Existing platforms on trunk should not break as a result of this change.
+ * At this point, you may submit the interface, tests, and stubs with your
+ reviewer’s +2.
+6. Implement the interface for at least one platform.
+7. Iterate
+8. It may be that implementation of the API reveals things that were overlooked
+ during the earlier stages of the review.
+
+Ideally most major points of feedback will be caught early in the review process
+before much time has been spent on implementation.
+In the case that the platform in (6) is an internal platform, provide a
+reference implementation for at least one external reference platform. This can
+be in a follow-up CL, but must be implemented before the new API is frozen
+(see [versioning.md](versioning.md)).
+
+## How to design a new API
+See [principles.md](principles.md) for a guide on how to design a good Starboard
+API.
diff --git a/src/cobalt/site/docs/gen/starboard/doc/building.md b/src/cobalt/site/docs/gen/starboard/doc/building.md
new file mode 100644
index 0000000..0281e71
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/building.md
@@ -0,0 +1,99 @@
+---
+layout: doc
+title: "Building Starboard"
+---
+# Building Starboard
+
+Starboard currently uses GYP as the basis of its build system, though there is
+already some movement towards GN as a replacement.
+
+While you can integrate Starboard into any build system, there are enough knobs
+and dials that it would be a daunting effort. Instead, Starboard tries to provide a
+functional build framework that an application developer can easily integrate with.
+
+
+## The Flow
+
+The basic flow of how Starboard builds is:
+
+1. `starboard/build/gyp` - Parse command line parameters and pass them into
+ `GypRunner`.
+2. `starboard/build/gyp_runner.py`
+ 1. Load the `PlatformConfiguration`.
+ 2. Load the `ApplicationConfiguration`.
+ 3. Calculate and merge the GYP includes, GYP variables, environment
+ variables, and generator variables, and pass them into GYP.
+3. tools/gyp - Parse all the .gyp and included .gypi files, generate ninja.
+4. ninja - Build all the source files.
+
+
+## The Platform vs. the Application
+
+In this documentation, you will see a lot of discussion about things being
+Platform or Application concerns.
+
+The Platform is more-or-less what you think it is -- Everything you might need
+to build any Starboard Application on a given platform.
+
+It helps to think about an Application as a broader concept than a single
+program. From Starboard's build system's perspective, an Application is a
+*single configuration of build variables per platform*, which may produce many
+build targets beyond a single executable - shared libraries, tests, and so on.
+
+
+## Application Customization
+
+Each Application will probably want to define its own knobs, dials, and defaults
+to be able to be customized per platform, and so Starboard provides a space for
+the Application to do that.
+
+Each Application can provide a platform-specific ApplicationConfiguration
+instance by creating a python module in
+`<platform-directory>/<application-name>/configuration.py`. This module must
+contain a class definition that extends from
+`starboard.build.application_configuration.ApplicationConfiguration`. If the
+class is not found in the platform-specific location, a generic configuration
+will be loaded, as dictated by the `APPLICATIONS` registry in
+`starboard_configuration.py`.
+
+Additionally, the Application can provide a GYPI file to be included at
+`<platform-directory>/<application-name>/configuration.gypi`. This will, by
+default, be included at the end of all other configuration GYPI files, but this
+behavior can be arbitrarily customized by the loaded `ApplicationConfiguration`
+class.
+
+
+## HOWTO: Create a new Application
+
+1. Create your Application's root `.gyp` file. Often called `all.gyp` or
+ something similar.
+
+2. Create a cross-platform `ApplicationConfiguration` python class for your
+ application. Take a look at
+ [`cobalt_configuration.py`](../../cobalt/build/cobalt_configuration.py) as an
+ example.
+
+ Define a subclass of
+ `starboard.build.application_configuration.ApplicationConfiguration` and
+ override any desired methods. In particular, you probably at least want to
+ override the `GetDefaultTargetBuildFile()` method to point at your root
+ `.gyp` file from step 1.
+
+3. Register your Application in your `starboard_configuration.py` file in your
+ source tree root.
+
+ To do this, just add an entry to the `APPLICATIONS` Mapping that maps your
+ canonical Application name to the cross-platform `ApplicationConfiguration`
+ subclass constructor for your application.
+
+ APPLICATIONS = {
+ # ...
+
+ 'example_app': example_app.ExampleAppConfiguration
+
+ # ...
+ }
+
+At this point, you should be able to build your application with:
+
+ starboard/build/gyp -a <application-name>
diff --git a/src/cobalt/site/docs/gen/starboard/doc/c99.md b/src/cobalt/site/docs/gen/starboard/doc/c99.md
new file mode 100644
index 0000000..3aed66d
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/c99.md
@@ -0,0 +1,82 @@
+---
+layout: doc
+title: "Starboard and C99"
+---
+# Starboard and C99
+
+## Background
+
+Historically Starboard did not allow usage of standard C symbols in order to
+isolate Cobalt from non-compliant libc implementations and to provide a single,
+consistent behavior at the Starboard API layer.
+
+## C99 Usage Rationale
+1. Inconsistencies in the libc libraries are rare and all third party libraries
+need to be ported to the Starboard API. This can be a significant maintenance
+cost as the dependencies need to be periodically rebased.
+
+2. Even with all the efforts to use POEM headers from the
+[starboard/client_porting](../../starboard/client_porting) directory many
+non-Evergreen platforms still have a lot of direct system dependencies. These
+dependencies do not exist for Evergreen platforms as Cobalt is statically
+linked with the [musl](../../third_party/musl/musl.gyp) libc library.
+
+3. Starting with Starboard 13 a limited set of C99 symbols will be allowed.
+This set will expand gradually while the corresponding Starboard APIs will be
+deprecated and eventually removed.
+
+## List of Allowed C99 Symbols
+### <ctype.h>
+* isalnum
+* isdigit
+* isspace
+* isupper
+* isxdigit
+* tolower
+* toupper
+### <math.h>
+* fabs
+* floor
+* isfinite
+* isnan
+* pow
+* sqrt
+* sqrtf
+### <stdlib.h>
+* abs
+* atoi
+* atol
+* bsearch
+* strtof
+* strtod
+* strtol
+* strtoll
+* strtoul
+* strtoull
+* qsort
+### <string.h>
+* memchr
+* memcmp
+* memcpy
+* memmove
+* memset
+* strcat
+* strchr
+* strcmp
+* strcspn
+* strlen
+* strncmp
+* strncat
+* strrchr
+* strstr
+* strspn
+### <wchar.h>
+* wcscat
+* wcschr
+* wcslen
+* wmemchr
+* wmemcmp
+* wmemcpy
+* wmemmove
+* wmemset
+* wcsncmp
diff --git a/src/cobalt/site/docs/gen/starboard/doc/crash_handlers.md b/src/cobalt/site/docs/gen/starboard/doc/crash_handlers.md
new file mode 100644
index 0000000..2f30683
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/crash_handlers.md
@@ -0,0 +1,56 @@
+---
+layout: doc
+title: "Installing Crash Handlers in Cobalt"
+---
+# Installing Crash Handlers in Cobalt
+
+Partners can install Crashpad's crash handlers to create crash reports in the
+cache directory. This is done by:
+
+1. Adding the following files to the `starboard_platform` target's sources:
+
+```
+'<(DEPTH)/starboard/shared/starboard/crash_handler.cc',
+'<(DEPTH)/starboard/shared/starboard/crash_handler.h',
+```
+
+2. Handling `kCobaltExtensionCrashHandlerName` in the implementation of
+`SbSystemGetExtension`:
+
+```
+#include "starboard/system.h"
+
+#include "cobalt/extension/crash_handler.h"
+#include "starboard/shared/starboard/crash_handler.h"
+
+...
+
+const void* SbSystemGetExtension(const char* name) {
+
+ ...
+
+ if (SbStringCompareAll(name, kCobaltExtensionCrashHandlerName) == 0) {
+ return starboard::common::GetCrashHandlerApi();
+ }
+ return NULL;
+}
+```
+
+3. Calling the `third_party::crashpad::wrapper::InstallCrashpadHandler()` hook
+directly after installing system crash handlers. On linux, for example, this
+could look like:
+
+```
+#include "third_party/crashpad/wrapper/wrapper.h"
+
+int main(int argc, char** argv) {
+ ...
+ starboard::shared::signal::InstallCrashSignalHandlers();
+ starboard::shared::signal::InstallSuspendSignalHandlers();
+
+ third_party::crashpad::wrapper::InstallCrashpadHandler();
+
+ int result = application.Run(argc, argv);
+ ...
+}
+```
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_evergreen_lite.md b/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_evergreen_lite.md
new file mode 100644
index 0000000..93ff983
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_evergreen_lite.md
@@ -0,0 +1,182 @@
+---
+layout: doc
+title: "Evergreen Lite Partner Doc"
+---
+Evergreen Lite Partner Doc
+
+
+## What is Cobalt Evergreen Lite?
+
+Evergreen Lite is a Cobalt configuration similar to Evergreen Full. Evergreen
+Lite takes advantage of the same Evergreen software architecture, but removes
+the need for additional storage and is missing the defining cloud-based Cobalt
+Updater feature used in Evergreen Full.
+
+Evergreen Lite relies on separating the Starboard (platform) and Cobalt (core)
+components of a Cobalt implementation into the following discrete components:
+
+![Evergreen Lite Overvew](resources/evergreen_lite_overview.png)
+
+## Components
+
+Google-built (on Google toolchain)
+
+
+* Cobalt Core
+ * Pre-built shared library available for all supported architectures
+* Cobalt Updater - disabled
+
+Partner-built (on Partner toolchain)
+
+
+
+* Starboard
+ * Platform-specific implementation
+ * Contains system dependencies (e.g. libpthread.so, libEGL.so)
+* Cobalt Loader (Loader App)
+ * Loads the Cobalt core shared library
+ * An ELF loader is used to load the Cobalt core and resolves symbols with
+ Starboard APIs when Cobalt starts up in Evergreen mode
+* Crash handler
+ * Uploads crash reports to Google server when crash happens
+
+With this new Cobalt Evergreen platform architecture, less engineering effort is
+ necessary for a full Cobalt integration/deployment.
+
+**The idea here is you should only need to implement Starboard one time (as
+long as the Starboard API version is supported by Cobalt), and any Cobalt
+Core-level binary updates are provided by Google with pre-built
+configurations/symbols via our open-source releases
+([GitHub](https://github.com/youtube/cobalt/releases))**. These pre-built
+Cobalt Core Evergreen binaries should be a direct replacement to update Cobalt
+without any engineering work required. As Cobalt Core binaries are pre-built,
+they should only require platform testing. NOTE that certain new Cobalt
+features may require Starboard changes, so if you want to take advantage of
+some of these new features, Starboard changes may be necessary.
+
+### Benefits compared to non-Evergreen
+
+* Less engineering work/accelerated timeline for Cobalt
+integration/deployment as Google builds Cobalt core code and partners only need
+to build and maintain the Starboard layer
+* Performance enhancements as the Cobalt core is built with modern toolchain
+* Crash reports are uploaded to Google backend and monitored by Google, so
+they can be acted on and addressed more quickly
+
+### New in Evergreen Lite compared to non-Evergreen
+
+* New `loader_app` and `crashpad_handler` components required to be built
+on platform toolchains
+* No Cobalt Core customization is allowed because the vanilla Cobalt Core
+binary is provided by Google.
+
+### Differences compared to Evergreen Full
+
+* The Google-control cloud-based automatic updates are disabled. Instead,
+Cobalt provides the update binary to partners, and partners control the release
+process
+* No extra storage required comparing to the existing software requirements
+
+## How is Evergreen different from porting Cobalt previously?
+
+Same as the [Evergreen full doc](cobalt_evergreen_overview.md).
+
+## Building Cobalt Evergreen Components
+
+`kSbSystemPathStorageDirectory` is not required to implement. Set both
+`sb_evergreen_compatible` and `sb_evergreen_compatible_lite` to `1`s in the `gyp`
+platform config. The remaining is the same as the Evergreen full doc.
+
+## How does the update work with Evergreen Lite?
+
+Cobalt will release the Cobalt Core binary to partners for each Cobalt LTS
+major and minor release, and partners decide whether to update their devices
+with the latest Cobalt Core code via firmware OTA update. To update, partners
+only need to put the new Cobalt Core binary at the system image location under
+`<kSbSystemPathContentDirectory>/app/cobalt`. More about the system image slot
+is explained below.
+
+## Platform Requirements
+
+Cobalt Evergreen currently supports the following
+
+Target Architectures:
+
+* `x86_32`
+* `x86_64`
+* `armv7 32`
+* `armv8 64`
+
+Supported Javascript Engines
+
+* V8
+
+## Building and Running Tests
+
+Same as the Evergreen Full doc -
+[cobalt_evergreen_overview.md](cobalt_evergreen_overview.md).
+
+## System Design
+
+### Cobalt Evergreen Components
+
+Cobalt updater is disabled. The binary will not check for updates by sending
+requests to the Google update server, nor download updates from the Google
+Download server.
+
+### Cobalt Evergreen Interfaces
+
+Same as the Evergreen Full doc -
+[cobalt_evergreen_overview.md](cobalt_evergreen_overview.md).
+
+### System Image Slot
+
+Evergreen Lite will have only one system image slot. This is stored in the
+directory specified by `kSbSystemPathContentDirectory` under the
+`app/cobalt` subdirectory.
+
+```
+.
+├── content <--(kSbSystemPathContentDirectory)
+│ └── fonts <--(kSbSystemPathFontDirectory, `standard` or `limit` configuration)
+│ └── app
+│ └── cobalt <--(System image, provided by Google)
+│ ├── content <--(relative path defined in kSystemImageContentPath)
+│ │ ├── fonts <--(`empty` configuration)
+│ │ ├── icu
+│ │ ├── licenses
+│ │ ├── ssl
+│ ├── lib
+│ │ └── libcobalt.so
+│ └── manifest.json
+└── loader_app <--(Cobalt loader binary)
+└── crashpad_handler <--(Cobalt crash handler binary)
+```
+
+### Fonts
+
+Same as the Evergreen Full doc -
+[cobalt_evergreen_overview.md](cobalt_evergreen_overview.md).
+
+## How to run Evergreen Lite
+
+Launch Cobalt with the loader app binary with the `evergreen_lite` flag
+
+```
+$ ./loader_app --evergreen_lite
+```
+## FAQ
+
+### What’s the path from Evergreen Lite to Evergreen Full?
+
+* Provision storage for the installation slots to contain downloaded update
+binaries - `kSbSystemPathStorageDirectory `and configure the slots as instructed
+in the Evergreen full doc
+* Configure icu table under `kSbSystemPathStorageDirectory` to be shared
+ among slots
+* Set `sb_evergreen_compatible_lite` to 0
+* Implement the handling of pending updates
+* Rebuild and rerun `nplb_evergreen_compat_tests`
+* Launch Cobalt with loader app without the `evergreen_lite` flag
+
+More details can be found in the Evergreen Full doc.
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_evergreen_overview.md b/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_evergreen_overview.md
new file mode 100644
index 0000000..4e07d8e
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_evergreen_overview.md
@@ -0,0 +1,728 @@
+---
+layout: doc
+title: "Cobalt Evergreen Overview"
+---
+# Cobalt Evergreen Overview
+
+![Cobalt non-Evergreen vs
+Evergreen](resources/cobalt_evergreen_overview_flow.png)
+
+## What is Cobalt Evergreen?
+
+Cobalt Evergreen is an end-to-end framework for cloud-based deployment of Cobalt
+updates without the need for supplemental Cobalt integration work on device
+platforms.
+
+There are two configurations available:
+* Evergreen-Lite
+ * Please read this document for general Evergreen details then see
+ Evergreen-Lite specific configuration details in
+ [cobalt_evergreen_lite.md](cobalt_evergreen_lite.md)
+* Evergreen Full
+ * Please continue reading below documentation for configuration details
+
+![Cobalt Evergreen Configurations](resources/cobalt_evergreen_configurations.png)
+
+For a bit of background context, as the number of Cobalt devices in the field
+increases there is a growing proliferation of version fragmentation. Many of
+these devices are unable to take advantage of the benefits of Cobalt
+performance, security, and functional improvements as it is costly to integrate
+and port new versions of Cobalt. We recognized this issue, listened to feedback
+from the Cobalt community and as a result developed Cobalt Evergreen as a way to
+make updating Cobalt a much simpler process for everyone involved.
+
+This relies on separating the Starboard(platform) and Cobalt(core) components of
+a Cobalt implementation into the following discrete components:
+
+**Google-built** (on Google toolchain)
+
+* Cobalt Core
+ * Pre-built shared library available for all supported architectures
+* Cobalt Updater
+ * Part of Cobalt Core and used to query servers to check for and download
+ updated Cobalt Core
+
+**Partner-built** (on Partner toolchain)
+
+* Starboard
+ * Platform-specific implementation
+ * Contains system dependencies (e.g. `libpthread.so`, `libEGL.so`)
+* Cobalt Loader (Loader App)
+ * Selects the appropriate Cobalt core for usage
+ * An ELF loader is used to load the Cobalt core and resolves symbols with
+ Starboard APIs when Cobalt starts up in Evergreen mode
+
+With this new Cobalt platform architecture, less engineering effort is necessary
+for a full Cobalt integration/deployment. The idea here is you should only need
+to implement Starboard one time and any Cobalt-level updates should only require
+platform testing. NOTE that certain new Cobalt features may require Starboard
+changes, so if you want to take advantage of some of these new features,
+Starboard changes may be necessary.
+
+### Main Benefits
+
+* More stable platform as there is less Cobalt version fragmentation
+* Little-to-no engineering effort necessary for Cobalt updates
+* Longer device lifetime due to more Cobalt updates
+* Less engineering work/accelerated timeline for Cobalt integration/deployment
+ as Google builds the Cobalt components and partners are only responsible for
+ the Starboard, `loader_app`, and `crashpad_handler` portion
+
+### New in Evergreen
+
+* Larger storage and system permissions requirements in order to update and
+ store multiple Cobalt binaries
+* Access permissions to download binaries onto a device platform from Google
+ servers
+* New `loader_app` and `crashpad_handler` components required to be built on
+ platform toolchains
+* Additional testing/verification required to ensure new Cobalt releases work
+ properly
+
+## How is Evergreen different from porting Cobalt previously?
+
+There are minimal differences in switching to Evergreen as the Cobalt team has
+already done a majority of the work building the necessary components to support
+the Evergreen architecture. You will still be responsible for building the
+Starboard and platform-specific components as usual. Thereafter, switching to
+Evergreen is as simple as building a different configuration. Please see the
+Raspberry Pi 2 Evergreen reference port
+([Instructions](cobalt_evergreen_reference_port_raspi2.md)) for an example.
+
+![Cobalt non-Evergreen vs
+Evergreen](resources/cobalt_evergreen_overview_vs_non_evergreen.png)
+
+### Building Cobalt Evergreen Components
+
+Cobalt Evergreen requires that there are two separate build(`gyp`)
+configurations used due to the separation of the Cobalt core(`libcobalt.so`) and
+the platform-specific Starboard layer(`loader_app`). As a result, you will have
+to initiate a separate gyp process for each. This is required since the Cobalt
+core binary is built with the Google toolchain settings and the
+platform-specific Starboard layer is built with partner toolchain
+configurations.
+
+Cobalt Evergreen is built by a separate gyp platform using the Google toolchain:
+
+```
+$ cobalt/build/gyp_cobalt evergreen-arm-softfp-sbversion-12
+$ ninja -C out/evergreen-arm-softfp-sbversion-12_qa cobalt
+```
+
+Which produces a shared library `libcobalt.so` targeted for specific
+architecture, ABI and Starboard version.
+
+The gyp variable `sb_evergreen` is set to 1 when building `libcobalt.so`.
+
+The partner port of Starboard is built with the partner’s toolchain and is
+linked into the `loader_app` which knows how to dynamically load
+`libcobalt.so`, and the `crashpad_handler` which handles crashes.
+
+```
+$ cobalt/build/gyp_cobalt <partner_port_name>
+$ ninja -C out/<partner_port_name>_qa loader_app crashpad_handler
+```
+
+Partners should set `sb_evergreen_compatible` to 1 in their gyp platform config.
+DO NOT set the `sb_evergreen` to 1 in your platform-specific configuration as it
+is used only by Cobalt when building with the Google toolchain.
+
+Additionally, partners should install crash handlers as instructed in the
+[Installing Crash Handlers for Cobalt guide](../crash_handlers.md).
+
+The following additional Starboard interfaces are necessary to implement for
+Evergreen:
+
+* `kSbSystemPathStorageDirectory`
+ * Dedicated location for storing Cobalt Evergreen-related binaries
+ * This path must be writable and have at least 96MB of reserved space for
+ Evergreen updates. Please see the “Platforms Requirements” section below
+ for more details.
+* `kSbMemoryMapProtectExec`
+ * Ensures mapped memory can be executed
+* `#define SB_CAN_MAP_EXECUTABLE_MEMORY 1`
+ * Specifies that the platform can map executable memory
+ * Defined in `configuration_public.h`
+
+Only if necessary, create a customized SABI configuration for your architecture.
+Note, we do not anticipate that you will need to make a new configuration for
+your platform unless it is not one of our supported architectures:
+
+* x86\_32
+* x86\_64
+* arm32
+* arm64
+
+If your target architecture falls outside the support list above, please reach
+out to us for guidance.
+
+#### Adding Crash Handlers to Evergreen
+
+### What is an example for how this would help me?
+
+Some common versions of Cobalt in the field may show a bug in the implementation
+of the CSS which can cause layout behavior to cause components to overlap and
+give users a poor user experience. A fix for this is identified and pushed to
+Cobalt open source ready for integration and deployment on devices.
+
+#### Without Cobalt Evergreen:
+
+Though a fix for this was made available in the latest Cobalt open source,
+affected devices in the field are not getting updated (e.g. due to engineering
+resources, timing, device end-of-life), users continue to have a poor experience
+and have negative sentiment against a device. In parallel, the web app team
+determines a workaround for this particular situation, but the workaround is
+obtuse and causes app bloat and technical debt from on-going maintenance of
+workarounds for various Cobalt versions.
+
+#### With Cobalt Evergreen:
+
+The Cobalt team can work with you to guide validation and deployment of a shared
+Cobalt library to all affected devices much more quickly without all the
+engineering effort required to deploy a new Cobalt build. With this simpler
+updating capability, device behavior will be more consistent and there is less
+technical debt from workarounds on the web application side. Additionally, users
+can benefit from the latest performance, security, and functional fixes.
+
+## Platform Requirements
+
+Cobalt Evergreen currently supports the following
+
+Target Architectures:
+
+* x86\_32
+* x86\_64
+* armv7 32
+* armv8 64
+
+Supported Javascript Engines
+
+* V8
+
+Additional reserved storage (96MB) is required for Evergreen binaries. We expect
+Evergreen implementations to have an initial Cobalt preloaded on the device and
+an additional reserved space for additional Cobalt update storage.
+
+* Initial Cobalt binary deployment - 64MB
+* Additional Cobalt update storage - 96MB
+ * Required for 2 update slots under `kSbSystemPathStorageDirectory`
+
+As Cobalt Evergreen is intended to be updated from Google Cloud architecture
+without the need for device FW updates, it is important that this can be done
+easily and securely on the target platform. There are a set of general minimum
+requirements to do so:
+
+* Writable access to the file system of a device platform to download Cobalt
+ Evergreen binaries
+* Enough reserved storage for Cobalt updates
+* Platform supporting mmap API with writable memory (`PROT_WRITE`,
+ `PROT_EXEC`) for loading in-memory and performing relocations for Cobalt
+ Evergreen binaries
+
+## Building and Running Tests
+
+The `elf_loader_sandbox` binary can be used to run tests in Evergreen mode. This
+is much more lightweight than the `loader_app`, and does not have any knowledge
+about installations or downloading updates.
+
+The `elf_loader_sandbox` is run using two command line switches:
+`--evergreen_library` and `--evergreen_content`. These switches are the path to
+the shared library to be run and the path to that shared library's content.
+These paths should be *relative to the content of the elf_loader_sandbox*.
+
+For example, if we wanted to run the NPLB set of tests and had the following
+directory tree,
+
+```
+.../elf_loader_sandbox
+.../content/app/nplb/lib/libnplb.so
+.../content/app/nplb/content
+```
+
+we would use the following command to run NPLB:
+
+```
+.../elf_loader_sandbox --evergreen_library=app/nplb/lib/libnplb.so
+ --evergreen_content=app/nplb/content
+```
+
+Building tests is identical to how they are already built except that a
+different platform configuration must be used. The platform configuration should
+be an Evergreen platform configuration, and have a Starboard ABI file that
+matches the file used by the platform configuration used to build the
+`elf_loader_sandbox`.
+
+For example, building these targets for the Raspberry Pi 2 would use the
+`raspi-2` and `evergreen-arm-hardfp` platform configurations.
+
+## Verifying Platform Requirements
+
+In order to verify the platform requirements you should run the
+`nplb_evergreen_compat_tests`. These tests ensure that the platform is
+configured appropriately for Evergreen.
+
+To enable the test, set the `sb_evergreen_compatible gyp` variable to 1 in the
+`gyp_configuration.gypi`. For more details please take a look at the Raspberry
+Pi 2 gyp files.
+
+There is a reference implementation available for Raspberry Pi 2 with
+instructions available [here](cobalt_evergreen_reference_port_raspi2.md).
+
+### Verifying Crashpad Uploads
+
+1. Build the `crashpad_database_util` target and deploy it onto the device.
+```
+$ cobalt/build/gyp_cobalt <partner_port_name>
+$ ninja -C out/<partner_port_name>_qa crashpad_database_util
+```
+2. Remove the existing state for crashpad as it throttles uploads to 1 per hour:
+```
+$ rm -rf <kSbSystemPathCacheDirectory>/crashpad_database/
+
+```
+3. Launch Cobalt.
+4. Trigger crash by sending `abort` signal to the `loader_app` process:
+```
+$ kill -6 <pid>
+```
+5. Verify the crash was uploaded through running `crashpad_database_util` on the device
+pointing it to the cache directory, where the crash data is stored.
+
+```
+$ crashpad_database_util -d <kSbSystemPathCacheDirectory>/crashpad_database/ --show-completed-reports --show-all-report-info
+```
+
+```
+8c3af145-30a0-43c7-a3a5-0952dea230e4:
+ Path: cobalt/cache/crashpad_database/completed/8c3af145-30a0-43c7-a3a5-0952dea230e4.dmp
+ Remote ID: c9b14b489a895093
+ Creation time: 2021-06-01 17:01:19 HDT
+ Uploaded: true
+ Last upload attempt time: 2021-06-01 17:01:19 HDT
+ Upload attempts: 1
+```
+
+In this example the minidump was successfully uploaded because we see `Uploaded: true`.
+
+Reference for [crashpad_database_util](https://chromium.googlesource.com/crashpad/crashpad/+/refs/heads/main/tools/crashpad_database_util.md)
+
+## System Design
+
+![Cobalt Evergreen
+Components](resources/cobalt_evergreen_overview_components.png)
+
+The above diagram is a high-level overview of the components in the Cobalt
+Evergreen architecture.
+
+* **Partner-built** represents components the Partner is responsible for
+ implementing and building.
+
+* **Cobalt-built** represents components the Cobalt team is responsible for
+ implementing and building.
+
+### Cobalt Evergreen Components
+
+#### Cobalt Updater
+
+This is a new component in the Cobalt Shared Library component that is built on
+top of the Starboard API. The purpose of this module is to check the update
+servers if there is a new version of the Cobalt Shared Library available for the
+target device. If a new version is available, the Cobalt updater will download,
+verify, and install the new package on the target platform. The new package can
+be used the next time Cobalt is started or it can be forced to update
+immediately and restart Cobalt as soon as the new package is available and
+verified on the platform. This behavior will take into account the
+suspend/resume logic on the target platform.
+
+Functionally, the Cobalt Updater itself runs as a separate thread within the
+Cobalt process when Cobalt is running. This behavior depends on what the target
+platform allows.
+
+For more detailed information on Cobalt Updater, please take a look
+[here](cobalt_update_framework.md).
+
+#### Google Update (Update Server)
+
+We use Google Update as the infrastructure to manage the Cobalt Evergreen
+package install and update process. This has been heavily used across Google for
+quite some time and has the level of reliability required for Cobalt Evergreen.
+There are also other important features such as:
+
+* Fine grained device targeting
+* Rollout and rollback
+* Multiple update channels (e.g. production, testing, development)
+* Staged rollouts
+
+For more detailed information on Google Update for Cobalt Evergreen, please take
+a look [here](cobalt_update_framework.md).
+
+#### Google Downloads (Download Server)
+
+We use Google Downloads to manage the downloads available for Cobalt Evergreen.
+The Cobalt Updater will use Google Downloads in order to download available
+packages onto the target platform. We selected Google Downloads for this purpose
+due to its ability to scale across billions of devices as well as the
+flexibility to control download behavior for reliability.
+
+For more detailed information on Google Downloads (Download Server) for Cobalt
+Evergreen, please take a look [here](cobalt_update_framework.md).
+
+### Cobalt Evergreen Interfaces
+
+#### Starboard ABI
+
+The Starboard ABI was introduced to provide a single, consistent method for
+specifying the Starboard API version and the ABI. This specification ensures
+that any two binaries, built with the same Starboard ABI and with arbitrary
+toolchains, are compatible.
+
+Note that Cobalt already provides default SABI files for the following
+architectures:
+
+* x86\_32
+* x86\_64
+* arm v7 (32-bit)
+* arm v8 (64-bit)
+
+You should not need to make a new SABI file for your target platform unless it
+is not a currently supported architecture. We recommend that you do not make any
+SABI file changes. If you believe it is necessary to create a new SABI file for
+your target platform, please reach out to the Cobalt team to advise.
+
+For more detailed information on the Starboard ABI for Cobalt Evergreen, please
+take a look here.
+
+### Installation Slots
+
+Cobalt Evergreen provides support for maintaining multiple, separate versions of
+the Cobalt binary on a platform. These versions are stored in installation
+slots(i.e. known locations on disk), and are used to significantly improve the
+resilience and reliability of Cobalt updates.
+
+All slot configurations assume the following:
+* 1 System Image Installation Slot (read-only)
+* 2+ Additional Installation Slot(s) (writable)
+
+The number of installation slots available will be determined by the platform
+owner. **3 slots is the default configuration for Evergreen**. There can be `N`
+installation slots configured with the only limitation being available storage.
+
+#### Slot Configuration
+NOTE: 3-slots is the DEFAULT configuration.
+
+The number of installation slots is directly controlled using
+`kMaxNumInstallations`, defined in
+[loader\_app.cc](../../loader_app/loader_app.cc).
+
+It is worth noting that all slot configurations specify that the first
+installation slot (`SLOT_0`) will always be the read-only factory system image.
+This is permanently installed on the platform and is used as a fail-safe option.
+This is stored in the directory specified by `kSbSystemPathContentDirectory`
+under the `app/cobalt` subdirectory.
+
+All of the other installation slots are located within the storage directory
+specified by `kSbSystemPathStorageDirectory`. This will vary depending on the
+platform.
+
+For example, on the Raspberry Pi the `kSbSystemPathStorageDirectory` directory
+is `/home/pi/.cobalt_storage`, and the paths to all existing installation slots
+will be as follows:
+
+```
+/home/pi/<kSbSystemPathContentDirectory>/app/cobalt (system image installation SLOT_0) (read-only)
+/home/pi/.cobalt_storage/installation_1 (SLOT_1)
+/home/pi/.cobalt_storage/installation_2 (SLOT_2)
+...
+/home/pi/.cobalt_storage/installation_N (SLOT_N)
+```
+
+Where the most recent update is stored will alternate between the available
+writable slots. In the above example, this would be `SLOT_1`...`SLOT_N`.
+
+#### Understanding Slot Structure
+Slots are used to manage Cobalt Evergreen binaries with associated app metadata
+to select the appropriate Cobalt Evergreen binaries.
+
+See the below structures for an example 3-slot configuration.
+
+Structure for `kSbSystemPathContentDirectory` used for the read-only System
+Image required for all slot configurations:
+
+```
+.
+├── content <--(kSbSystemPathContentDirectory)
+│ └── fonts <--(kSbSystemPathFontDirectory, `standard` or `limit` configuration, to be explained below)
+│ └── app
+│ └── cobalt <--(SLOT_0)
+│ ├── content <--(relative path defined in kSystemImageContentPath)
+│ │ ├── fonts <--(`empty` configuration)
+│ │ ├── (icu) <--(only present when it needs to be updated by Cobalt Update)
+│ │ ├── licenses
+│ │ ├── ssl
+│ ├── lib
+│ │ └── libcobalt.so <--(System image version of libcobalt.so)
+│ └── manifest.json
+└── loader_app <--(Cobalt launcher binary)
+└── crashpad_handler <--(Cobalt crash handler)
+```
+
+Structure for `kSbSystemPathStorageDirectory` used for future Cobalt Evergreen
+updates in an example 3-slot configuration:
+
+```
+├── .cobalt_storage <--(kSbSystemPathStorageDirectory)
+ ├── cobalt_updater
+ │ └── prefs_<APP_KEY>.json
+ ├── installation_1 <--(SLOT_1 - currently unused)
+ ├── installation_2 <--(SLOT_2 - contains new Cobalt version)
+ │ ├── content
+ │ │ ├── fonts <--(`empty` configuration)
+ │ │ ├── (icu) <--(only present when it needs to be updated by Cobalt Update)
+ │ │ ├── licenses
+ │ │ ├── ssl
+ │ ├── lib
+ │ │ └── libcobalt.so <--(SLOT_2 version of libcobalt.so)
+ │ ├── manifest.fingerprint
+ │ └── manifest.json <-- (Evergreen version information of libcobalt.so under SLOT_2)
+ ├── installation_store_<APP_KEY>.pb
+ └── icu (default location shared by installation slots, to be explained below)
+```
+Note that after the Cobalt binary is loaded by the loader_app, `kSbSystemPathContentDirectory` points to the
+content directory of the running binary, as stated in Starboard Module Reference of system.h.
+
+#### App metadata
+Each Cobalt Evergreen application has a set of unique metadata to track slot
+selection. The following set of files are unique per application via a
+differentiating <APP_KEY> identifier, which is a Base64 hash appended to the
+filename.
+
+```
+<SLOT_#>/installation_store_<APP_KEY>.pb
+<SLOT_#>/cobalt_updater/prefs_<APP_KEY>.json
+```
+
+You should NOT change any of these files and they are highlighted here just for
+reference.
+
+
+### Fonts
+The system font directory `kSbSystemPathFontDirectory` should be configured to
+point to the `standard` (23MB) or the `limited` (3.1MB) cobalt font packages. An
+easy way to do that is to use the `kSbSystemPathContentDirectory` to contain
+the system font directory and setting the `cobalt_font_package` to `standard` or
+`limited` in your port.
+
+Cobalt Evergreen (built by Google), will by default use the `empty` font
+package to minimize storage requirements. A separate
+`cobalt_font_package` variable is set to `empty` in the Evergreen platform.
+
+On Raspberry Pi this is:
+
+`empty` set of fonts under:
+```
+<kSbSystemPathContentDirectory>/app/cobalt/content/fonts
+```
+
+`standard` or `limited` set of fonts under:
+```
+<kSbSystemPathContentDirectory>/fonts
+```
+
+### ICU Tables
+The ICU table should be deployed under the `kSbSystemPathStorageDirectory`. This
+way all Cobalt Evergreen installations would be able to share the same tables.
+The current storage size for the ICU tables is 7MB.
+
+On Raspberry Pi this is:
+
+```
+/home/pi/.cobalt_storage/icu
+```
+The Cobalt Evergreen package will not carry ICU tables by default but may add
+them in the future if needed. When the package has ICU tables they would be
+stored under the content location for the installation:
+
+```
+<SLOT_#>/content/icu
+```
+
+### Handling Pending Updates
+Pending updates will be picked up on the next application start, which means
+that on platforms that support suspending the platform should check
+`loader_app::IsPendingRestart` and call `SbSystemRequestStop` instead of
+ suspending if there is a pending restart.
+
+Please see
+[`suspend_signals.cc`](../../shared/signal/suspend_signals.cc)
+for an example.
+
+### Multi-App Support
+Evergreen can support multiple apps that share a Cobalt binary. This is a very
+common way to save space and keep all your Cobalt apps using the latest version
+of Cobalt. We understand that there are situations where updates are only needed
+for certain apps, so we have provided a way where Cobalt Updater and loader_app
+behavior can be easily configured on a per-app basis with simple command-line flags.
+
+The configurable options for Cobalt Updater configuration are:
+* `--evergreen_lite` *Use the System Image version of Cobalt under Slot_0 and turn
+ off the updater for the specified application.*
+* `--disable_updater_module` *Stay on the current version of Cobalt that might be the
+ system image or an installed update, and turn off the updater for the
+ specified application.*
+
+Each app’s Cobalt Updater will perform an independent, regular check for new
+Cobalt Evergreen updates. Note that all apps will share the same set of slots,
+but each app will maintain metadata about which slots are “good” (working) or
+“bad” (error detected) and use the appropriate slot. Sharing slots allows
+Evergreen to download Cobalt updates a single time and be able to use it across
+all Evergreen-enabled apps.
+
+To illustrate, a simple example:
+
+* Cobalt v5 - latest Cobalt Evergreen version
+
+#### BEFORE COBALT UPDATE
+```
+[APP_1] (currently using SLOT_1, using Cobalt v4)
+[APP_2] (currently using SLOT_0, using Cobalt v3)
+[APP_3] (currently using SLOT_0, using Cobalt v3)
+```
+
+Now remember, apps could share the same Cobalt binary. Let’s say `APP_1` has
+detected an update available and downloads the latest update (Cobalt v5) into
+SLOT_2. The next time `APP_2` runs, it may detect Cobalt v5 as well. It would
+then simply do a `request_roll_forward` operation to switch to SLOT_2 and does
+not have to download a new update since the latest is already available in an
+existing slot. In this case, `APP_1` and `APP_2` are now using the same Cobalt
+binaries in SLOT_2.
+
+If `APP_3` has not been launched, not run through a regular Cobalt Updater
+check, or launched with the `--evergreen_lite`/`--disable_updater_module` flag,
+it stays with its current configuration.
+
+#### AFTER COBALT UPDATE
+```
+[APP_1] (currently using SLOT_2, using Cobalt v5)
+[APP_2] (currently using SLOT_2, using Cobalt v5)
+[APP_3] (currently using SLOT_0, using Cobalt v3)
+```
+
+Now that we have gone through an example scenario, we can cover some examples of
+how to configure Cobalt Updater behavior and `loader_app` configuration.
+
+
+Some example configurations include:
+```
+
+# All Cobalt-based apps get Evergreen Updates
+[APP_1] (Cobalt Updater ENABLED)
+[APP_2] (Cobalt Updater ENABLED)
+[APP_3] (Cobalt Updater ENABLED)
+
+loader_app --url="<YOUR_APP_1_URL>"
+loader_app --url="<YOUR_APP_2_URL>"
+loader_app --url="<YOUR_APP_3_URL>"
+
+
+# Only APP_1 gets Evergreen Updates, APP_2 disables the updater and uses an alternate splash screen, APP_3 uses
+# the system image and disables the updater
+[APP_1] (Cobalt Updater ENABLED)
+[APP_2] (Cobalt Updater DISABLED)
+[APP_3] (System Image loaded, Cobalt Updater DISABLED)
+
+loader_app --url="<YOUR_APP_1_URL>"
+loader_app --url="<YOUR_APP_2_URL>" --disable_updater_module \
+--fallback_splash_screen_url="/<PATH_TO_APP_2>/app_2_splash_screen.html"
+loader_app --url="<YOUR_APP_3_URL>" --evergreen_lite
+
+
+# APP_3 is a local app, wants Cobalt Updater disabled and stays on the system image, and uses an alternate content
+# directory (This configuration is common for System UI apps. APP_3 in this example.)
+[APP_1] (Cobalt Updater ENABLED)
+[APP_2] (Cobalt Updater ENABLED)
+[APP_3] (System Image loaded, Cobalt Updater DISABLED)
+
+loader_app --url="<YOUR_APP_1_URL>"
+loader_app --url="<YOUR_APP_2_URL>"
+loader_app --csp_mode=disable --allow_http --url="file:///<PATH_TO_APP_3>/index.html" --content="/<PATH_TO_APP_3>/content" --evergreen_lite
+```
+
+Please see
+[`loader_app_switches.cc`](../../loader_app/loader_app.cc)
+for full list of available command-line flags.
+
+### Platform Security
+
+As Cobalt binary packages ([CRX
+format](https://docs.google.com/document/d/1pAVB4y5EBhqufLshWMcvbQ5velk0yMGl5ynqiorTCG4/edit#heading=h.ke61kmpkapku))
+are downloaded from the Google Downloads server, the verification of the Cobalt
+update package is critical to the reliability of Cobalt Evergreen. There are
+mechanisms in place to ensure that the binary is verified and a chain of trust
+is formed. The Cobalt Updater is responsible for downloading the available
+Cobalt update package and verifies that the package is authored by Cobalt(and
+not an imposter), before trying to install the downloaded package.
+
+#### Understanding Verification
+
+![Cobalt Evergreen CRX
+Verification](resources/cobalt_evergreen_overview_crx_verification.png)
+
+In the above diagram, the Cobalt Updater downloads the update package if
+available, and parses the CRX header of the package for verification, before
+unpacking the whole package. A copy of the Cobalt public key is contained in the
+CRX header, so the updater retrieves the key and generates the hash of the key
+coming from the header of the package, say _Key_ _hash1_.
+
+At the same time, the updater has the hash of the Cobalt public key hard-coded
+locally, say _Key hash2_.
+
+The updater compares _Key hash1_ with _Key hash2._ If they match, verification
+succeeds.
+
+## **FAQ**
+
+### Can I host the binaries for Cobalt core myself to deploy on my devices?
+
+Not at this time. All Cobalt updates will be deployed through Google
+infrastructure. We believe Google hosting the Cobalt core binaries allows us to
+ensure a high-level of reliability and monitoring in case issues arise.
+
+### What is the performance impact of switching to Cobalt Evergreen?
+
+We expect performance to be similar to a standard non-Evergreen Cobalt port.
+
+### How can I ensure that Cobalt updates work well on our platform?
+
+Google will work closely with device partners to ensure that the appropriate
+testing is in place to prevent regressions.
+
+### Will there be tests provided to verify functionality and detect regression?
+
+Yes, there are tests available to help validate the implementation:
+
+* NPLB tests to ensure all necessary APIs are implemented
+* Cobalt Evergreen Test Plan to verify the functionality of all components and
+ use cases
+
+### How can I be sure that Cobalt space requirements will not grow too large for my system resources?
+
+The Cobalt team is focusing a large amount of effort to identify and integrate
+various methods to reduce the size of the Cobalt binary such as compression and
+using less fonts.
+
+### What if something goes wrong in the field? Can we rollback?
+
+Yes, this is one of the benefits of Evergreen. We can initiate an update from
+the server side that addresses problems that were undetected during full
+testing. There are a formal set of guidelines to verify an updated binary
+deployed to the device to ensure that it will work properly with no regressions
+that partners should follow to ensure that there are no regressions. In
+addition, it is also critical to do your own testing to exercise
+platform-specific behavior.
+
+### How can I be sure that Cobalt Evergreen will be optimized for my platform?
+
+Much of the optimization work remains in the Starboard layer and configuration
+so you should still expect good performance using Cobalt Evergreen. That being
+said, the Cobalt Evergreen configuration allows you to customize Cobalt features
+and settings as before.
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_evergreen_reference_port_raspi2.md b/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_evergreen_reference_port_raspi2.md
new file mode 100644
index 0000000..7763cc2
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_evergreen_reference_port_raspi2.md
@@ -0,0 +1,124 @@
+---
+layout: doc
+title: "Cobalt Evergreen Raspi-2 Reference Port"
+---
+# Cobalt Evergreen Raspi-2 Reference Port
+
+## Requirements
+
+* Raspberry Pi 2 (image configured per
+ [instructions](https://cobalt.dev/development/setup-raspi.html) on
+ cobalt.dev)
+
+## Build instructions
+
+```
+## Clone the repository
+$ git clone https://cobalt.googlesource.com/cobalt
+
+## Build the loader app (new entry point)
+$ cd cobalt/src
+$ cobalt/build/gyp_cobalt -v raspi-2-sbversion-12 -C qa
+$ ninja -C out/raspi-2-sbversion-12_qa loader_app crashpad_handler
+
+## Create package directory for Cobalt Evergreen
+$ export COEG_PATH=coeg
+$ cp out/raspi-2-sbversion-12_qa/loader_app $COEG_PATH
+
+## Create directory structure for the initial installation
+[2-slot configuration]
+$ mkdir -p ~/.cobalt_storage/installation_0/
+$ cd ~/.cobalt_storage/installation_0/
+
+[3-slot configuration]
+$ mkdir -p $COEG_PATH/content/app/cobalt
+$ cd $COEG_PATH/content/app/cobalt
+
+## Download package
+$ curl -L https://dl.google.com/cobalt/evergreen/latest/cobalt_arm-hardfp_qa.crx -o cobalt.zip
+
+## Unpack content package
+$ unzip cobalt.zip
+$ rm cobalt.zip
+$ cd -
+```
+
+The following are the steps to build the Cobalt content that’s contained in the
+crx package. Note you only need to do this if you want to build the Cobalt
+shared library and supplementary components.
+
+```
+## Build Cobalt core locally
+$ cd cobalt/src
+$ cobalt/build/gyp_cobalt -v evergreen-arm-hardfp-sbversion-12 -C qa
+$ ninja -C out/evergreen-arm-hardfp-sbversion-12_qa cobalt
+
+## Copy the generated files to the package directory for Cobalt Evergreen
+$ cp -r out/evergreen-arm-hardfp-sbversion-12_qa/lib $COEG_PATH/content/app/cobalt/
+$ cp -r out/evergreen-arm-hardfp-sbversion-12_qa/content $COEG_PATH/content/app/cobalt/
+
+## Create a file named manifest.json with the following content, and put it under $COEG_PATH/content/app/cobalt/
+$ cat > $COEG_PATH/content/app/cobalt/manifest.json <<EOF
+{
+ "manifest_version": 2,
+ "name": "Cobalt",
+ "description": "Cobalt",
+ "version": "1.0.0"
+}
+EOF
+```
+
+## Deployment instructions
+
+Configure your Raspberry Pi 2 with the following steps from your Linux machine.
+
+```
+## Save the address of the device
+$ export RASPI_ADDR=<YOUR_RASPI_ID_ADDR>
+
+## Remove old storage directory
+$ rm -rf /home/pi/.cobalt_storage
+
+## Copy the Evergreen contents to the device
+$ rsync -arvp $COEG_PATH pi@$RASPI_ADDR:/home/pi
+
+## Launch
+$ ssh pi@$RASPI_ADDR /home/pi/$COEG_PATH/loader_app
+```
+
+## Run instructions
+
+```
+$ ssh pi@$RASPI_ADDR
+$ cd coeg
+$ ./loader_app
+```
+
+Cobalt should load and work as usual, but leveraging Evergreen. That’s it!
+
+## Troubleshooting
+
+### Certificate errors on execution of loader\_app
+
+Certificate issues may occur on certain network environments when launching
+`loader_app` via SSH. In this case, try launching with a keyboard directly
+connected to the device.
+
+### “Failed to load library at <path>” thrown on startup
+
+The loader can’t find the `libcobalt.so` file. Check that the path to
+`libcobalt.so` completely matches the one in Deployment instructions.
+
+### “fatal error: “assert(sk\_file)”” thrown on startup
+
+The loader can’t find the content/data folder or it is malformed. Check that the
+path to this folder completely matches the one in Deployment instructions.
+
+### “Check failed: address. Failed to retrieve the address” thrown on startup
+
+Ensure that `libcobalt.so` being used is the correct version. For a rebuild, you
+may need to remove the old .cobalt\_storage directory on your device.
+
+```
+## Remove old storage directory
+$ rm -rf /home/pi/.cobalt_storage
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_update_framework.md b/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_update_framework.md
new file mode 100644
index 0000000..f1b1cf8
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_update_framework.md
@@ -0,0 +1,104 @@
+---
+layout: doc
+title: "Cobalt Update Framework"
+---
+# Cobalt Update Framework
+
+## Background
+
+The updatability of Cobalt on the field devices enables the deployment of new
+features and crucial bug fixes in a timely manner. It significantly reduces the
+amount of work on partners’ shoulders to update to a newer version of Cobalt.
+This document introduces how Cobalt updates itself and what the system is like
+that supports the update of Cobalt. Note that the Cobalt Update Framework is
+currently used only for Evergreen configurations.
+
+## Goal
+
+* Enable Cobalt to automatically update itself periodically
+* Build a framework that hosts and serves the updates reliably
+
+## Overview
+
+![Cobalt Update Overview](resources/cobalt_update_overview.png)
+
+The Cobalt Updater is a module of Cobalt. It is initiated as Cobalt starts. It
+periodically sends requests to Google Update server to check for updates. If an
+update is available, the Update server responds with a downloadable link of the
+update package to the Updater. Then the Updater connects to the link, which is
+hosted on Google Downloads server, to download the update package. If an update
+is not available, the Updater server responds to indicate no update. Then the
+Updater waits until the next scheduled time to check for updates again.
+
+## Implementation
+
+### Google Update
+
+![Cobalt Update Interaction](resources/cobalt_update_interaction.png)
+
+Google Update is an update service that manages updates for Google products
+serving billions of users worldwide. We set up Cobalt updates on Google Update
+in a way that each type of device gets a unique update link (URL). The device
+type is identified by [Starboard
+ABI](../starboard_abi.md)
+(SABI) string. For instance, Raspberry Pi 2 and Linux desktop are two different
+types of devices. They are identified by two different SABI strings, and get two
+different update URLs on Google Update. The request sent by the Cobalt updater
+to Google Update contains a SABI string. Google Update finds the suitable
+update link that matches the SABI string from the request, and responds to the
+Cobalt updater.
+
+Google Update allows the setup of multiple channels. We set up different
+channels for internal testing, partner testing, production and developers.
+
+Google Update also allows staged rollout and rollback when things go wrong. In
+the case where a problem is detected that requires rollback or fixes, Google
+will work with the partner to find a path to resolution.
+
+### Google Downloads
+
+Google Downloads is a download hosting service for official Google content. We
+generate Cobalt update packages for various types of devices, and upload the
+packages to Google Downloads. Then the links to the packages on Google Downloads
+are served on Google Update.
+
+### Cobalt Updater
+
+The updater checks for updates on Google Downloads, then downloads the update
+package if available. After the download is complete, the updater verifies the
+downloaded package, then unpack the package to a designated installation
+location. The updater runs update checks following a predefined schedule: the
+first check happens after Cobalt starts; the second check runs in a randomized
+number of hours between 1 and 24 hours; the following checks run every 24 hours.
+
+### Update flow
+
+![Cobalt Update Flow](resources/cobalt_update_flow.png)
+
+Above is a chart of the workflow of a complete update cycle. It shows how the
+Updater operates step by step and how it interacts with the Installation Manager
+and the Elf Loader[^1].
+
+The Installation Manager maintains the installation slots and provides a proper
+slot to the Updater. During the update and installation process, the
+Installation Manager keeps track of the status and collects any installation
+error. After the installation is completed, the Installation Manager marks the
+installation as pending, so that next time Cobalt starts, the Elf Loader loads
+the new installation and the update is complete. If the target platform supports
+app exits/suspends on user exiting, Cobalt will exit when an installation is
+pending, so that the new update will be picked up on the next start; otherwise,
+Cobalt is not able to exit by itself, then a manual termination of the app is
+required to pick up the update on restart.
+
+## FAQ
+
+### What happens if an urgent problem is found that requires a rollback or update?
+
+In the case where a problem is detected that requires rollback or fixes, Google
+will work with the partner to find a path to resolution.
+
+<!-- Footnotes themselves at the bottom. -->
+## Footnotes
+
+[^1]: Elf loader - A portable loader that loads the Cobalt binary and resolves
+ symbols with Starboard API when Cobalt starts up in Evergreen mode.
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_configurations.png b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_configurations.png
new file mode 100644
index 0000000..8b3721c
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_configurations.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_overview_components.png b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_overview_components.png
new file mode 100644
index 0000000..073ce92
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_overview_components.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_overview_crx_verification.png b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_overview_crx_verification.png
new file mode 100644
index 0000000..16ec0d9
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_overview_crx_verification.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_overview_flow.png b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_overview_flow.png
new file mode 100644
index 0000000..df0284b
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_overview_flow.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_overview_vs_non_evergreen.png b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_overview_vs_non_evergreen.png
new file mode 100644
index 0000000..cd9cb9f
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_evergreen_overview_vs_non_evergreen.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_update_flow.png b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_update_flow.png
new file mode 100644
index 0000000..eebe1d3
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_update_flow.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_update_interaction.png b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_update_interaction.png
new file mode 100644
index 0000000..07b710a
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_update_interaction.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_update_overview.png b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_update_overview.png
new file mode 100644
index 0000000..3c8328e
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/cobalt_update_overview.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/evergreen_lite_overview.png b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/evergreen_lite_overview.png
new file mode 100644
index 0000000..fa338d9
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/resources/evergreen_lite_overview.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/symbolizing_minidumps.md b/src/cobalt/site/docs/gen/starboard/doc/evergreen/symbolizing_minidumps.md
new file mode 100644
index 0000000..df7a502
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/symbolizing_minidumps.md
@@ -0,0 +1,133 @@
+---
+layout: doc
+title: "How to Symbolize Dumps"
+---
+# How to Symbolize Dumps
+
+Evergreen will store the minidumps (`.dmp` files) from the 2 most recent
+crashes on the disk. They are stored under `kSbSystemPathCacheDirectory` in the
+subdirectory `crashpad_database/`. These files can be used along with
+Breakpad's tools to get a full stacktrace of the past crashes. This can help in
+debugging, as these minidumps have the information for the dynamic
+`libcobalt.so` module correctly mapped, which a out-of-the-box dumper could not
+manage.
+
+## Obtaining the Tools to Symbolize Minidumps
+
+Tools for symbolizing these dumps are available through
+[Breakpad](https://chromium.googlesource.com/breakpad/breakpad/). Breakpad is
+an open source crash reporting library that we use to obtain symbol files
+(`.sym`) from unstripped binaries, and to process the symbol files with the
+minidumps to produce human-readable stacktraces.
+
+
+### Building Breakpad
+
+[Breakpad](https://chromium.googlesource.com/breakpad/breakpad/) provides
+instructions for building these tools yourself. The
+[Getting Started with Breakpad](https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/getting_started_with_breakpad.md)
+guide is a good place to start if you want to go through the docs yourself, but
+below is a brief overview of how to get and build the tools.
+
+Download depot_tools:
+```
+$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
+$ export PATH=/path/to/depot_tools:$PATH
+```
+
+Get breakpad:
+```
+$ mkdir breakpad && cd breakpad
+$ fetch breakpad
+$ cd src
+```
+
+Build breakpad:
+```
+$ ./configure && make
+```
+
+This will build the processor (`src/processor/minidump_stackwalk`), and when
+building on Linux it will also build the `dump_syms` tool
+(`src/tools/linux/dump_syms/dump_syms`).
+
+**IMPORTANT:** Once you have fetched Breakpad, you should remove the path to
+depot_tools from your `$PATH` environment variable, as it can conflict with
+Cobalt's depot_tools.
+
+## Symbolizing Minidumps
+
+Now that you have all the tools you need, we can symbolize the dumps. To be
+able to symbolize Cobalt using Evergreen, you need to be get the unstripped
+`libcobalt.so` binary. These will be available as assets in GitHub releases
+[on Cobalt's public GitHub repo](https://github.com/youtube/cobalt/releases).
+
+libcobalt releases will be labeled by the Evergreen version, the architecture,
+the config, and the ELF build id, for example
+"libcobalt_1.0.10_unstripped_armeabi_softfp_qa_ac3132014007df0e.tgz". Here, we
+have:
+* Evergreen Version: 1.0.10
+* Architecture: armeabi_softfp
+* Config: qa
+* ELF Build Id: ac3132014007df0e
+
+Knowing the architecture and config you want, you'll just have to know which
+version of Evergreen you're on or obtain the build id of the library. If you
+need to obtain the ELF build id, you can do so easily by running
+`readelf -n /path/to/libcobalt.so` and look at the hash displayed after "Build
+ID:".
+
+Now you can get the debug symbols from the library using the tools we
+downloaded previously. Unpack libcobalt and dump its symbols into a file:
+
+```
+$ tar xzf /path/to/libcobalt.tgz
+$ /path/to/dump_syms /path/to/unzipped/libcobalt > libcobalt.so.sym
+$ head -n1 libcobalt.so.sym
+MODULE Linux x86_64 6462A5D44C0843D100000000000000000 libcobalt.so
+```
+
+We run `head` on the symbol file to get the debug identifier, the hash
+displayed above (in this case, it's `6462A5D44C0843D100000000000000000`). Now
+we can create the file structure that `minidump_stackwalker` expects and run
+the stackwalker against the minidump:
+
+```
+$ mkdir -p symbols/libcobalt.so/<debug identifier>/
+$ mv libcobalt.so.sym symbols/libcobalt.so/<debug identifier>/
+$ /path/to/minidump_stackwalk /path/to/your/minidump.dmp symbols/
+```
+
+`minidump_stackwalk` produces verbose output on stderr, and the stacktrace on
+stdout, so you may want to redirect stderr.
+
+### Addendum: Adding Other Symbols
+
+We can use the process above to add symbols for any library or executable you
+use, not just `libcobalt.so`. To do this, all you have to do is run the
+`dump_syms` tools on the binary you want symbolized and put that in the
+"symbols/" folder.
+
+```
+$ /path/to/dump_syms /path/to/<your-binary> > <your-binary>.sym
+$ head -n1 <your-binary.sym>
+MODULE Linux x86_64 <debug-identifier> <your-binary>
+$ mkdir -p symbols/<your-binary>/<debug-identifier>
+$ mv <your-binary>.sym symbols/<your-binary>/<debug-identifier>/
+```
+
+Now, `minidump_stackwalk` should symbolize sections within `<your-binary>`. For
+example, if you decided to symbolize the `loader_app`, it would transform the
+stacktrace output from `minidump_stackwalk` from:
+
+```
+9 loader_app + 0x3a31130
+```
+
+to:
+
+```
+9 loader_app!SbEventHandle [sandbox.cc : 44 + 0x8]
+```
+
+Note that the addresses will vary.
diff --git a/src/cobalt/site/docs/gen/starboard/doc/howto_decode_to_texture.md b/src/cobalt/site/docs/gen/starboard/doc/howto_decode_to_texture.md
new file mode 100644
index 0000000..bd2f7b8
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/howto_decode_to_texture.md
@@ -0,0 +1,140 @@
+---
+layout: doc
+title: "**HOWTO:** Decode to Texture"
+---
+# **HOWTO:** Decode to Texture
+
+Starboard declares the interfaces necessary to allow applications to query for
+video frames from the media player, and have them returned as texture objects
+(e.g. GLES textures). This is useful if the application would like to apply
+a geometrical transformation to the rendered video, in order to support 360
+spherical video playback for example. Additionally, if a Starboard platform
+implementation does not support punch-through video playback, then
+applications can choose to use decode-to-texture instead.
+
+## API Overview
+
+Decode-to-texture support involves multiple Starboard API functions spanning
+both the [`starboard/player.h`](../player.h) and
+[`starboard/decode_target.h`](../decode_target.h) Starboard interface header
+files. Support for decode-to-texture began in version 4 of the Starboard
+API.
+
+In particular, the following function implementations require consideration
+for decode-to-texture support:
+
+From [`starboard/player.h`](../player.h),
+
+* `SbPlayerCreate()`
+* `SbPlayerOutputModeSupported()`
+* `SbPlayerGetCurrentFrame()`
+
+From [`starboard/decode_target.h`](../decode_target.h),
+
+* `SbDecodeTargetRelease()`
+* `SbDecodeTargetGetInfo()`
+
+Note that it is possible that you may not need to use the
+`SbDecodeTargetGraphicsContextProvider` parameter of SbPlayerCreate(). More on
+this later.
+
+## Example Application Usage Pattern
+
+We now describe an example, and typical, sequence of steps that an
+application will take when it wishes to make use of decode-to-texture
+support.
+
+![Decode-to-texture sequence diagram](resources/decode_to_texture_sequence.png)
+
+1. An application with the desire to make use of decode-to-texture will first
+ call `SbPlayerOutputModeSupported()`, passing in
+ `kSbPlayerOutputModeDecodeToTexture` for its `output_mode` parameter. If
+ the function returns false, the application learns that decode-to-texture
+ is not supported by the platform and it will not continue with a
+ decode-to-texture flow.
+
+2. If `SbPlayerOutputModeSupported()` returns true, the application will call
+ `SbPlayerCreate()`, passing in `kSbPlayerOutputModeDecodeToTexture` for
+ the `output_mode` parameter, and also providing a valid `provider`
+ parameter (more on this later). At this point, the Starboard platform is
+ expected to have created a player with the decode-to-texture output mode.
+
+3. Once the player is started and playback has begun, the application's
+ renderer thread (this may be a different thread than the one that called
+ `SbPlayerCreate()`) will repeatedly and frequently call
+ `SbPlayerGetCurrentFrame()`. Since this function will be called from the
+ application's renderer thread, it should be thread-safe. If the platform
+ uses a GLES renderer, it is guaranteed that this function will be called
+ with the GLES renderer context set as current. This function is expected
+ to return the video frame that is to be displayed at the time the function
+ is called as a `SbDecodeTarget` object. The `SbPlayerGetCurrentFrame()`
+ will be called at the renderer's frequency, i.e. the application render
+ loop's frame rate. If the application's frame rate is higher than the
+ video's frame rate, then the same video frame will sometimes be returned
+ in consecutive calls to `SbPlayerGetCurrentFrame()`. If the video's frame
+ rate is higher than the application's (this should be rare), then some
+ video frames will never be returned by calls to
+ `SbPlayerGetCurrentFrame()`; in other words, video frames will be
+ dropped.
+
+4. Once the application has acquired a valid SbDecodeTarget object through a
+ call to `SbPlayerGetCurrentFrame()`, it will call
+ `SbDecodeTargetGetInfo()` on it to extract information about the opaque
+ `SbDecodeTarget` object. The `SbDecodeTargetGetInfo()` function fills
+ out a `SbDecodeTargetInfo` structure which contains information about the
+ decoded frame and, most importantly, a reference to a GLES texture ID on
+ GLES platforms, or a reference to a `SbBlitterSurface` object on
+ Starboard Blitter API platforms. The application can then use this
+ texture/surface handle to render the video frame as it wishes.
+
+5. When the application is finished using the `SbDecodeTarget` that it has
+ aquired through the `SbPlayerGetCurrentFrame()` function, it will call
+ `SbDecodeTargetRelease()` on it. The Starboard platform implementation
+ should ensure that the `SbDecodeTarget` object returned by
+ `SbPlayerGetCurrentFrame()` remains valid until the corresponding call to
+ `SbDecodeTargetRelease()` is made. A call to `SbDecodeTargetRelease()`
+ will be made to match each call to `SbPlayerGetCurrentFrame()`.
+
+## The `SbDecodeTargetGraphicsContextProvider` object
+
+It is completely possible that a platform's Starboard implementation can
+properly implement decode-to-texture support without dealing with the
+`SbDecodeTargetGraphicsContextProvider` object (passed in to
+`SbPlayerCreate()`). The `SbDecodeTargetGraphicsContextProvider` reference
+gives platforms references to the graphics objects that will later be used to
+render the decoded frames. For example, on Blitter API platforms, a reference
+to the `SbBlitterDevice` object will be a mamber of
+`SbDecodeTargetGraphicsContextProvider`. For EGL platforms, a `EGLDisplay` and
+`EGLContext` will be available, but additionally a
+`SbDecodeTargetGlesContextRunner` function pointer will be provided that will
+allow you to run arbitrary code on the renderer thread with the `EGLContext`
+held current. This may be useful if your `SbDecodeTarget` creation code will
+required making GLES calls (e.g. `glGenTextures()`) in which a `EGLContext` must
+be held current.
+
+## Performance Considerations
+
+The decode-to-texture Starboard API is specifically designed to allow
+Starboard implementations to have the player decode directly to a texture,
+so that the application can then reference and render with that texture
+without at any point performing a pixel copy. The
+decode-to-texture path can therefore be highly performant.
+
+It is still recommended however that platforms support the punch-through
+player mode if possible. When using the decode-to-texture player output
+mode, the video may be rendered within the application's render loop, which
+means that non-video-related time complexity in the application's render
+loop can affect video playback's apparent frame rate, potentially resulting in
+dropped frames. The platform can likely configure punch-through video to
+refresh on its own loop, decoupling it from the application render loop.
+
+## Implementation Strategies
+
+### Working with "push" players
+
+If your player implementation is setup with a "push" framework where
+frames are pushed out as soon as they are decoded, then you will need
+to cache those frames (along with their timestamps) so that they can be
+passed on to the application when `SbPlayerGetCurrentFrame()` is called.
+This same strategy applies if the player pushes frames only when they are meant
+to be rendered.
\ No newline at end of file
diff --git a/src/cobalt/site/docs/gen/starboard/doc/principles.md b/src/cobalt/site/docs/gen/starboard/doc/principles.md
new file mode 100644
index 0000000..880c09c
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/principles.md
@@ -0,0 +1,157 @@
+---
+layout: doc
+title: "Starboard Design Principles"
+---
+# Starboard Design Principles
+
+An overview of the goals and design principles of Starboard with the perspective
+of hindsight.
+
+**Status:** REVIEWED\
+**Created:** 2016-11-12
+
+Starboard is a porting abstraction and a collection of implementation fragments
+used to abstract operating system facilities and platform quirks from C or C++
+applications. It occupies a similar space to SDL, DirectFB, Marmalade, and
+various others.
+
+## Background
+
+Starboard was created as a response to the significant effort it has
+historically taken to port desktop-oriented web browsers to non-traditional
+device platforms like game consoles. Chromium in particular mixes
+platform-specific code with common code throughout the technology stack, making
+it very difficult to know what has to be done for a new platform or how much
+work it is going to be.
+
+## Goals
+
+Here are the main goals of Starboard, stack-ranked from most-to-least important.
+
+ * **G1** Minimize the total time and effort required to port Starboard Client
+ Applications to new platforms.
+ * **G2** Minimize the incremental time and effort required to rebase Starboard
+ Client Applications across platforms.
+ * **G3** Enable third parties to port Starboard to their platform without
+ significant engineering support from the Starboard team.
+ * **G4** Ensure support for low-profile platforms that are not geared towards
+ broad native C/C++ development access.
+ * **G5** Provide an organization framework for platform-specific code, clearly
+ delineating what is common and what is platform-specific, consolidating
+ platform-specific code into a single location, and enumerating all the APIs
+ needed to provide full functionality.
+ * **G6** Encapsulate all platform-provided services needed to build graphical
+ media applications into a single API.
+ * **G7** Reduce the total surface area needed to port to new platforms.
+ * **G8** Improve and encourage sharing of platform-specific implementation
+ components between platforms.
+ * **G9** Maximize the amount of common (platform-independent) code, to avoid
+ variances between platforms, and to increase the leverage of testing,
+ including fuzz testing which must often be done on particular platforms.
+ * **G10** Maintain a loose binding between a Starboard Platform Implementation
+ and a Starboard Client Application, such that they can be updated
+ independently at a source level.
+ * **G11** Avoid the pitfalls of trying to emulate POSIX, including, but not
+ limited to: auto-included headers, global defines of short and common
+ symbols, wrapping misbehaving or misprototyped system APIs, using custom
+ toolchain facilities, and conflicts with platform headers.
+
+## Principles
+
+### Make APIs sufficient for their purpose, but minimally so.
+
+APIs can generally be augmented without serious backwards-compatibility
+consequences, but they can not be changed or pruned so easily, so it is better
+to **err on the side of providing less**.
+
+#### Corollary: Implementation details should be as hidden as possible.
+
+#### Corollary: Anything that could be implemented purely on top of Starboard APIs should be implemented purely on top of Starboard APIs.
+
+#### Exception: If there are good reasons why an API may need to be implemented in a platform-specific manner on one or more platforms, but can be commonly implemented on other platforms, it should be part of the API, with a shared Starboard-based implementation.
+
+#### Exception: For the select few cases where Starboard implementations also need to use it, it should be included in the Starboard API so that can happen without creating circular dependencies.
+
+### Specify public APIs concretely and narrowly.
+
+A broader specification of the behavior of an API function makes life easier for
+the implementor, but more difficult for anyone attempting to use the API. An API
+can be so weakly specified that it is not usable across platforms. It can also
+be so strictly specified that it is not implementable across platforms. **Err on
+the side of narrower specifications**, requiring generality only when
+necessitated by one or more platforms.
+
+#### Corollary: Documentation should be exhaustive and clear.
+
+#### Corollary: Avoid overly-flexible convention-based interfaces.
+
+For example, passing in a set of string-string name-value pairs. This takes the
+compiler out of any kind of validation, and can encourage mismatches of
+understanding between Clients and Platforms.
+
+### Minimize the burden on the porter.
+
+Whenever adding or changing an API, or specifying a contract, consider whether
+this places a large burden on some platform implementers. This burden could be
+because of a wide porting surface, or complex requirements that are difficult to
+implement. It could be caused by a fundamental piece of infrastructure that
+isn't provided by a particular platform.
+
+We can always make APIs that are burdensome to use easier with more common code.
+
+### Be consistent and predictable.
+
+Consistency, not just in formatting, but in semantics, leads to
+predictability. Some people just won't read the documentation, even if it's
+thorough. Perhaps especially if it's thorough. The names of API entities should
+convey the intention as completely as possible.
+
+Yet, overly-verbose naming will make the API difficult to remember, read, and
+use.
+
+### Assume the porter knows nothing.
+
+Engineers from a broad set of backgrounds and environments will end up being
+dropped into porting Starboard. They may not have knowledge of any particular
+technologies, best practices, or design patterns. They may be under an
+aggressive deadline.
+
+### Always consider threading (and document it).
+
+Each function and module should have a strategy for dealing with multiple
+threads. It should make sense for the expected use cases of the interface
+entities in question. As the interface designer, it is most clear to you how the
+API should be used with respect to threads.
+
+Some may be "thread-safe," such that any functions can be called from any thread
+without much concern. Note that this places the burden on the implementer to
+ensure that an implementation meets that specification, and they MAY not know
+how to do that. This can also be more complex than just acquiring a mutex inside
+every function implementation, as there may be inherent race conditions between
+function calls even when using a synchronization mechanism.
+
+The path of least burden to the porter is to say that an interface is not
+thread-safe at all, which means applications will have to take care how the API
+is used. But, sometimes even this requires clarification as to what modes of
+access are dangerous and how to use the API safely.
+
+### Don't expose Informational-Only result codes, but do DLOG them.
+
+"Informational-Only" is defined by a result code that doesn't change the
+behavior of the caller. Many times, why something failed does not matter when
+the product is already in the hands of the user. We often want diagnostic
+logging during development
+
+### Trust but Verify. Whenever possible, write NPLB tests for all contracts declared by the interface.
+
+#### Corollary: For hard-to-test features (like Input) add an example sandbox app for testing.
+
+### We will get it wrong the first time, so plan for some kind of change mechanism.
+
+Starboard has a [versioning mechanism](versioning.md) to manage change.
+
+## References
+ * [Joshua Bloch's presentation about API design](https://www.youtube.com/watch?v=aAb7hSCtvGw)
+ * [Joshua Bloch's bumper sticker API design rules](http://www.infoq.com/articles/API-Design-Joshua-Bloch)
+ * [digithead's collection of API design links (I didn't read them all)](http://digitheadslabnotebook.blogspot.com/2010/07/how-to-design-good-apis.html)
+
diff --git a/src/cobalt/site/docs/gen/starboard/doc/resources/decode_to_texture_sequence.png b/src/cobalt/site/docs/gen/starboard/doc/resources/decode_to_texture_sequence.png
new file mode 100644
index 0000000..b2b4cb4
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/resources/decode_to_texture_sequence.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/starboard/doc/resources/decode_to_texture_sequence.txt b/src/cobalt/site/docs/gen/starboard/doc/resources/decode_to_texture_sequence.txt
new file mode 100644
index 0000000..5118f0b
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/resources/decode_to_texture_sequence.txt
@@ -0,0 +1,14 @@
+participant Application (e.g. Cobalt) as a [fillcolor="#ffd0d0"]
+participant Starboard as s [fillcolor="#d0d0ff"]
+
+a->s: SbPlayerOutputModeSupported(kSbPlayerOutputModeDecodeToTexture, ...)
+s-->a: returns bool
+Note over a: If SbPlayerOutputModeSupported()\nreturns true... [fillcolor="white"]
+a->s: SbPlayerCreate(..., kSbPlayerOutputModeDecodeToTexture, ...)
+Note over a: Start of render loop [fillcolor="#ffffd0"]
+a->s: SbPlayerGetCurrentFrame()
+s-->a: returns SbDecodeTarget
+Note over a: Extracts GLES texture(s) from the\nSbDecodeTarget object and\nrenders a scene with them. [fillcolor="white"]
+a->s: SbDecodeTargetRelease()
+Note over a: Goto: Start of render loop [fillcolor="#ffffd0"]
+
diff --git a/src/cobalt/site/docs/gen/starboard/doc/resources/starboard_abi_overview.png b/src/cobalt/site/docs/gen/starboard/doc/resources/starboard_abi_overview.png
new file mode 100644
index 0000000..8a15c74
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/resources/starboard_abi_overview.png
Binary files differ
diff --git a/src/cobalt/site/docs/gen/starboard/doc/starboard_abi.md b/src/cobalt/site/docs/gen/starboard/doc/starboard_abi.md
new file mode 100644
index 0000000..619703c
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/starboard_abi.md
@@ -0,0 +1,123 @@
+---
+layout: doc
+title: "Starboard ABI"
+---
+# Starboard ABI
+
+The Starboard ABI was introduced to provide a single, consistent method for
+specifying the Starboard API version and the ABI. This specification ensures
+that any two binaries, built with the same Starboard ABI and with arbitrary
+toolchains, are compatible.
+
+## Background
+
+The Starboard ABI is the set of features, such as the Starboard API version or
+the sizes of data types, that collectively describes the relationship between
+the Starboard API and ABI of a binary. In the past, each of these features were
+inconsistently and ambiguously defined in a variety of files. This led to
+confusion, and made it difficult to track down the feature values for a
+platform. To simplify how Starboard is configured for a target platform, all of
+these features, and their concrete values, are now listed for each distinct
+target architecture in Starboard ABI files. These files provide a consistent,
+consolidated view of the values for each of these features, decoupling
+platform-specific details from architecture.
+
+## Goals
+
+The overall goal of the Starboard ABI is to provide a way to implement and
+verify binary compatibility on a target platform, and this goal can be broken
+down into the following more concise motivations:
+
+* Separate platform and architecture into distinct concepts.
+* Establish a consistent set of values for the various features of each target
+ architecture.
+* Consolidate this set of features and their values in a consistent,
+ predictable location.
+* Provide the ability to validate the values of each feature in produced
+ binaries.
+
+## Using Starboard ABI Files
+
+With the Starboard ABI being the source of truth for all things architecture
+related, each platform must now include a Starboard ABI file in its build (see
+[//starboard/sabi](../sabi)
+for examples). Starboard ABI files are JSON, and should all contain identical
+keys with the values being appropriate for the architecture. Each platform must
+override the new
+[GetPathToSabiJsonFile](../build/platform_configuration.py##339)
+method in its platform configuration to return the path to the desired Starboard
+ABI file (e.g.
+[//starboard/linux/shared/gyp\_configuration.py](../linux/shared/gyp_configuration.py)).
+By default, an empty and invalid Starboard ABI file is provided.
+
+Additionally, all platforms must include the
+[sabi.gypi](../sabi/sabi.gypi)
+in their build configuration. This file will consume the specified Starboard ABI
+file, resulting in the creation of a set of GYP variables and preprocessor
+macros. The preprocessor macros are passed directly to the compiler and replace
+the macros you might be familiar with, such as `SB_HAS_32_BIT_LONG`.
+
+The newly defined GYP variables need to be transformed into toolchain specific
+flags; these flags are what actually makes the build result in a binary for the
+desired architecture. These flags will, in most cases, be identical to the flags
+already being used for building.
+
+The process outlined above is shown in the diagram below.
+
+![Starboard ABI Overview](resources/starboard_abi_overview.png)
+
+### Post-Starboard ABI File Cleanup
+
+A number of GYP variables and preprocessor macros should no longer be defined
+directly, and instead the Starboard ABI file will be used to define them. These
+definitions need to be removed.
+
+From `configuration_public.h`:
+
+* `SB_IS_ARCH_*`
+* `SB_IS_BIG_ENDIAN`
+* `SB_IS_32_BIT`
+* `SB_IS_64_BIT`
+* `SB_HAS_32_BIT_LONG`
+* `SB_HAS_64_BIT_LONG`
+* `SB_HAS_32_BIT_POINTERS`
+* `SB_HAS_64_BIT_POINTERS`
+
+From `gyp_configuration.gypi`:
+
+* `target_arch`
+
+## FAQ
+
+### What Starboard ABI files are provided?
+
+The Cobalt team provides, and maintains, Starboard ABI files for the following
+architectures:
+
+* x86\_32
+* x86\_64
+* ARM v7 (32-bit)
+* ARM v8 (64-bit)
+
+If you find that no valid Starboard ABI file exists for your architecture, or
+that you need to change any values of a provided Starboard ABI file, please
+reach out to the Cobalt team to advise.
+
+### How can I verify that my build is configured correctly?
+
+Similar to the process prior to Starboard ABI files, there are multiple levels
+of verification that occur:
+
+1. When configuring your build, the Starboard ABI file that was specified will
+ have its values sanity checked against a provided
+ [schema](../sabi/sabi.schema.json).
+1. When building, a number of static assertions will assert correctness of a
+ number of features generated from the Starboard ABI file against the
+ features of the binary.
+1. The NPLB test suite has been expanded to include [additional
+ tests](../nplb/sabi/)
+ capable of verifying the remaining features of the binary.
+
+Finally, binaries produced by the Cobalt team for your architecture, including
+NPLB, will be made available to ensure end-to-end correctness of the produced
+binaries.
diff --git a/src/cobalt/site/docs/gen/starboard/doc/starboard_split.md b/src/cobalt/site/docs/gen/starboard/doc/starboard_split.md
new file mode 100644
index 0000000..2e145ae
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/starboard_split.md
@@ -0,0 +1,62 @@
+---
+layout: doc
+title: "Separation of Starboard from Cobalt"
+---
+# Separation of Starboard from Cobalt
+
+### Background
+
+In creating Cobalt Evergreen, we needed to have as few differences in the code
+as we could from one platform to another. Simply put, that means we want to get
+rid of as many platform specific compile time macros as possible. Because of
+the large amount of platform differences we had previously, there were macros
+defined in a variety places, all of which require different cases to convert.
+The below sections go into the differences regarding changes to these macros
+from Cobalt 20 to 21 and from Starboard 11 to 12.
+
+## Optional APIs
+
+In previous versions, there were a few APIs that could optionally defined and
+would only be enabled if certain macros were set. The platform would only have
+to implement the API if it set the macros accordingly. Now, those differences
+have been removed, and all platforms are required to implement these APIs. For
+convenience, we have provided stub functions for all implementations, which a
+platform can use without differences in Cobalt if they did not enable the API
+beforehand.
+
+## Migration from Configuration Macros to External Constants
+
+Starboard configurations have moved from
+[configuration.h](../configuration.h) and platform specific
+`configuration_public.h` files to `configuration_constants.cc` files. They
+have also been changes from macros to `extern const`s. This means that Cobalt
+will be able to evaluate these variables at runtime instead of compile time.
+The declarations for all of these variables are located in
+[configuration_constants.h](../configuration_constants.h), but each platform
+must define each variable individually, i.e. as
+```
+// configuration_constants.cc
+#include "starboard/configuration_constants.h"
+
+const int32_t kSbFileMaxName = 64;
+```
+There are two changes that are a result of this migration:
+
+1. There is no longer any form of inheritance. This means that if there are any
+configuration differences between two platforms, they must have separate
+`configuration_constants.cc` files.
+2. There are no longer default values for any variable. Because we cannot
+inherit values, we would not be able to receive a default value for any one, so
+each platform must have a definition for every configuration variable.
+
+## Migration from GYP Variables to Cobalt Extensions
+
+Cobalt configurations have moved from [cobalt_configuration.gypi](../../cobalt/build/cobalt_configuration.gypi) and platform specific `gyp_configuration.gypi` files to Cobalt extensions, primarily [CobaltExtensionConfigurationApi](../../cobalt/extension/configuration.h), but including the [CobaltExtensionGraphicsApi](../../cobalt/extension/graphics.h).
+
+Some variables were already in the process of being deprecated, sometimes with a replacement. In those cases, that path was followed.
+
+Implementing the Cobalt extension is completely optional, and when calling the functions corresponding to the old GYP variable, there will be a default value that the function will be able to fall back onto if the extension has not been implemented. That being said, if there is a single function the platform needs a custom implementation for, it must completely implement the CobaltExtensionConfigurationApi. For convenience, we have provided default functions to use to define the API if desired.
+
+##### Notes
+
+For migrating from macros, partners will have to treat their use differently! I.e. string literal vs const char* in their implementations. Add an overview of all of the cases of this migration in runtime code.
\ No newline at end of file
diff --git a/src/cobalt/site/docs/gen/starboard/doc/style.md b/src/cobalt/site/docs/gen/starboard/doc/style.md
new file mode 100644
index 0000000..43b3623
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/style.md
@@ -0,0 +1,280 @@
+---
+layout: doc
+title: "Starboard C and C++ Style Guide"
+---
+# Starboard C and C++ Style Guide
+
+A description of the coding conventions for Starboard code and API headers.
+
+**Status:** REVIEWED\
+**Created:** 2016-11-08
+
+Starboard generally tries to follow the coding conventions of Cobalt, which
+itself mostly follows the conventions of Chromium, which mostly follows the
+externally-published Google C++ coding conventions. But, Starboard has some
+special requirements due to its unusual constraints, so it must add a few new
+conventions and loosen some of the existing style prescriptions.
+
+## Background
+
+Before looking at this document, bear in mind that it is not intending to
+completely describe all conventions that apply to Starboard. You probably want
+to take some time to familiarize yourself with these documents first, probably
+in this order:
+
+ * [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)
+ * [Chromium C++ Style Guide](https://chromium.googlesource.com/chromium/src/+/master/styleguide/c++/c++.md)
+ * [Cobalt Style Guide](http://cobalt.foo/broken)
+
+The main additional constraints that Starboard has to deal with are:
+
+ * The Starboard API is defined in straight-C. It must be able to interface
+ with all possible third-party components, many of which are in C and not
+ C++.
+ * Starboard is a public API. Starboard platform implementations and
+ applications written on top of Starboard will change independently. This
+ means there are intense requirements for API stability, usage
+ predictability, searchability, and documentation.
+ * Note that even though it is presented as a "style guide," the conventions
+ presented here are required to be approved for check-in unless otherwise
+ noted.
+
+
+## Definitions
+
+### snake-case
+
+Words separated with underscores.
+
+ lower_snake_case
+ ALL_CAPS_SNAKE_CASE
+
+### camel-case
+
+Words separated by letter capitalization.
+
+ camelCase
+ CapitalizedCamelCase
+
+## C++ Guidelines
+
+What follows are hereby the guidelines for Starboard C and C++ code. Heretofore
+the guidelines follow thusly as follows.
+
+### API Definitions
+
+ * Starboard API definitions must always be compatible with straight-C99 compilers.
+ * All public API declarations must be specified in headers in
+ `src/starboard/*.h`, not in any subdirectories.
+ * Non-public declarations must NOT be specified in headers in
+ `src/starboard/*.h`.
+ * C++ inline helper definitions may be included inside an `#if
+ defined(__cplusplus)` preprocessor block. They must only provide
+ convenience, and must NOT be required for any API functionality.
+ * All public API functions should be exported symbols with the SB_EXPORT
+ attribute.
+ * No non-const variables shall be exposed as part of the public API.
+ * All APIs should be implemented in C++ source files, not straight-C source files.
+
+### Modules
+
+ * Each module header must be contained with a single header file.
+
+ * The name of the module must be the singular form of the noun being
+ interfaced with by the module, without any "sb" or "starboard".
+ * `file.h`
+ * `directory.h`
+ * `window.h`
+ * Module interfaces should not have circular dependencies.
+
+### File Names
+
+ * Like in the other conventions (e.g. Google, Chromium), file names must be in
+ `lower_snake_case`.
+ * File names must not contain `sb_` or `starboard_`.
+ * The name of a module header file must be the `lower_snake_case` form of the
+ module name.
+ * `SbConditionVariable` âž¡ `starboard/condition_variable.h`
+ * A header that is intended to be an internal implementation detail of one or
+ more platform implementations should have the suffix `_internal.h`, and
+ include the header `starboard/shared/internal_only.h`.
+ * See "Implementations" for conventions about where to place implementation files.
+
+### Types
+
+ * Like in the other conventions, types should be `CapitalizedCamelCase`.
+ * Every public Starboard type must start with `Sb`. There are no namespaces in
+ C, so `Sb` is the Starboard namespace.
+ * Every public Starboard type must be declared by a module, and must have the
+ name of the module following the `Sb`.
+ * `file.h` contains `SbFile`, `SbFileInfo`, `SbFileWhence`, etc...
+ * Every seemingly-allocatable, platform-specific Starboard type should be
+ defined as an opaque handle to a publically undefined struct with the
+ `Private` suffix. Follow this pattern for all such type declarations.
+ * `struct SbFilePrivate` is declared, but not defined in the public header.
+ * `SbFilePrivate` is `typedef`'d to `struct SbFilePrivate`. This is a C
+ thing where types are defined as names with the "`struct`" keyword
+ prepended unless `typedef`'d.
+ * `SbFile` is defined as a `typedef` of `struct SbFilePrivate*`.
+ * C structs may be defined internally to have functions and visibility. It is
+ allowed for such structs to have constructors, destructors, methods,
+ members, and public members.
+ * It is also considered idiomatic to never define the private struct but to
+ just treat it like a handle into some other method of object tracking,
+ casting the handle back and forth to the pointer type.
+ * If a word in the name of a type is redundant with the module name, it is
+ omitted.
+ * A monotonic time type in the Time module is `SbTimeMonotonic`, not
+ ~~`SbMonotonicTime`, `SbTimeMonotonicTime`, or
+ `SbTimeMonotonicSbTime`~~.
+
+### Functions
+
+ * Like in the other conventions, functions should be `CapitalizedCamelCase`.
+ * Every public Starboard function must start with `Sb`. There are no namespaces
+ in C, so `Sb` is the Starboard namespace.
+ * Every public Starboard function must be declared by a module, and must have
+ the name of the module following the `Sb`.
+ * `system.h` contains `SbSystemGetPath()`
+ * `file.h` contains `SbFileOpen()`
+ * After the Starboard and Module prefix, functions should start with an
+ imperative verb indicating what the function does.
+ * The Thread module defines `SbThreadCreateLocalKey()` to create a key for
+ thread local storage.
+ * If a word in the name of a function is redundant with the module name, it is
+ omitted.
+ * The `File` module as the function `SbFileOpen`, not ~~`SbOpenFile`,
+ `SbFileOpenFile` or `SbFileOpenSbFile`~~.
+ * If this gets awkward, it may indicate a need to split into a different
+ module.
+
+### Variables, Parameters, Fields
+
+ * Like in the other conventions, variable, function parameter, and field names
+ must be in `lower_snake_case`.
+ * Private member fields end in an underscore.
+ * Public member fields do not end in an underscore.
+
+### Namespaces
+
+Most Starboard API headers are straight-C compatible, so cannot live inside a
+namespace. Implementations, since they implement straight-C interface functions,
+also cannot live inside a namespace.
+
+But, in all other cases, Starboard C++ code should follow the inherited
+conventions and use a namespace for each directory starting with a "starboard"
+namespace at the starboard repository root.
+
+### Preprocessor Macros
+
+ * Like in the other conventions, variable, function parameter, and field names
+ must be in `ALL_CAPS_SNAKE_CASE`.
+ * Macros may be used as compile-time constants because straight-C does not
+ have a proper facility for typed constants. This is as opposed to macros
+ used primarily at preprocessor-time to filter or modify what gets sent to
+ the compiler. Macros used as compile-time constants and that are not
+ configuration parameters should be explicitly-typed with a c-style cast, and
+ should follow the Constants naming conventions.
+ * Macros must start with `SB_`, and then must further be namespaced with the
+ module name, with the exception of configuration definitions.
+ * Configuration definitions should be namespaced with the module name that
+ they primarily affect, if applicable, or a scope that generally indicates
+ its domain.
+ * `SB_FILE_MAX_NAME`
+ * `SB_MEMORY_PAGE_SIZE`
+ * Always use `#if defined(MACRO)` over `#ifdef MACRO`.
+
+### Constants
+
+ * Constants (including enum entries) are named using the Google constant
+ naming convention, `CapitalizedCamelCase`d, but starting with a lower-case
+ `k`.
+ * After the `k`, all constants have `Sb`, the Starboard namespace.
+ * `kSb`
+ * After `kSb`, all constants then have the module name.
+ * `kSbTime`
+ * `kSbFile`
+ * After `kSb<module>` comes the rest of the name of the constant.
+ * `kSbTimeMillisecond`
+ * `kSbFileInvalid`
+ * Enum entries are prefixed with the full name of the enum.
+ * The enum `SbSystemDeviceType` contains entries like
+ `kSbSystemDeviceTypeBlueRayDiskPlayer`.
+
+### Comments
+
+ * All files must have a license and copyright comment.
+ * It is expected that the straight-C compiler supports C99 single-line
+ comments. Block comments should be avoided whenever possible, even in
+ license and copyright headers.
+ * Each public API module file should have a Module Overview documentation
+ comment below the license explaining what the module is for, and how to use
+ it effectively.
+ * The Module Overview must be separated by a completely blank line from the
+ license comment.
+ * The first line of the Module Overview documentation comment must say
+ "`Module Overview: Starboard <module-name> module`", followed by a blank
+ comment line (i.e. a line that contains a `//`, but nothing else).
+ * The first sentence of a documentation comment describing any entity (module,
+ type, function, variable, etc...) should assume "This module," "This type,"
+ "This function," or "This variable" at the beginning of the sentence, and
+ not include it.
+ * The first sentence of a documentation comment describing any entity should
+ be a single-sentence summary description of the entire entity.
+ * The first paragraph of a documentation comment should describe the overall
+ behavior of the entity.
+ * Paragraphs in comments should be separated by a blank comment line.
+ * All public entities must have documentation comments, including enum
+ entries.
+ * Documentation comments should be formatted with Markdown.
+ * Variables, constants, literals, and expressions should be referenced in
+ comments with pipes around them.
+ * All comments must be full grammatically-correct English sentences with
+ proper punctuation.
+ * Comments in Starboard headers must be written as requirements for the
+ porter, for example: "must not return NULL" or "should not return
+ NULL" rather than "will not return NULL". The choice of "must" vs "should"
+ must follow the guidelines of IETF RFC,
+ https://www.ietf.org/rfc/rfc2119.txt .
+
+### Implementations
+
+ * Each API implementation should attempt to minimize other platform
+ assumptions, and should therefore use Starboard APIs to accomplish
+ platform-specific work unless directly related to the platform functionality
+ being implemented.
+ * For example, `SbFile` can use POSIX file I/O, because that what it is
+ abstracting, but it should use `SbMemoryAllocate` for any memory
+ allocations, because it might be used with a variety of `SbMemory`
+ implementations.
+ * Whenever possible, each shared function implementation should be implemented
+ in an individual file so as to maximize the chances of reuse between
+ implementations.
+ * This does not apply to platform-specific functions that have no chance of
+ being reusable on other platforms.
+ * Implementation files that can conceivably be shared between one or more
+ implementations should be placed in a `starboard/shared/<dependency>/`
+ directory, where `<dependency>` is the primary platform dependency of that
+ implementation. (e.g. `libevent`, `posix`, `c++11`, etc.)
+ * Implementation files that don't have a specific platform dependency, but
+ whether to use them should be a platform decision should be placed in
+ `starboard/shared/starboard/`, and must only have dependencies on other
+ Starboard APIs.
+ * Implementation files that definitely can be common to ALL implementations
+ should be placed in `starboard/common/`.
+
+### Language Features
+
+ * In public headers, particularly in inline functions and macros, only C-Style
+ casts may be used, though they are forbidden everywhere else.
+ * It is expected that the C compiler supports inline functions. They must be
+ declared `static`, and they must use the `SB_C_INLINE` or
+ `SB_C_FORCE_INLINE` attribute. In straight-C code, there is no anonymous
+ namespace, so `static` is allowed and required for inline functions.
+ * No straight-C ISO or POSIX headers should be assumed to exist. Basic C++03
+ headers may be assumed to exist in C++ code. The ISO C standards have grown
+ up over a long period of time and have historically been implemented with
+ quirks, missing pieces, and so on. Support for the core C++ standard library
+ is much more consistent on those platforms that do support it.
+ * It is idiomatic to include thin C++ inline wrappers inside public API
+ headers, gated by an `#if defined(cplusplus__)` check.
diff --git a/src/cobalt/site/docs/gen/starboard/doc/versioning.md b/src/cobalt/site/docs/gen/starboard/doc/versioning.md
new file mode 100644
index 0000000..c3e07f1
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/doc/versioning.md
@@ -0,0 +1,245 @@
+---
+layout: doc
+title: "Starboard Versioning"
+---
+# Starboard Versioning
+
+## Motivation
+
+When a porter implements Starboard for a platform, it is more precise to say
+that they have implemented support for a certain version of Starboard.
+Changes to the Starboard API are associated with Starboard versions. Any usage
+of new Starboard APIs must also be protected by a compile-time check for the
+Starboard version it belongs to. This decoupling of Cobalt and Starboard
+versions ensures that a porter can update to a newer version of Cobalt, but not
+be required to implement new Starboard APIs, if the version of Starboard they
+have implemented is still supported.
+
+## Starboard API version vs. Starboard application version
+
+The Starboard version describes the set of Starboard APIs available to Starboard
+applications. It will be incremented with every open-source release that
+includes changes to the Starboard API. Reasons to increment the Starboard API
+version include:
+
+* New Starboard APIs
+* Removed Starboard APIs
+* Modified semantics to existing APIs
+
+Some notable cases that do not justify incrementing the Starboard version
+include:
+
+* More descriptive or clearer comments for existing APIs that do not change the
+ semantics
+* New utility classes that are built on top of Starboard APIs, such as
+ `starboard::ScopedFile`
+* Changes that affect the upward API to Starboard applications, but not the
+ downward API to porters. For example, defining new upward APIs in terms of
+ existing Starboard APIs.
+
+A particular Starboard application may be versioned independently of the
+Starboard API. A given version of a Starboard application may support a range of
+Starboard versions. It may be the case that some new functionality in a
+Starboard application requires Starboard APIs that were added to a particular
+API version. If a porter wants to use such a feature, they must therefore also
+implement the required version of the Starboard API. For example, Voice Search
+was added to Cobalt version 5 and requires the SbMicrophone APIs which were
+added to Starboard version 2. Platforms that implemented Starboard version 1
+continued to build and run Cobalt 5 correctly, but the Voice Search feature
+would be unavailable.
+
+## Range of supported Starboard versions
+
+The minimum supported API version is defined by the `SB_MINIMUM_API_VERSION`
+macro, which is defined in starboard/configuration.h. Likewise, the
+`SB_MAXIMUM_API_VERSION` macro defines the maximum supported API version. All
+platforms must declare a `SB_API_VERSION` macro in the platform’s
+configuration.h to declare the starboard version the platform has implemented.
+Declaring implementation for an API version outside this range will result in an
+error at compilation time.
+Generally Starboard applications will not support all versions of the Starboard
+API indefinitely. Starboard application owners may increment the minimum
+required Starboard version at their discretion.
+TBD: Timelines and communication around when an upcoming Cobalt release will
+require porters to implement a newer version of Starboard.
+
+## Using new Starboard APIs from Starboard Applications
+
+Usage of a Starboard API that is not available in all supported Starboard API
+versions must be guarded with a check for `SB_API_VERSION`. Starboard
+applications must continue to function correctly and must not disable existing
+functionality if this check evaluates to false, but it’s acceptable to disable
+new functionality in Starboard applications if this evaluates to false.
+
+## Adding and using new Starboard APIs
+
+### The "Experimental" Starboard Version
+
+At any given time, exactly one version of Starboard will be denoted as the
+"experimental" version, as defined by the `SB_EXPERIMENTAL_API_VERSION` macro in
+`starboard/configuration.h`. It is generally not recommended to declare support
+for this version. Any Starboard APIs defined in the experimental version are
+subject to change and API requirements could be added, removed, or changed at
+any time.
+
+### The "Release Candidate" Starboard Version
+
+At any given time, zero or more versions of Starboard will be denoted as the
+"release candidate" version, as defined by the
+`SB_RELEASE_CANDIDATE_API_VERSION` macro in `starboard/configuration.h`. The
+"release candidate" version is a set of API changes that have been considered
+and tested together. It is reasonable to port against this version, it has gone
+through some stabilization and may become frozen as it currently is. But, be
+aware that it is possible that minor incompatible changes may be made to this
+version if an unexpected situation arises. `SB_RELEASE_CANDIDATE_API_VERSION` is
+not defined if there is no "release candidate" version. Every API version
+greater than `SB_RELEASE_CANDIDATE_API_VERSION` but less than `SB_EXPERIMENTAL_API_VERSION` is also considered a release candidate.
+
+### "Frozen" Starboard versions
+
+All Starboard versions that are less than the experimental and release candidate
+versions are considered frozen. Any Starboard APIs in a frozen version MUST not
+change.
+
+### Version Numbers, and how They Interrelate Numerically
+
+```
+frozen < release-candidate < experimental < future
+```
+
+As mentioned previously, a release candidate version may or may not exist at any
+given time. When there is a release candate version, it follows the invariant
+above.
+
+### Life of a Starboard API
+
+New Starboard APIs should be defined in the experimental version.
+
+When introducing a new Starboard API (or modifying an existing one), a new
+feature version define should be created within the "Experimental Feature
+Defines" section of `starboard/configuration.h`, and set to
+`SB_EXPERIMENTAL_API_VERSION`. A well written comment should be added in front
+of the feature define that describes exactly what is introduced by the feature.
+In the comment, all new/modified/removed symbols should be identified, and all
+modified header files should be named.
+
+For example,
+
+```
+// in starboard/configuration.h
+
+#define SB_EXPERIMENTAL_API_VERSION 7
+
+#undef SB_RELEASE_CANDIDATE_API_VERSION
+
+// --- Experimental Feature Defines ------------------------------------------
+
+...
+
+// Introduce a new API in starboard/screensaver.h, which declares the following
+// functions for managing the platform's screensaver settings:
+// SbScreensaverDisableScreensaver()
+// SbScreensaverEnableScreensaver()
+// Additionally, a new event, kSbEventTypeScreensaverStarted, is introduced in
+// starboard/event.h.
+#define SB_SCREENSAVER_FEATURE_API_VERSION SB_EXPERIMENTAL_API_VERSION
+
+// Introduce a new API in starboard/new_functionality.h which declares the
+// function SbNewFunctionality().
+#define SB_MY_NEW_FEATURE_API_VERSION SB_EXPERIMENTAL_API_VERSION
+
+// Introduce another new API in starboard/still_in_development.h which
+// declares the function SbStillInDevelopment().
+#define SB_MY_OTHER_NEW_FEATURE_API_VERSION SB_EXPERIMENTAL_API_VERSION
+```
+
+When declaring the new interface, the following syntax should be used:
+
+```
+// starboard/new_functionality.h
+#if SB_API_VERSION >= SB_MY_NEW_FEATURE_API_VERSION
+void SbNewFunctionality();
+#endif
+```
+
+Starboard application features that use a new API must have a similar check:
+
+```
+// cobalt/new_feature.cc
+#if SB_API_VERSION >= SB_MY_NEW_FEATURE_API_VERSION
+void DoSomethingCool() {
+ SbNewFunctionality();
+}
+#endif
+```
+
+When promoting the experimental API version to be the release candidate API
+version, the previously undefined `SB_RELEASE_CANDIDATE_API_VERSION` is set to
+the current value of `SB_EXPERIMENTAL_API_VERSION`, and
+`SB_EXPERIMENTAL_API_VERSION` is then incremented by one. As a result,
+`SB_RELEASE_CANDIDATE_API_VERSION` on the master branch should always either be
+undefined, or `SB_EXPERIMENTAL_API_VERSION - 1`.
+
+One or more features are then moved from `SB_EXPERIMENTAL_API_VERSION` to
+`SB_RELEASE_CANDIDATE_API_VERSION`, and into the "Release Candidate Feature
+Defines" section of `starboard/configuration.h`. Some features may be left in
+experimental if they are not ready for release. The documentation comments of
+these features should be moved into the (newly created) section for the
+corresponding version in [starboard/CHANGELOG.md](../CHANGELOG.md).
+
+```
+// in starboard/configuration.h
+
+#define SB_EXPERIMENTAL_API_VERSION 8
+
+#define SB_RELEASE_CANDIDATE_API_VERSION 7
+
+// --- Experimental Feature Defines ------------------------------------------
+
+// Introduce another new API in starboard/still_in_development.h which
+// declares the function SbStillInDevelopment().
+#define SB_MY_OTHER_NEW_FEATURE_API_VERSION SB_EXPERIMENTAL_API_VERSION
+
+// --- Release Candidate Features Defines ------------------------------------
+
+#define SB_MY_NEW_FEATURE_API_VERSION SB_RELEASE_CANDIDATE_API_VERSION
+
+```
+
+When a release candidate branch is promoted to a full release, these new
+Starboard APIs will be irrevocably frozen to the value of
+`SB_RELEASE_CANDIDATE_API_VERSION`, and the release candidate version will be
+undefined. Additionally, the feature defines should be removed.
+
+```
+// starboard/new_functionality.h
+#if SB_API_VERSION >= 7
+void SbNewFunctionality();
+#endif
+
+// starboard/other_new_functionality.h
+#if SB_API_VERSION >= SB_MY_OTHER_NEW_FEATURE_API_VERSION
+void SbStillInDevelopment();
+#endif
+
+// starboard/configuration.h
+#define SB_EXPERIMENTAL_API_VERSION 8
+#undef SB_RELEASE_CANDIDATE_API_VERSION
+
+// cobalt/new_feature.cc
+#if SB_API_VERSION >= 7
+void DoSomethingCool() {
+ SbNewFunctionality();
+}
+#endif
+```
+
+Whoever increments the experimental version must ensure that stubs and reference
+platforms declare support for the new experimental version through their
+respective `SB_API_VERSION` macros.
+
+### Communicating Starboard API changes to porters
+
+When a new version of Starboard is released, [starboard/CHANGELOG.md](../CHANGELOG.md) should be
+updated with the feature define comments for all features enabled in that
+version.
diff --git a/src/cobalt/site/docs/gen/starboard/tools/doc/abstract_launcher.md b/src/cobalt/site/docs/gen/starboard/tools/doc/abstract_launcher.md
new file mode 100644
index 0000000..e404ea5
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/tools/doc/abstract_launcher.md
@@ -0,0 +1,41 @@
+---
+layout: doc
+title: "App Launchers"
+---
+# App Launchers
+
+The app launcher framework is used to run an executable on a given platform,
+allowing its output/results to be used by other scripts or tools.
+
+## Making an App Launcher
+
+In order to use this framework for your platform, there must be a method called
+"GetLauncher()" in the PlatformConfig class that your platform's
+"gyp_configuration.py" file refers to. It should load and return a module
+containing a class called "Launcher." This class must inherit from the
+AbstractLauncher class in [abstract_launcher.py](../../abstract_launcher.py),
+and must implement at minimum the following abstract methods:
+
+- Run(): Runs the executable, logs its output, and returns its return code.
+ Generally, any app installation work is also done in this method.
+- Kill(): Kills the currently running executable and cleans up any leftover
+ resources such as threads, processes, etc.
+
+Once the above steps are implemented, tools that use this framework, such as
+[Starboard's unit test runner](../../testing/test_runner.py), should work
+properly for your platform. For an example of a Launcher class, see
+[this Linux implementation](../../../linux/shared/launcher.py). For an example
+of the corresponding "GetLauncher()" method, see
+[this gyp_configuration.py file](../../../linux/shared/gyp_configuration.py).
+
+## Using an App Launcher
+
+In order to use this framework in a Python tool, it must import
+abstract_launcher.py and call "abstract_launcher.LauncherFactory()." This
+method returns a Launcher object from the platform specified by its "platform"
+argument. To run the launcher, call its "Run()" method, and to stop it, call
+its "Kill()" method. If your tools need to access the Launcher's output while
+the executable is still running, have it start "Run()" in a separate thread;
+this will allow the main thread to easily read from the Launcher's output file.
+For an example of creating and using a Launcher, see
+[this example](../../example/app_launcher_client.py).
\ No newline at end of file
diff --git a/src/cobalt/site/docs/gen/starboard/tools/doc/testing.md b/src/cobalt/site/docs/gen/starboard/tools/doc/testing.md
new file mode 100644
index 0000000..b9edba5
--- /dev/null
+++ b/src/cobalt/site/docs/gen/starboard/tools/doc/testing.md
@@ -0,0 +1,111 @@
+---
+layout: doc
+title: "Test Runner Documentation"
+---
+# Test Runner Documentation
+
+The scripts in this folder comprise a cross-platform unit test runner. The
+components of this runner are as follows:
+
+## Components
+
+### 1.) test_runner.py
+
+This script is used to run unit test binaries on multiple platforms. To see a
+full list of parameters that can be supplied to the script, run:
+
+ python test_runner.py --help
+
+#### Running Tests:
+
+To run all tests for a given platform, execute the `test_runner.py` script and
+provide at minimum the `--platform` and `--config` arguments.
+
+Example:
+
+ python test_runner.py --platform=android-x86 --config=devel
+
+Running this command will run all unit tests for the `devel` build of the
+`android-x86` platform. To specify a device to run the tests on, provide the
+`--device_id` argument, as shown below:
+
+ python test_runner.py --platform=android-x86 --config=devel \
+ --device_id=emulator-4
+
+#### Running a Single Test:
+
+If you would like to run a single unit test binary and view its output, you can
+do so by using the `--target_name` parameter and providing a test binary name,
+as shown below:
+
+ python test_runner.py --platform=android-x86 --config=devel \
+ --device_id=emulator-4 --target_name=audio_test
+
+#### Building Tests:
+
+You can also use this script to build your unit test binaries before running
+them. To do this, provide the `-b` command line flag. If you would like to
+build the tests and then run them, provide the flags `-br`.
+
+### 2.) Master list of test binaries
+
+In your application's `starboard_configuration.py` file, define a variable
+called TEST_TARGETS. It should be a list containing the names of all of the
+test binaries that you want the test runner to run. An example is shown below:
+
+ TEST_TARGETS =[
+ 'audio_test',
+ 'bindings_test',
+ ]
+
+If your 'starboard_configuration.py' file contains this list, then every
+platform you support in Starboard will try to run these test binaries unless
+they are filtered out as described below.
+
+## Filtering Tests
+
+To filter out tests that you do not want to run for a specific platform,
+implement a method within the platform's `PlatformConfiguration` subclass called
+`GetTestFilters()`. The `PlatformConfiguration` subclass lives in the
+`gyp_configuration.py` file for each platform. If the tests are
+application-specific, you may define `GetTestFilters()` on an optional
+`ApplicationConfiguration` subclass, which will be found in the
+`<platform-directory>/<application-name>/configuration.py` subdirectory. See
+[this Linux implementation](../../linux/x64x11/cobalt/configuration.py) for an
+example.
+
+The `GetTestFilters()` function should return a list of `TestFilter` objects,
+which can be constructed by importing `starboard.tools.testing.test_filter`. To
+make a `TestFilter` object, provide the constructor with the test target name,
+the name of the actual unit test that the target runs, and optionally, the build
+configuration from which the test should be excluded. An example is shown below:
+
+ test_filter.TestFilter('math_test', 'Vector3dTest.IsZero', 'debug')
+
+If a configuration is not provided, then the test will be exluded from all
+configurations.
+
+To filter out all tests for a particular target, provide
+`test_filter.FILTER_ALL` as the test name.
+
+To disable unit testing for all targets and all configurations, return a list
+containing `test_filter.DISABLE_TESTING`.
+
+## Environment Variables
+
+If a platform requires extra environment variables in order to run tests
+properly, implement a method called `GetTestEnvVariables()` in the same
+`PlatformConfiguration` or `ApplicationConfiguration` mentioned above. The
+application-level variables will be merged on top of the platform-level
+variables. There is an example of this method in the provided Linux
+implementation. The method should return a dictionary that maps test binary
+names to dictionaries of environment variables that they need.
+
+Example:
+
+ def GetTestEnvVariables(self):
+ return {
+ 'base_unittests': {'ASAN_OPTIONS': 'detect_leaks=0'},
+ 'crypto_unittests': {'ASAN_OPTIONS': 'detect_leaks=0'},
+ 'net_unittests': {'ASAN_OPTIONS': 'detect_leaks=0'}
+ }
diff --git a/src/cobalt/updater/one_app_only_sandbox.cc b/src/cobalt/updater/one_app_only_sandbox.cc
index 8b31ce4..33e6478 100644
--- a/src/cobalt/updater/one_app_only_sandbox.cc
+++ b/src/cobalt/updater/one_app_only_sandbox.cc
@@ -26,13 +26,17 @@
#include "cobalt/browser/switches.h"
#include "cobalt/version.h"
#include "starboard/event.h"
+#include "starboard/loader_app/app_key.h"
#include "starboard/system.h"
namespace {
+const char kMainAppKey[] = "aHR0cHM6Ly93d3cueW91dHViZS5jb20vdHY=";
+// Use the html instead of url or app key to target the Evergreen cert test
+// page, because there are various urls to launch the test page.
const char kEvergreenCertTestHtml[] = "evergreen-cert-test.html";
-bool is_evergreen_cert_test = false;
+bool is_target_app = false;
cobalt::browser::Application* g_application = NULL;
bool g_is_startup_switch_set = false;
@@ -75,9 +79,8 @@
}
LOG(INFO) << "Concealing application.";
DCHECK(!g_application);
- g_application =
- new cobalt::browser::Application(quit_closure, true /*should_preload*/,
- timestamp);
+ g_application = new cobalt::browser::Application(
+ quit_closure, true /*should_preload*/, timestamp);
DCHECK(g_application);
}
@@ -91,15 +94,13 @@
LOG(INFO) << "Starting application.";
#if SB_API_VERSION >= 13
DCHECK(!g_application);
- g_application =
- new cobalt::browser::Application(quit_closure, false /*not_preload*/,
- timestamp);
+ g_application = new cobalt::browser::Application(
+ quit_closure, false /*not_preload*/, timestamp);
DCHECK(g_application);
#else
if (!g_application) {
- g_application = new cobalt::browser::Application(quit_closure,
- false /*should_preload*/,
- timestamp);
+ g_application = new cobalt::browser::Application(
+ quit_closure, false /*should_preload*/, timestamp);
DCHECK(g_application);
} else {
g_application->Start(timestamp);
@@ -126,7 +127,7 @@
} // namespace
void SbEventHandle(const SbEvent* event) {
- if (is_evergreen_cert_test)
+ if (is_target_app)
return ::cobalt::wrap_main::BaseEventHandler<
PreloadApplication, StartApplication, HandleStarboardEvent,
StopApplication>(event);
@@ -134,19 +135,22 @@
const SbEventStartData* data = static_cast<SbEventStartData*>(event->data);
const base::CommandLine command_line(
data->argument_count, const_cast<const char**>(data->argument_values));
+
if (command_line.HasSwitch(cobalt::browser::switches::kInitialURL)) {
std::string url = command_line.GetSwitchValueASCII(
cobalt::browser::switches::kInitialURL);
- size_t pos = url.find(kEvergreenCertTestHtml);
- if (pos != std::string::npos) {
- // If the url is the Evergreen cert test page, hook up the app lifecycle
- // functions.
- is_evergreen_cert_test = true;
- return ::cobalt::wrap_main::BaseEventHandler<
- PreloadApplication, StartApplication, HandleStarboardEvent,
- StopApplication>(event);
+ if (starboard::loader_app::GetAppKey(url) != kMainAppKey &&
+ url.find(kEvergreenCertTestHtml) == std::string::npos) {
+ // If the app is not the main app nor Evergreen cert test page, stop the
+ // app.
+ SbSystemRequestStop(0);
}
}
- // If the url is not the Evergreen cert test page, stop the app.
- SbSystemRequestStop(0);
+
+ // If the url is the main app or the Evergreen cert test page, hook up the app
+ // lifecycle functions.
+ is_target_app = true;
+ return ::cobalt::wrap_main::BaseEventHandler<
+ PreloadApplication, StartApplication, HandleStarboardEvent,
+ StopApplication>(event);
}
diff --git a/src/cobalt/updater/one_app_only_sandbox.gyp b/src/cobalt/updater/one_app_only_sandbox.gyp
index f311023..0d99d26 100644
--- a/src/cobalt/updater/one_app_only_sandbox.gyp
+++ b/src/cobalt/updater/one_app_only_sandbox.gyp
@@ -20,6 +20,7 @@
'dependencies': [
'<(DEPTH)/cobalt/browser/browser.gyp:browser',
'<(DEPTH)/net/net.gyp:net',
+ '<(DEPTH)/starboard/loader_app/app_key.gyp:app_key',
'<(DEPTH)/starboard/starboard.gyp:starboard',
],
'sources': [
diff --git a/src/cobalt/version.h b/src/cobalt/version.h
index 94b0f68..b338e71 100644
--- a/src/cobalt/version.h
+++ b/src/cobalt/version.h
@@ -35,6 +35,6 @@
// release is cut.
//.
-#define COBALT_VERSION "22.lts.1"
+#define COBALT_VERSION "22.lts.2"
#endif // COBALT_VERSION_H_
diff --git a/src/starboard/BUILD.gn b/src/starboard/BUILD.gn
index b421b3e..b9ab2b6 100644
--- a/src/starboard/BUILD.gn
+++ b/src/starboard/BUILD.gn
@@ -62,6 +62,7 @@
"//third_party/crashpad/client",
"//third_party/crashpad/handler",
]
+ data_deps = [ "//starboard/loader_app" ]
}
}
}
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltSystemConfigChangeReceiver.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltSystemConfigChangeReceiver.java
index 5207655..9f2c5d9 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltSystemConfigChangeReceiver.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltSystemConfigChangeReceiver.java
@@ -31,18 +31,39 @@
CobaltSystemConfigChangeReceiver(Context appContext, Runnable stopRequester) {
this.isForeground = true;
this.stopRequester = stopRequester;
- appContext.registerReceiver(this, new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_LOCALE_CHANGED);
+ filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+ filter.addAction(Intent.ACTION_TIME_CHANGED);
+ filter.addAction(Intent.ACTION_DATE_CHANGED);
+ appContext.registerReceiver(this, filter);
}
@Override
public void onReceive(Context context, Intent intent) {
- if ((!Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) || isForeground) return;
+ if (isForeground) {
+ return;
+ }
- Log.w(TAG, "System locale settings have changed.");
- stopRequester.run();
+ switch (intent.getAction()) {
+ case Intent.ACTION_TIMEZONE_CHANGED:
+ case Intent.ACTION_TIME_CHANGED:
+ case Intent.ACTION_DATE_CHANGED:
+ Log.w(TAG, "System Date or Time have changed.");
+ nativeDateTimeConfigurationChanged();
+ break;
+ case Intent.ACTION_LOCALE_CHANGED:
+ Log.w(TAG, "System locale settings have changed.");
+ stopRequester.run();
+ break;
+ default:
+ Log.w(TAG, "Unknown intent.");
+ }
}
public void setForeground(final boolean isForeground) {
this.isForeground = isForeground;
}
+
+ private native void nativeDateTimeConfigurationChanged();
}
diff --git a/src/starboard/android/shared/application_android.cc b/src/starboard/android/shared/application_android.cc
index 598bed7..45a57af 100644
--- a/src/starboard/android/shared/application_android.cc
+++ b/src/starboard/android/shared/application_android.cc
@@ -247,13 +247,13 @@
if (window_) {
window_->native_window = native_window_;
}
+ // Now that we have the window, signal that the Android UI thread can
+ // continue, before we start or resume the Starboard app.
+ android_command_condition_.Signal();
// Media playback service is tied to UI window being created/destroyed
// (rather than to the Activity lifecycle), the service should be
// stopped before native window being created.
StopMediaPlaybackService();
- // Now that we have the window, signal that the Android UI thread can
- // continue, before we start or resume the Starboard app.
- android_command_condition_.Signal();
}
if (state() == kStateUnstarted) {
// This is the initial launch, so we have to start Cobalt now that we
@@ -261,16 +261,9 @@
env->CallStarboardVoidMethodOrAbort("beforeStartOrResume", "()V");
#if SB_API_VERSION >= 13
DispatchStart(GetAppStartTimestamp());
-#else // SB_API_VERSION >= 13
+#else // SB_API_VERSION >= 13
DispatchStart();
#endif // SB_API_VERSION >= 13
- } else if (state() == kStateConcealed || state() == kStateFrozen) {
-#if SB_API_VERSION >= 13
- DispatchAndDelete(new Event(kSbEventTypeReveal, SbTimeGetMonotonicNow(),
- NULL, NULL));
-#else // SB_API_VERSION >= 13
- DispatchAndDelete(new Event(kSbEventTypeReveal, NULL, NULL));
-#endif // SB_API_VERSION >= 13
} else {
// Now that we got a window back, change the command for the switch
// below to sync up with the current activity lifecycle.
@@ -282,17 +275,13 @@
// early in SendAndroidCommand().
{
ScopedLock lock(android_command_mutex_);
- // Media playback service is tied to UI window being created/destroyed
- // (rather than to the Activity lifecycle). The service should be
- // started after window being destroyed.
- StartMediaPlaybackService();
- // Cobalt can't keep running without a window, even if the Activity
- // hasn't stopped yet. DispatchAndDelete() will inject events as needed
- // if we're not already paused.
+// Cobalt can't keep running without a window, even if the Activity
+// hasn't stopped yet. DispatchAndDelete() will inject events as needed
+// if we're not already paused.
#if SB_API_VERSION >= 13
- DispatchAndDelete(new Event(kSbEventTypeConceal, SbTimeGetMonotonicNow(),
- NULL, NULL));
-#else // SB_API_VERSION >= 13
+ DispatchAndDelete(new Event(kSbEventTypeConceal,
+ SbTimeGetMonotonicNow(), NULL, NULL));
+#else // SB_API_VERSION >= 13
DispatchAndDelete(new Event(kSbEventTypeConceal, NULL, NULL));
#endif // SB_API_VERSION >= 13
if (window_) {
@@ -302,6 +291,10 @@
// Now that we've suspended the Starboard app, and let go of the window,
// signal that the Android UI thread can continue.
android_command_condition_.Signal();
+ // Media playback service is tied to UI window being created/destroyed
+ // (rather than to the Activity lifecycle). The service should be
+ // started after window being destroyed.
+ StartMediaPlaybackService();
}
break;
@@ -349,9 +342,9 @@
} else {
SB_LOG(INFO) << "ApplicationAndroid Inject: kSbEventTypeLink";
#if SB_API_VERSION >= 13
- Inject(new Event(kSbEventTypeLink, SbTimeGetMonotonicNow(),
- deep_link, SbMemoryDeallocate));
-#else // SB_API_VERSION >= 13
+ Inject(new Event(kSbEventTypeLink, SbTimeGetMonotonicNow(), deep_link,
+ SbMemoryDeallocate));
+#else // SB_API_VERSION >= 13
Inject(new Event(kSbEventTypeLink, deep_link, SbMemoryDeallocate));
#endif // SB_API_VERSION >= 13
}
@@ -359,37 +352,37 @@
break;
}
- // If there's a window, sync the app state to the Activity lifecycle, letting
- // DispatchAndDelete() inject events as needed if we missed a state.
+// If there's a window, sync the app state to the Activity lifecycle, letting
+// DispatchAndDelete() inject events as needed if we missed a state.
#if SB_API_VERSION >= 13
-if (native_window_) {
+ if (native_window_) {
switch (sync_state) {
case AndroidCommand::kStart:
- DispatchAndDelete(new Event(kSbEventTypeReveal, SbTimeGetMonotonicNow(),
- NULL, NULL));
+ DispatchAndDelete(
+ new Event(kSbEventTypeReveal, SbTimeGetMonotonicNow(), NULL, NULL));
break;
case AndroidCommand::kResume:
- DispatchAndDelete(new Event(kSbEventTypeFocus, SbTimeGetMonotonicNow(),
- NULL, NULL));
+ DispatchAndDelete(
+ new Event(kSbEventTypeFocus, SbTimeGetMonotonicNow(), NULL, NULL));
break;
case AndroidCommand::kPause:
- DispatchAndDelete(new Event(kSbEventTypeBlur, SbTimeGetMonotonicNow(),
- NULL, NULL));
+ DispatchAndDelete(
+ new Event(kSbEventTypeBlur, SbTimeGetMonotonicNow(), NULL, NULL));
break;
case AndroidCommand::kStop:
if (state() != kStateConcealed && state() != kStateFrozen) {
// We usually conceal when losing the window above, but if the window
// wasn't destroyed (e.g. when Daydream starts) then we still have to
// conceal when the Activity is stopped.
- DispatchAndDelete(new Event(kSbEventTypeConceal, SbTimeGetMonotonicNow(),
- NULL, NULL));
+ DispatchAndDelete(new Event(kSbEventTypeConceal,
+ SbTimeGetMonotonicNow(), NULL, NULL));
}
break;
default:
break;
}
}
-#else // SB_API_VERSION >= 13
+#else // SB_API_VERSION >= 13
if (native_window_) {
switch (sync_state) {
case AndroidCommand::kStart:
@@ -671,8 +664,7 @@
SbTimeMonotonic ApplicationAndroid::GetAppStartTimestamp() {
JniEnvExt* env = JniEnvExt::Get();
jlong app_start_timestamp =
- env->CallStarboardLongMethodOrAbort("getAppStartTimestamp",
- "()J");
+ env->CallStarboardLongMethodOrAbort("getAppStartTimestamp", "()J");
return app_start_timestamp;
}
@@ -684,6 +676,19 @@
return SbTimeGetMonotonicNow();
}
+void ApplicationAndroid::SendDateTimeConfigurationChangedEvent() {
+ // Set the timezone to allow SbTimeZoneGetName() to return updated timezone.
+ tzset();
+ Inject(new Event(kSbEventDateTimeConfigurationChanged, NULL, NULL));
+}
+
+extern "C" SB_EXPORT_PLATFORM void
+Java_dev_cobalt_coat_CobaltSystemConfigChangeReceiver_nativeDateTimeConfigurationChanged(
+ JNIEnv* env,
+ jobject jcaller) {
+ ApplicationAndroid::Get()->SendDateTimeConfigurationChangedEvent();
+}
+
} // namespace shared
} // namespace android
} // namespace starboard
diff --git a/src/starboard/android/shared/application_android.h b/src/starboard/android/shared/application_android.h
index 1c8dde4..6e5a458 100644
--- a/src/starboard/android/shared/application_android.h
+++ b/src/starboard/android/shared/application_android.h
@@ -94,6 +94,8 @@
void OsNetworkStatusChange(bool became_online);
SbTimeMonotonic GetAppStartTimestamp();
+ void SendDateTimeConfigurationChangedEvent();
+
protected:
// --- Application overrides ---
void Initialize() override;
diff --git a/src/starboard/android/shared/install_target.gni b/src/starboard/android/shared/install_target.gni
index 4111a06..1442c9f 100644
--- a/src/starboard/android/shared/install_target.gni
+++ b/src/starboard/android/shared/install_target.gni
@@ -89,6 +89,8 @@
"-P",
"cobaltProductDir=$root_out_dir",
"-P",
+ "cobaltLibraryDir=$root_out_dir",
+ "-P",
"cobaltTarget=$installable_target_name",
"-P",
"enableVulkan=$enable_vulkan",
diff --git a/src/starboard/android/shared/launcher.py b/src/starboard/android/shared/launcher.py
index abd2787..2e90983 100644
--- a/src/starboard/android/shared/launcher.py
+++ b/src/starboard/android/shared/launcher.py
@@ -450,3 +450,7 @@
def GetDeviceIp(self):
"""Gets the device IP. TODO: Implement."""
return None
+
+ def GetDeviceOutputPath(self):
+ """Writable path where test targets can output files"""
+ return '/data/data/{}/cache/'.format(_APP_PACKAGE_NAME)
diff --git a/src/starboard/android/shared/media_is_video_supported.cc b/src/starboard/android/shared/media_is_video_supported.cc
index 095a698..09895ed 100644
--- a/src/starboard/android/shared/media_is_video_supported.cc
+++ b/src/starboard/android/shared/media_is_video_supported.cc
@@ -42,13 +42,13 @@
return false;
}
JniEnvExt* env = JniEnvExt::Get();
+ ScopedLocalJavaRef<jstring> j_mime(env->NewStringStandardUTFOrAbort(mime));
// An HDR capable VP9 or AV1 decoder is needed to handle HDR at all.
bool has_hdr_capable_decoder =
JniEnvExt::Get()->CallStaticBooleanMethodOrAbort(
"dev/cobalt/media/MediaCodecUtil", "hasHdrCapableVideoDecoder",
- "(Ljava/lang/String;)Z",
- env->NewStringStandardUTFOrAbort(mime)) == JNI_TRUE;
+ "(Ljava/lang/String;)Z", j_mime.Get()) == JNI_TRUE;
if (!has_hdr_capable_decoder) {
return false;
}
@@ -98,14 +98,16 @@
// Check extended parameters for correctness and return false if any invalid
// invalid params are found.
MimeType mime_type(content_type);
- // Allows for enabling tunneled playback. Disabled by default.
- // https://source.android.com/devices/tv/multimedia-tunneling
- mime_type.RegisterBoolParameter("tunnelmode");
- // Override endianness on HDR Info header. Defaults to little.
- mime_type.RegisterStringParameter("hdrinfoendianness", "big|little");
+ if (strlen(content_type) > 0) {
+ // Allows for enabling tunneled playback. Disabled by default.
+ // https://source.android.com/devices/tv/multimedia-tunneling
+ mime_type.RegisterBoolParameter("tunnelmode");
+ // Override endianness on HDR Info header. Defaults to little.
+ mime_type.RegisterStringParameter("hdrinfoendianness", "big|little");
- if (!mime_type.is_valid()) {
- return false;
+ if (!mime_type.is_valid()) {
+ return false;
+ }
}
bool must_support_tunnel_mode =
diff --git a/src/starboard/android/shared/microphone_impl.cc b/src/starboard/android/shared/microphone_impl.cc
index 1972d0e..68c4188 100644
--- a/src/starboard/android/shared/microphone_impl.cc
+++ b/src/starboard/android/shared/microphone_impl.cc
@@ -18,10 +18,12 @@
#include <SLES/OpenSLES_Android.h>
#include <algorithm>
+#include <cstddef>
#include <queue>
#include "starboard/android/shared/jni_env_ext.h"
#include "starboard/common/log.h"
+#include "starboard/common/mutex.h"
#include "starboard/common/scoped_ptr.h"
#include "starboard/memory.h"
#include "starboard/shared/starboard/thread_checker.h"
@@ -83,8 +85,10 @@
// Keeps track of the microphone's current state.
State state_;
// Audio data that has been delivered to the buffer queue.
+ Mutex delivered_queue_mutex_;
std::queue<int16_t*> delivered_queue_;
// Audio data that is ready to be read.
+ Mutex ready_queue_mutex_;
std::queue<int16_t*> ready_queue_;
};
@@ -169,7 +173,10 @@
for (int i = 0; i < kNumOfOpenSLESBuffers; ++i) {
int16_t* buffer = new int16_t[kSamplesPerBuffer];
memset(buffer, 0, kBufferSizeInBytes);
- delivered_queue_.push(buffer);
+ {
+ ScopedLock lock(delivered_queue_mutex_);
+ delivered_queue_.push(buffer);
+ }
SLresult result =
(*buffer_object_)->Enqueue(buffer_object_, buffer, kBufferSizeInBytes);
if (!CheckReturnValue(result)) {
@@ -245,14 +252,17 @@
int read_bytes = 0;
scoped_ptr<int16_t> buffer;
- // Go through the ready queue, reading and sending audio data.
- while (!ready_queue_.empty() &&
- audio_data_size - read_bytes >= kBufferSizeInBytes) {
- buffer.reset(ready_queue_.front());
- memcpy(static_cast<uint8_t*>(out_audio_data) + read_bytes,
- buffer.get(), kBufferSizeInBytes);
- ready_queue_.pop();
- read_bytes += kBufferSizeInBytes;
+ {
+ ScopedLock lock(ready_queue_mutex_);
+ // Go through the ready queue, reading and sending audio data.
+ while (!ready_queue_.empty() &&
+ audio_data_size - read_bytes >= kBufferSizeInBytes) {
+ buffer.reset(ready_queue_.front());
+ memcpy(static_cast<uint8_t*>(out_audio_data) + read_bytes, buffer.get(),
+ kBufferSizeInBytes);
+ ready_queue_.pop();
+ read_bytes += kBufferSizeInBytes;
+ }
}
buffer.reset();
@@ -272,18 +282,29 @@
}
void SbMicrophoneImpl::SwapAndPublishBuffer() {
- if (!delivered_queue_.empty()) {
- // The front item in the delivered queue already has the buffered data, so
- // move it from the delivered queue to the ready queue for future reads.
- int16_t* buffer = delivered_queue_.front();
- delivered_queue_.pop();
+ int16_t* buffer = nullptr;
+ {
+ ScopedLock lock(delivered_queue_mutex_);
+ if (!delivered_queue_.empty()) {
+ // The front item in the delivered queue already has the buffered data, so
+ // move it from the delivered queue to the ready queue for future reads.
+ buffer = delivered_queue_.front();
+ delivered_queue_.pop();
+ }
+ }
+
+ if (buffer != NULL) {
+ ScopedLock lock(ready_queue_mutex_);
ready_queue_.push(buffer);
}
if (state_ == kOpened) {
int16_t* buffer = new int16_t[kSamplesPerBuffer];
memset(buffer, 0, kBufferSizeInBytes);
- delivered_queue_.push(buffer);
+ {
+ ScopedLock lock(delivered_queue_mutex_);
+ delivered_queue_.push(buffer);
+ }
SLresult result =
(*buffer_object_)->Enqueue(buffer_object_, buffer, kBufferSizeInBytes);
CheckReturnValue(result);
@@ -437,14 +458,20 @@
}
}
- while (!delivered_queue_.empty()) {
- delete[] delivered_queue_.front();
- delivered_queue_.pop();
+ {
+ ScopedLock lock(delivered_queue_mutex_);
+ while (!delivered_queue_.empty()) {
+ delete[] delivered_queue_.front();
+ delivered_queue_.pop();
+ }
}
- while (!ready_queue_.empty()) {
- delete[] ready_queue_.front();
- ready_queue_.pop();
+ {
+ ScopedLock lock(ready_queue_mutex_);
+ while (!ready_queue_.empty()) {
+ delete[] ready_queue_.front();
+ ready_queue_.pop();
+ }
}
}
diff --git a/src/starboard/android/shared/player_create.cc b/src/starboard/android/shared/player_create.cc
index f4c4083..e9e1041 100644
--- a/src/starboard/android/shared/player_create.cc
+++ b/src/starboard/android/shared/player_create.cc
@@ -17,6 +17,8 @@
#include "starboard/android/shared/video_decoder.h"
#include "starboard/android/shared/video_window.h"
#include "starboard/common/log.h"
+#include "starboard/common/media.h"
+#include "starboard/common/string.h"
#include "starboard/configuration.h"
#include "starboard/decode_target.h"
#include "starboard/shared/starboard/player/filter/filter_based_player_worker_handler.h"
@@ -37,8 +39,15 @@
SbPlayerErrorFunc player_error_func,
void* context,
SbDecodeTargetGraphicsContextProvider* provider) {
+ if (!player_error_func) {
+ SB_LOG(ERROR) << "|player_error_func| cannot be null.";
+ return kSbPlayerInvalid;
+ }
+
if (!creation_param) {
SB_LOG(ERROR) << "CreationParam cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "CreationParam cannot be null");
return kSbPlayerInvalid;
}
@@ -56,15 +65,22 @@
if (!audio_mime) {
SB_LOG(ERROR) << "creation_param->audio_sample_info.mime cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "creation_param->audio_sample_info.mime cannot be null");
return kSbPlayerInvalid;
}
if (!video_mime) {
SB_LOG(ERROR) << "creation_param->video_sample_info.mime cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "creation_param->video_sample_info.mime cannot be null");
return kSbPlayerInvalid;
}
if (!max_video_capabilities) {
SB_LOG(ERROR) << "creation_param->video_sample_info.max_video_capabilities"
<< " cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "creation_param->video_sample_info.max_video_"
+ "capabilities cannot be null");
return kSbPlayerInvalid;
}
@@ -73,8 +89,24 @@
<< "\", and max video capabilities \"" << max_video_capabilities
<< "\".";
- if (!sample_deallocate_func || !decoder_status_func || !player_status_func ||
- !player_error_func) {
+ if (!sample_deallocate_func) {
+ SB_LOG(ERROR) << "|sample_deallocate_func| cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "|sample_deallocate_func| cannot be null.");
+ return kSbPlayerInvalid;
+ }
+
+ if (!decoder_status_func) {
+ SB_LOG(ERROR) << "|decoder_status_func| cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "|decoder_status_func| cannot be null.");
+ return kSbPlayerInvalid;
+ }
+
+ if (!player_status_func) {
+ SB_LOG(ERROR) << "|player_status_func| cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "|player_status_func| cannot be null.");
return kSbPlayerInvalid;
}
@@ -86,7 +118,13 @@
audio_codec != kSbMediaAudioCodecAc3 &&
audio_codec != kSbMediaAudioCodecEac3 &&
audio_codec != kSbMediaAudioCodecOpus) {
- SB_LOG(ERROR) << "Unsupported audio codec " << audio_codec;
+ SB_LOG(ERROR) << "Unsupported audio codec: "
+ << starboard::GetMediaAudioCodecName(audio_codec) << ".";
+ player_error_func(
+ kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ starboard::FormatString("Unsupported audio codec: %s",
+ starboard::GetMediaAudioCodecName(audio_codec))
+ .c_str());
return kSbPlayerInvalid;
}
@@ -95,7 +133,13 @@
video_codec != kSbMediaVideoCodecH265 &&
video_codec != kSbMediaVideoCodecVp9 &&
video_codec != kSbMediaVideoCodecAv1) {
- SB_LOG(ERROR) << "Unsupported video codec " << video_codec;
+ SB_LOG(ERROR) << "Unsupported video codec: "
+ << starboard::GetMediaVideoCodecName(video_codec) << ".";
+ player_error_func(
+ kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ starboard::FormatString("Unsupported video codec: %s",
+ starboard::GetMediaVideoCodecName(video_codec))
+ .c_str());
return kSbPlayerInvalid;
}
@@ -103,20 +147,33 @@
video_codec == kSbMediaVideoCodecNone) {
SB_LOG(ERROR) << "SbPlayerCreate() requires at least one audio track or"
<< " one video track.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "SbPlayerCreate() requires at least one audio track or "
+ "one video track");
return kSbPlayerInvalid;
}
+ std::string error_message;
if (has_audio && creation_param->audio_sample_info.number_of_channels >
SbAudioSinkGetMaxChannels()) {
- SB_LOG(ERROR) << "creation_param->audio_sample_info.number_of_channels"
- << " exceeds the maximum number of audio channels supported"
- << " by this platform.";
+ error_message = starboard::FormatString(
+ "Number of audio channels (%d) exceeds the maximum number of audio "
+ "channels supported by this platform (%d)",
+ creation_param->audio_sample_info.number_of_channels,
+ SbAudioSinkGetMaxChannels());
+ SB_LOG(ERROR) << error_message << ".";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ error_message.c_str());
return kSbPlayerInvalid;
}
auto output_mode = creation_param->output_mode;
if (SbPlayerGetPreferredOutputMode(creation_param) != output_mode) {
- SB_LOG(ERROR) << "Unsupported player output mode " << output_mode;
+ error_message = starboard::FormatString(
+ "Unsupported player output mode: %d", output_mode);
+ SB_LOG(ERROR) << error_message << ".";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ error_message.c_str());
return kSbPlayerInvalid;
}
@@ -127,8 +184,16 @@
// support one main player on Android, which can be either in punch out mode
// or decode to target mode.
const int kMaxNumberOfHardwareDecoders = 1;
- if (VideoDecoder::number_of_hardware_decoders() >=
- kMaxNumberOfHardwareDecoders) {
+ auto number_of_hardware_decoders =
+ VideoDecoder::number_of_hardware_decoders();
+ if (number_of_hardware_decoders >= kMaxNumberOfHardwareDecoders) {
+ error_message = starboard::FormatString(
+ "Number of hardware decoders (%d) is equal to or exceeds the max "
+ "number of hardware decoders supported by this platform (%d)",
+ number_of_hardware_decoders, kMaxNumberOfHardwareDecoders);
+ SB_LOG(ERROR) << error_message << ".";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ error_message.c_str());
return kSbPlayerInvalid;
}
}
@@ -143,6 +208,8 @@
if (!starboard::android::shared::VideoSurfaceHolder::
IsVideoSurfaceAvailable()) {
SB_LOG(ERROR) << "Video surface is not available now.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "Video surface is not available now");
return kSbPlayerInvalid;
}
}
@@ -161,5 +228,12 @@
SbPlayerSetBounds(player, 0, 0, 0, 0, 0);
}
+ if (!SbPlayerIsValid(player)) {
+ SB_LOG(ERROR)
+ << "Invalid player returned by SbPlayerPrivate::CreateInstance().";
+ player_error_func(
+ kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "Invalid player returned by SbPlayerPrivate::CreateInstance()");
+ }
return player;
}
diff --git a/src/starboard/android/shared/window_get_size.cc b/src/starboard/android/shared/window_get_size.cc
index a6182c4..744e233 100644
--- a/src/starboard/android/shared/window_get_size.cc
+++ b/src/starboard/android/shared/window_get_size.cc
@@ -29,6 +29,10 @@
return false;
}
+ if (window->native_window == NULL) {
+ SB_DLOG(ERROR) << __FUNCTION__ << ": Native window has been destroyed.";
+ return false;
+ }
size->width = ANativeWindow_getWidth(window->native_window);
size->height = ANativeWindow_getHeight(window->native_window);
diff --git a/src/starboard/android/x86/gyp_configuration.py b/src/starboard/android/x86/gyp_configuration.py
index 80de3ec..0df1f47 100644
--- a/src/starboard/android/x86/gyp_configuration.py
+++ b/src/starboard/android/x86/gyp_configuration.py
@@ -54,16 +54,6 @@
'AudioDecoderTests/*',
'VideoDecoderTests/*',
- 'PlayerComponentsTests/PlayerComponentsTest.Preroll/*',
- 'PlayerComponentsTests/PlayerComponentsTest.Pause/*',
-
- 'PlayerComponentsTests/PlayerComponentsTest.*/2',
- 'PlayerComponentsTests/PlayerComponentsTest.*/4',
- 'PlayerComponentsTests/PlayerComponentsTest.*/9',
- 'PlayerComponentsTests/PlayerComponentsTest.*/11',
- 'PlayerComponentsTests/PlayerComponentsTest.*/16',
- 'PlayerComponentsTests/PlayerComponentsTest.*/17',
- 'PlayerComponentsTests/PlayerComponentsTest.*/20',
- 'PlayerComponentsTests/PlayerComponentsTest.*/21',
+ 'PlayerComponentsTests/*',
],
}
diff --git a/src/starboard/build/collect_deploy_content.gypi b/src/starboard/build/collect_deploy_content.gypi
index 4068e57..65953f5 100644
--- a/src/starboard/build/collect_deploy_content.gypi
+++ b/src/starboard/build/collect_deploy_content.gypi
@@ -51,7 +51,7 @@
'collect_deploy_content_extra_args': [ '--use_absolute_symlinks' ],
}
}],
- ['cobalt_docker_build == 1 and host_os == "win"', {
+ ['cobalt_docker_build == 1 and host_os == "win" and cobalt_fastbuild != 1', {
'variables': {
'collect_deploy_content_extra_args': [ '--copy_override' ],
}
diff --git a/src/starboard/build/collect_deploy_content.py b/src/starboard/build/collect_deploy_content.py
index 3f03b9d..3b4ce71 100755
--- a/src/starboard/build/collect_deploy_content.py
+++ b/src/starboard/build/collect_deploy_content.py
@@ -12,7 +12,7 @@
# 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.
-"""Builds a symlink farm pointing to specified subdirectories of the input dir."""
+"""Builds a symlink farm pointing to specified subdirs of the input dir."""
import argparse
import logging
@@ -21,7 +21,7 @@
import sys
import _env # pylint: disable=unused-import
-import starboard.tools.port_symlink as port_symlink
+from starboard.tools import port_symlink
from starboard.tools import log_level
# The name of an environment variable that when set to |'1'|, signals to us that
@@ -60,6 +60,7 @@
raise RuntimeError('Content is %d levels deep (max allowed is %d): %s' %
(depth, max_depth, deepest_file))
+
def _CopyTree(src_path, dst_path):
"""Copy tree with a safeguard for windows long path (>260).
@@ -74,6 +75,7 @@
dst_path = prefix + dst_path
shutil.copytree(src_path, dst_path)
+
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument(
diff --git a/src/starboard/build/install/install_target.gni b/src/starboard/build/install/install_target.gni
index aa7e715..e072622 100644
--- a/src/starboard/build/install/install_target.gni
+++ b/src/starboard/build/install/install_target.gni
@@ -15,8 +15,10 @@
template("install_target") {
if (invoker.type == "executable") {
install_subdir = "bin"
+ source_name = invoker.installable_target_name
} else if (invoker.type == "shared_library") {
install_subdir = "lib"
+ source_name = "lib${invoker.installable_target_name}.so"
} else {
assert(false, "You can only install an executable or shared library.")
}
@@ -29,7 +31,7 @@
])
deps = [ ":$installable_target_name" ]
- sources = [ "$root_out_dir/$installable_target_name" ]
+ sources = [ "$root_out_dir/$source_name" ]
outputs = [ "$root_out_dir/install/$install_subdir/{{source_file_part}}" ]
}
diff --git a/src/starboard/doc/evergreen/cobalt_evergreen_overview.md b/src/starboard/doc/evergreen/cobalt_evergreen_overview.md
index 51130f1..001f324 100644
--- a/src/starboard/doc/evergreen/cobalt_evergreen_overview.md
+++ b/src/starboard/doc/evergreen/cobalt_evergreen_overview.md
@@ -503,16 +503,17 @@
### Fonts
The system font directory `kSbSystemPathFontDirectory` should be configured to
-point to the `standard` (23MB) or the `limited` (3.1MB) cobalt font packages. An
-easy way to do that is to use the `kSbSystemPathContentDirectory` to contain
-the system font directory and setting the `cobalt_font_package` to `standard` or
-`limited` in your port.
+point to either the system fonts on the device or the Cobalt `standard` (23MB)
+or the Cobalt `limited` (3.1MB) font packages. An easy way to use the Cobalt
+fonts is to set `kSbSystemPathFontDirectory` to point to
+`kSbSystemPathContentDirectory/fonts` and configure `cobalt_font_package` to
+`standard` or `limited` in your port.
Cobalt Evergreen (built by Google), will by default use the `empty` font
package to minimize storage requirements. A separate
`cobalt_font_package` variable is set to `empty` in the Evergreen platform.
-On Raspberry Pi this is:
+On Raspberry Pi the Cobalt fonts are configured the following way:
`empty` set of fonts under:
```
diff --git a/src/starboard/elf_loader/elf_header_test.cc b/src/starboard/elf_loader/elf_header_test.cc
index a00805b..cb03d42 100644
--- a/src/starboard/elf_loader/elf_header_test.cc
+++ b/src/starboard/elf_loader/elf_header_test.cc
@@ -14,6 +14,8 @@
#include "starboard/elf_loader/elf_header.h"
+#include <string>
+
#include "starboard/common/scoped_ptr.h"
#include "starboard/elf_loader/file.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -30,7 +32,10 @@
public:
DummyFile(const char* buffer, int size) : buffer_(buffer), size_(size) {}
- bool Open(const char* name) { return true; }
+ bool Open(const char* name) {
+ name_ = name;
+ return true;
+ }
bool ReadFromOffset(int64_t offset, char* buffer, int size) {
SB_LOG(INFO) << "ReadFromOffset";
if (offset != 0) {
@@ -46,9 +51,12 @@
}
void Close() {}
+ const std::string& GetName() { return name_; }
+
private:
const char* buffer_;
int size_;
+ std::string name_;
};
class ElfHeaderTest : public ::testing::Test {
diff --git a/src/starboard/elf_loader/elf_loader_impl.cc b/src/starboard/elf_loader/elf_loader_impl.cc
index 7445332..cf392a9 100644
--- a/src/starboard/elf_loader/elf_loader_impl.cc
+++ b/src/starboard/elf_loader/elf_loader_impl.cc
@@ -34,8 +34,7 @@
if (s.size() < suffix.size()) {
return false;
}
- return strcmp(s.c_str() + (s.size() - suffix.size()),
- suffix.c_str()) == 0;
+ return strcmp(s.c_str() + (s.size() - suffix.size()), suffix.c_str()) == 0;
}
} // namespace
@@ -68,7 +67,18 @@
SB_DLOG(INFO) << "Loaded ELF header";
- program_table_.reset(new ProgramTable());
+ const auto* memory_mapped_file_extension =
+ reinterpret_cast<const CobaltExtensionMemoryMappedFileApi*>(
+ SbSystemGetExtension(kCobaltExtensionMemoryMappedFileName));
+ if (memory_mapped_file_extension &&
+ strcmp(memory_mapped_file_extension->name,
+ kCobaltExtensionMemoryMappedFileName) == 0 &&
+ memory_mapped_file_extension->version >= 1) {
+ program_table_.reset(new ProgramTable(memory_mapped_file_extension));
+ } else {
+ program_table_.reset(new ProgramTable(nullptr));
+ }
+
program_table_->LoadProgramHeader(elf_header_loader_->GetHeader(),
elf_file_.get());
diff --git a/src/starboard/elf_loader/file.h b/src/starboard/elf_loader/file.h
index ad9b701..0fd4a3d 100644
--- a/src/starboard/elf_loader/file.h
+++ b/src/starboard/elf_loader/file.h
@@ -15,6 +15,8 @@
#ifndef STARBOARD_ELF_LOADER_FILE_H_
#define STARBOARD_ELF_LOADER_FILE_H_
+#include <string>
+
#include "starboard/types.h"
namespace starboard {
@@ -35,6 +37,9 @@
// Closes the underlying file.
virtual void Close() = 0;
+ // Returns the name of the file.
+ virtual const std::string& GetName() = 0;
+
virtual ~File() {}
};
diff --git a/src/starboard/elf_loader/file_impl.cc b/src/starboard/elf_loader/file_impl.cc
index 94ee465..951db5f 100644
--- a/src/starboard/elf_loader/file_impl.cc
+++ b/src/starboard/elf_loader/file_impl.cc
@@ -39,6 +39,7 @@
bool FileImpl::Open(const char* name) {
SB_DLOG(INFO) << "Loading: " << name;
+ name_ = name;
file_ = SbFileOpen(name, kSbFileOpenOnly | kSbFileRead, NULL, NULL);
if (!file_) {
return false;
@@ -72,5 +73,9 @@
}
}
+const std::string& FileImpl::GetName() {
+ return name_;
+}
+
} // namespace elf_loader
} // namespace starboard
diff --git a/src/starboard/elf_loader/file_impl.h b/src/starboard/elf_loader/file_impl.h
index ebd1c92..a6a30bd 100644
--- a/src/starboard/elf_loader/file_impl.h
+++ b/src/starboard/elf_loader/file_impl.h
@@ -16,6 +16,9 @@
#define STARBOARD_ELF_LOADER_FILE_IMPL_H_
#include "starboard/elf_loader/file.h"
+
+#include <string>
+
#include "starboard/file.h"
namespace starboard {
@@ -29,9 +32,11 @@
bool Open(const char* name) override;
bool ReadFromOffset(int64_t offset, char* buffer, int size) override;
void Close() override;
+ const std::string& GetName() override;
protected:
SbFile file_;
+ std::string name_;
FileImpl(const FileImpl&) = delete;
void operator=(const FileImpl&) = delete;
diff --git a/src/starboard/elf_loader/program_table.cc b/src/starboard/elf_loader/program_table.cc
index 2684338..61d823c 100644
--- a/src/starboard/elf_loader/program_table.cc
+++ b/src/starboard/elf_loader/program_table.cc
@@ -35,14 +35,16 @@
namespace starboard {
namespace elf_loader {
-ProgramTable::ProgramTable()
+ProgramTable::ProgramTable(
+ const CobaltExtensionMemoryMappedFileApi* memory_mapped_file_extension)
: phdr_num_(0),
phdr_mmap_(NULL),
phdr_table_(NULL),
phdr_size_(0),
load_start_(NULL),
load_size_(0),
- base_memory_address_(0) {}
+ base_memory_address_(0),
+ memory_mapped_file_extension_(memory_mapped_file_extension) {}
bool ProgramTable::LoadProgramHeader(const Ehdr* elf_header, File* elf_file) {
if (!elf_header) {
@@ -77,39 +79,52 @@
SB_DLOG(INFO) << "page_max - page_min=" << page_max - page_min;
-#if SB_API_VERSION >= 12 || SB_HAS(MMAP)
- phdr_mmap_ =
- SbMemoryMap(phdr_size_, kSbMemoryMapProtectWrite, "program_header");
- if (!phdr_mmap_) {
- SB_LOG(ERROR) << "Failed to allocate memory";
- return false;
- }
+ if (memory_mapped_file_extension_) {
+ SB_DLOG(INFO) << "Memory mapped file for the program header";
+ phdr_mmap_ = memory_mapped_file_extension_->MemoryMapFile(
+ NULL, elf_file->GetName().c_str(), kSbMemoryMapProtectRead, page_min,
+ phdr_size_);
+ if (!phdr_mmap_) {
+ SB_LOG(ERROR) << "Failed to memory map the program header";
+ return false;
+ }
- SB_DLOG(INFO) << "Allocated address=" << phdr_mmap_;
-#else
- SB_CHECK(false);
-#endif
- if (!elf_file->ReadFromOffset(page_min, reinterpret_cast<char*>(phdr_mmap_),
- phdr_size_)) {
- SB_LOG(ERROR) << "Failed to read program header from file offset: "
- << page_min;
- return false;
- }
+ SB_DLOG(INFO) << "Allocated address=" << phdr_mmap_;
+ } else {
#if SB_API_VERSION >= 12 || SB_HAS(MMAP)
- bool mp_result =
- SbMemoryProtect(phdr_mmap_, phdr_size_, kSbMemoryMapProtectRead);
- SB_DLOG(INFO) << "mp_result=" << mp_result;
- if (!mp_result) {
- SB_LOG(ERROR) << "Failed to protect program header";
- return false;
- }
+ phdr_mmap_ =
+ SbMemoryMap(phdr_size_, kSbMemoryMapProtectWrite, "program_header");
+ if (!phdr_mmap_) {
+ SB_LOG(ERROR) << "Failed to allocate memory";
+ return false;
+ }
+
+ SB_DLOG(INFO) << "Allocated address=" << phdr_mmap_;
#else
- SB_CHECK(false);
+ SB_CHECK(false);
#endif
+ if (!elf_file->ReadFromOffset(page_min, reinterpret_cast<char*>(phdr_mmap_),
+ phdr_size_)) {
+ SB_LOG(ERROR) << "Failed to read program header from file offset: "
+ << page_min;
+ return false;
+ }
+#if SB_API_VERSION >= 12 || SB_HAS(MMAP)
+ bool mp_result =
+ SbMemoryProtect(phdr_mmap_, phdr_size_, kSbMemoryMapProtectRead);
+ SB_DLOG(INFO) << "mp_result=" << mp_result;
+ if (!mp_result) {
+ SB_LOG(ERROR) << "Failed to protect program header";
+ return false;
+ }
+#else
+ SB_CHECK(false);
+#endif
+ }
phdr_table_ = reinterpret_cast<Phdr*>(reinterpret_cast<char*>(phdr_mmap_) +
page_offset);
-
+ SB_DLOG(INFO) << "phdr_table_=" << phdr_table_;
return true;
}
@@ -186,20 +201,33 @@
SB_DLOG(INFO) << "segment prot_flags=" << std::hex << prot_flags;
void* seg_addr = reinterpret_cast<void*>(seg_page_start);
- bool mp_ret =
- SbMemoryProtect(seg_addr, file_length, kSbMemoryMapProtectWrite);
- SB_DLOG(INFO) << "segment vaddress=" << seg_addr;
+ bool mp_ret = false;
+ if (memory_mapped_file_extension_) {
+ SB_DLOG(INFO) << "Using Memory Mapped File for Loading the Segment";
+ void* p = memory_mapped_file_extension_->MemoryMapFile(
+ seg_addr, elf_file->GetName().c_str(), kSbMemoryMapProtectRead,
+ file_page_start, file_length);
+ if (!p) {
+ SB_LOG(ERROR) << "Failed to memory map file: " << elf_file->GetName();
+ return false;
+ }
+ } else {
+ SB_DLOG(INFO) << "Not using Memory Mapped Files";
+ mp_ret =
+ SbMemoryProtect(seg_addr, file_length, kSbMemoryMapProtectWrite);
+ SB_DLOG(INFO) << "segment vaddress=" << seg_addr;
- if (!mp_ret) {
- SB_LOG(ERROR) << "Failed to unprotect segment";
- return false;
- }
- if (!elf_file->ReadFromOffset(file_page_start,
- reinterpret_cast<char*>(seg_addr),
- file_length)) {
- SB_DLOG(INFO) << "Failed to read segment from file offset: "
- << file_page_start;
- return false;
+ if (!mp_ret) {
+ SB_LOG(ERROR) << "Failed to unprotect segment";
+ return false;
+ }
+ if (!elf_file->ReadFromOffset(file_page_start,
+ reinterpret_cast<char*>(seg_addr),
+ file_length)) {
+ SB_DLOG(INFO) << "Failed to read segment from file offset: "
+ << file_page_start;
+ return false;
+ }
}
mp_ret = SbMemoryProtect(seg_addr, file_length, prot_flags);
SB_DLOG(INFO) << "mp_ret=" << mp_ret;
@@ -314,7 +342,7 @@
SB_DLOG(INFO) << "Reading at vaddr: " << phdr->p_vaddr;
*dynamic = reinterpret_cast<Dyn*>(base_memory_address_ + phdr->p_vaddr);
if (dynamic_count) {
- *dynamic_count = (size_t)(phdr->p_memsz / sizeof(Dyn));
+ *dynamic_count = static_cast<size_t>((phdr->p_memsz / sizeof(Dyn)));
}
if (dynamic_flags) {
*dynamic_flags = phdr->p_flags;
diff --git a/src/starboard/elf_loader/program_table.h b/src/starboard/elf_loader/program_table.h
index 3741002..08f4231 100644
--- a/src/starboard/elf_loader/program_table.h
+++ b/src/starboard/elf_loader/program_table.h
@@ -17,6 +17,7 @@
#include <vector>
+#include "cobalt/extension/memory_mapped_file.h"
#include "starboard/elf_loader/elf.h"
#include "starboard/elf_loader/file.h"
@@ -36,7 +37,8 @@
class ProgramTable {
public:
- ProgramTable();
+ explicit ProgramTable(
+ const CobaltExtensionMemoryMappedFileApi* memory_mapped_file_extension);
// Loads the program header.
bool LoadProgramHeader(const Ehdr* elf_header, File* elf_file);
@@ -90,6 +92,8 @@
// from the ELF file are offsets from this address.
Addr base_memory_address_;
+ const CobaltExtensionMemoryMappedFileApi* memory_mapped_file_extension_;
+
ProgramTable(const ProgramTable&) = delete;
void operator=(const ProgramTable&) = delete;
};
diff --git a/src/starboard/elf_loader/program_table_test.cc b/src/starboard/elf_loader/program_table_test.cc
index 4e56dd7..3a23711 100644
--- a/src/starboard/elf_loader/program_table_test.cc
+++ b/src/starboard/elf_loader/program_table_test.cc
@@ -14,6 +14,7 @@
#include "starboard/elf_loader/program_table.h"
+#include <string>
#include <vector>
#include "starboard/common/scoped_ptr.h"
@@ -41,7 +42,11 @@
explicit DummyFile(const std::vector<FileChunk>& file_chunks)
: file_chunks_(file_chunks), read_index_(0) {}
- bool Open(const char* name) { return true; }
+ bool Open(const char* name) {
+ name_ = name;
+ return true;
+ }
+
bool ReadFromOffset(int64_t offset, char* buffer, int size) {
SB_LOG(INFO) << "ReadFromOffset offset=" << offset << " size=" << size
<< " read_index_=" << read_index_;
@@ -65,17 +70,20 @@
}
void Close() {}
+ const std::string& GetName() { return name_; }
+
private:
int file_offset_;
const char* buffer_;
int size_;
std::vector<FileChunk> file_chunks_;
int read_index_;
+ std::string name_;
};
class ProgramTableTest : public ::testing::Test {
protected:
- ProgramTableTest() { program_table_.reset(new ProgramTable()); }
+ ProgramTableTest() { program_table_.reset(new ProgramTable(nullptr)); }
~ProgramTableTest() {}
void HelperMethod() {}
@@ -136,14 +144,13 @@
char program_table_page[PAGE_SIZE];
memset(program_table_page, 0, sizeof(program_table_page));
- memcpy(program_table_page, program_table_data,
- sizeof(program_table_data));
+ memcpy(program_table_page, program_table_data, sizeof(program_table_data));
char segment_file_data1[2 * PAGE_SIZE];
char segment_file_data2[3 * PAGE_SIZE];
memcpy(segment_file_data1 + 250, dynamic_table_data,
- sizeof(dynamic_table_data));
+ sizeof(dynamic_table_data));
std::vector<DummyFile::FileChunk> file_chunks;
file_chunks.push_back(
diff --git a/src/starboard/evergreen/shared/launcher.py b/src/starboard/evergreen/shared/launcher.py
index 3915278..034d71f 100644
--- a/src/starboard/evergreen/shared/launcher.py
+++ b/src/starboard/evergreen/shared/launcher.py
@@ -236,3 +236,6 @@
def GetDeviceIp(self):
return self.launcher.GetDeviceIp()
+
+ def GetDeviceOutputPath(self):
+ return self.launcher.GetDeviceOutputPath()
diff --git a/src/starboard/linux/shared/BUILD.gn b/src/starboard/linux/shared/BUILD.gn
index b9d5b3a..c720b16 100644
--- a/src/starboard/linux/shared/BUILD.gn
+++ b/src/starboard/linux/shared/BUILD.gn
@@ -184,6 +184,8 @@
"//starboard/shared/posix/memory_allocate_aligned_unchecked.cc",
"//starboard/shared/posix/memory_flush.cc",
"//starboard/shared/posix/memory_free_aligned.cc",
+ "//starboard/shared/posix/memory_mapped_file.cc",
+ "//starboard/shared/posix/memory_mapped_file.h",
"//starboard/shared/posix/set_non_blocking_internal.cc",
"//starboard/shared/posix/socket_accept.cc",
"//starboard/shared/posix/socket_bind.cc",
@@ -385,6 +387,8 @@
sources += common_player_sources
+ sources -= [ "//starboard/shared/starboard/player/player_set_bounds.cc" ]
+
configs += [
"//starboard/build/config:starboard_implementation",
"//third_party/de265_includes",
diff --git a/src/starboard/linux/shared/launcher.py b/src/starboard/linux/shared/launcher.py
index 5cfec50..8888d6d 100644
--- a/src/starboard/linux/shared/launcher.py
+++ b/src/starboard/linux/shared/launcher.py
@@ -197,3 +197,7 @@
def GetDeviceIp(self):
"""Gets the device IP."""
return self.device_ip
+
+ def GetDeviceOutputPath(self):
+ """Writable path where test targets can output files"""
+ return "/tmp"
diff --git a/src/starboard/linux/shared/starboard_platform.gypi b/src/starboard/linux/shared/starboard_platform.gypi
index 5387624..fef07e1 100644
--- a/src/starboard/linux/shared/starboard_platform.gypi
+++ b/src/starboard/linux/shared/starboard_platform.gypi
@@ -155,6 +155,8 @@
'<(DEPTH)/starboard/shared/posix/memory_allocate_aligned_unchecked.cc',
'<(DEPTH)/starboard/shared/posix/memory_flush.cc',
'<(DEPTH)/starboard/shared/posix/memory_free_aligned.cc',
+ '<(DEPTH)/starboard/shared/posix/memory_mapped_file.cc',
+ '<(DEPTH)/starboard/shared/posix/memory_mapped_file.h',
'<(DEPTH)/starboard/shared/posix/set_non_blocking_internal.cc',
'<(DEPTH)/starboard/shared/posix/socket_accept.cc',
'<(DEPTH)/starboard/shared/posix/socket_bind.cc',
diff --git a/src/starboard/linux/shared/system_get_extensions.cc b/src/starboard/linux/shared/system_get_extensions.cc
index 5c7ac86..3411d93 100644
--- a/src/starboard/linux/shared/system_get_extensions.cc
+++ b/src/starboard/linux/shared/system_get_extensions.cc
@@ -16,7 +16,9 @@
#include "cobalt/extension/configuration.h"
#include "cobalt/extension/crash_handler.h"
+#include "cobalt/extension/memory_mapped_file.h"
#include "starboard/common/string.h"
+#include "starboard/shared/posix/memory_mapped_file.h"
#include "starboard/shared/starboard/crash_handler.h"
#if SB_IS(EVERGREEN_COMPATIBLE)
#include "starboard/elf_loader/evergreen_config.h"
@@ -41,5 +43,8 @@
if (strcmp(name, kCobaltExtensionCrashHandlerName) == 0) {
return starboard::common::GetCrashHandlerApi();
}
+ if (strcmp(name, kCobaltExtensionMemoryMappedFileName) == 0) {
+ return starboard::shared::posix::GetMemoryMappedFileApi();
+ }
return NULL;
}
diff --git a/src/starboard/linux/x64x11/BUILD.gn b/src/starboard/linux/x64x11/BUILD.gn
index c443ead..ad6b13a 100644
--- a/src/starboard/linux/x64x11/BUILD.gn
+++ b/src/starboard/linux/x64x11/BUILD.gn
@@ -15,13 +15,7 @@
static_library("starboard_platform") {
check_includes = false
- sources = [
- "//starboard/linux/x64x11/main.cc",
- "//starboard/shared/starboard/player/video_dmp_common.cc",
- "//starboard/shared/starboard/player/video_dmp_common.h",
- "//starboard/shared/starboard/player/video_dmp_writer.cc",
- "//starboard/shared/starboard/player/video_dmp_writer.h",
- ]
+ sources = [ "//starboard/linux/x64x11/main.cc" ]
public_deps = [
"//starboard/linux/x64x11/shared:starboard_platform",
diff --git a/src/starboard/linux/x64x11/egl/BUILD.gn b/src/starboard/linux/x64x11/egl/BUILD.gn
index c443ead..ad6b13a 100644
--- a/src/starboard/linux/x64x11/egl/BUILD.gn
+++ b/src/starboard/linux/x64x11/egl/BUILD.gn
@@ -15,13 +15,7 @@
static_library("starboard_platform") {
check_includes = false
- sources = [
- "//starboard/linux/x64x11/main.cc",
- "//starboard/shared/starboard/player/video_dmp_common.cc",
- "//starboard/shared/starboard/player/video_dmp_common.h",
- "//starboard/shared/starboard/player/video_dmp_writer.cc",
- "//starboard/shared/starboard/player/video_dmp_writer.h",
- ]
+ sources = [ "//starboard/linux/x64x11/main.cc" ]
public_deps = [
"//starboard/linux/x64x11/shared:starboard_platform",
diff --git a/src/starboard/linux/x64x11/skia/BUILD.gn b/src/starboard/linux/x64x11/skia/BUILD.gn
index cf08201..024e560 100644
--- a/src/starboard/linux/x64x11/skia/BUILD.gn
+++ b/src/starboard/linux/x64x11/skia/BUILD.gn
@@ -20,10 +20,6 @@
"//starboard/linux/x64x11/skia/configuration.cc",
"//starboard/linux/x64x11/skia/configuration.h",
"//starboard/linux/x64x11/skia/system_get_extensions.cc",
- "//starboard/shared/starboard/player/video_dmp_common.cc",
- "//starboard/shared/starboard/player/video_dmp_common.h",
- "//starboard/shared/starboard/player/video_dmp_writer.cc",
- "//starboard/shared/starboard/player/video_dmp_writer.h",
]
public_deps = [
diff --git a/src/starboard/loader_app/loader_app.cc b/src/starboard/loader_app/loader_app.cc
index c1834af..2fdce8f 100644
--- a/src/starboard/loader_app/loader_app.cc
+++ b/src/starboard/loader_app/loader_app.cc
@@ -14,6 +14,7 @@
#include <vector>
+#include "cobalt/version.h"
#include "starboard/common/log.h"
#include "starboard/common/string.h"
#include "starboard/configuration.h"
@@ -165,10 +166,25 @@
const starboard::shared::starboard::CommandLine command_line(
data->argument_count, const_cast<const char**>(data->argument_values));
+ if (command_line.HasSwitch(starboard::loader_app::kLoaderAppVersion)) {
+ std::string versiong_msg = "Loader app version: ";
+ versiong_msg += COBALT_VERSION;
+ versiong_msg += "\n";
+ SbLogRaw(versiong_msg.c_str());
+ }
+
bool is_evergreen_lite =
command_line.HasSwitch(starboard::loader_app::kEvergreenLite);
SB_LOG(INFO) << "is_evergreen_lite=" << is_evergreen_lite;
+#if SB_API_VERSION >= 12
+ if (command_line.HasSwitch(starboard::loader_app::kShowSABI)) {
+ std::string sabi = "SABI=";
+ sabi += SB_SABI_JSON_ID;
+ SbLogRaw(sabi.c_str());
+ }
+#endif
+
std::string alternative_content =
command_line.GetSwitchValue(starboard::loader_app::kContent);
SB_LOG(INFO) << "alternative_content=" << alternative_content;
diff --git a/src/starboard/loader_app/loader_app_switches.cc b/src/starboard/loader_app/loader_app_switches.cc
index 36b6f8f..7758dea 100644
--- a/src/starboard/loader_app/loader_app_switches.cc
+++ b/src/starboard/loader_app/loader_app_switches.cc
@@ -20,6 +20,8 @@
const char kContent[] = "content";
const char kURL[] = "url";
const char kEvergreenLite[] = "evergreen_lite";
+const char kLoaderAppVersion[] = "loader_app_version";
+const char kShowSABI[] = "show_sabi";
} // namespace loader_app
} // namespace starboard
diff --git a/src/starboard/loader_app/loader_app_switches.h b/src/starboard/loader_app/loader_app_switches.h
index 45cbf01..22030c5 100644
--- a/src/starboard/loader_app/loader_app_switches.h
+++ b/src/starboard/loader_app/loader_app_switches.h
@@ -32,6 +32,12 @@
// Run Evergreen Lite by loading the system image and disabling the updater.
extern const char kEvergreenLite[];
+// Print the loader_app version on the command line.
+extern const char kLoaderAppVersion[];
+
+// Print the loader_app Starboard ABI string on the command line.
+extern const char kShowSABI[];
+
} // namespace loader_app
} // namespace starboard
diff --git a/src/starboard/nplb/audio_sink_destroy_test.cc b/src/starboard/nplb/audio_sink_destroy_test.cc
index 81adf21..e90a3d1 100644
--- a/src/starboard/nplb/audio_sink_destroy_test.cc
+++ b/src/starboard/nplb/audio_sink_destroy_test.cc
@@ -18,7 +18,7 @@
namespace starboard {
namespace nplb {
-TEST(SbAudioSinkCreateTest, DestroyInvalidAudioSink) {
+TEST(SbAudioSinkDestroyTest, DestroyInvalidAudioSink) {
SbAudioSinkDestroy(kSbAudioSinkInvalid);
}
diff --git a/src/starboard/nplb/media_buffer_test.cc b/src/starboard/nplb/media_buffer_test.cc
index 66640dd..10599ce 100644
--- a/src/starboard/nplb/media_buffer_test.cc
+++ b/src/starboard/nplb/media_buffer_test.cc
@@ -12,7 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <cmath>
+#include <random>
+#include <vector>
+
#include "starboard/media.h"
+#include "starboard/memory.h"
#include "starboard/nplb/performance_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -38,8 +43,7 @@
kSbMediaVideoCodecNone,
kSbMediaVideoCodecH264, kSbMediaVideoCodecH265, kSbMediaVideoCodecMpeg2,
- kSbMediaVideoCodecTheora, kSbMediaVideoCodecVc1,
- kSbMediaVideoCodecAv1,
+ kSbMediaVideoCodecTheora, kSbMediaVideoCodecVc1, kSbMediaVideoCodecAv1,
kSbMediaVideoCodecVp8, kSbMediaVideoCodecVp9,
};
@@ -47,6 +51,37 @@
kSbMediaTypeAudio, kSbMediaTypeVideo,
};
+// Minimum audio and video budgets required by the 2020 Youtube Software
+// Requirements.
+constexpr int kMinAudioBudget = 5 * 1024 * 1024;
+constexpr int kMinVideoBudget = 30 * 1024 * 1024;
+
+std::vector<void*> TryToAllocateMemory(int size,
+ int allocation_unit,
+ int alignment) {
+ int total_allocated = 0;
+ std::vector<void*> allocated_ptrs;
+ if (allocation_unit != 0) {
+ allocated_ptrs.reserve(std::ceil(size / allocation_unit));
+ }
+ while (total_allocated < size) {
+ // When |allocation_unit| == 0, randomly allocate a size between 100k -
+ // 500k.
+ int allocation_increment = allocation_unit != 0
+ ? allocation_unit
+ : (std::rand() % 500 + 100) * 1024;
+ void* allocated_memory =
+ SbMemoryAllocateAligned(alignment, allocation_increment);
+ EXPECT_NE(allocated_memory, nullptr);
+ if (!allocated_memory) {
+ return allocated_ptrs;
+ }
+ allocated_ptrs.push_back(allocated_memory);
+ total_allocated += allocation_increment;
+ }
+ return allocated_ptrs;
+}
+
} // namespace
TEST(SbMediaBufferTest, VideoCodecs) {
@@ -83,28 +118,60 @@
TEST(SbMediaBufferTest, Alignment) {
for (auto type : kMediaTypes) {
int alignment = SbMediaGetBufferAlignment(type);
- // TODO: This currently accepts 0 or a power of 2. We should disallow 0 here
- // when we change the default value to be 1 instead of 0.
- EXPECT_GE(alignment, 0);
+ EXPECT_GE(alignment, 1);
EXPECT_EQ(alignment & (alignment - 1), 0)
<< "Alignment must always be a power of 2";
}
}
TEST(SbMediaBufferTest, AllocationUnit) {
- // TODO: impose more bounds.
EXPECT_GE(SbMediaGetBufferAllocationUnit(), 0);
+
+ if (SbMediaGetBufferAllocationUnit() != 0) {
+ EXPECT_GE(SbMediaGetBufferAllocationUnit(), 64 * 1024);
+ }
+
+ int allocation_unit = SbMediaGetBufferAllocationUnit();
+ std::vector<void*> allocated_ptrs;
+ int initial_buffer_capacity = SbMediaGetInitialBufferCapacity();
+ if (initial_buffer_capacity > 0) {
+ allocated_ptrs =
+ TryToAllocateMemory(initial_buffer_capacity, allocation_unit, 1);
+ }
+
+ if (!HasNonfatalFailure()) {
+ for (SbMediaType type : kMediaTypes) {
+ int alignment = SbMediaGetBufferAlignment(type);
+ EXPECT_EQ(alignment & (alignment - 1), 0)
+ << "Alignment must always be a power of 2";
+ if (HasNonfatalFailure()) {
+ break;
+ }
+ int media_budget = type == SbMediaType::kSbMediaTypeAudio
+ ? kMinAudioBudget
+ : kMinVideoBudget;
+ std::vector<void*> media_buffer_allocated_memory =
+ TryToAllocateMemory(media_budget, allocation_unit, alignment);
+ allocated_ptrs.insert(allocated_ptrs.end(),
+ media_buffer_allocated_memory.begin(),
+ media_buffer_allocated_memory.end());
+ if (HasNonfatalFailure()) {
+ break;
+ }
+ }
+ }
+
+ for (void* ptr : allocated_ptrs) {
+ SbMemoryFreeAligned(ptr);
+ }
}
TEST(SbMediaBufferTest, AudioBudget) {
- // TODO: refine this lower bound.
- const int kMinAudioBudget = 1 * 1024 * 1024;
- EXPECT_GT(SbMediaGetAudioBufferBudget(), kMinAudioBudget);
+ EXPECT_GE(SbMediaGetAudioBufferBudget(), kMinAudioBudget);
}
TEST(SbMediaBufferTest, GarbageCollectionDurationThreshold) {
- // TODO: impose reasonable bounds here.
- int kMinGarbageCollectionDurationThreshold = 10 * kSbTimeSecond;
+ int kMinGarbageCollectionDurationThreshold = 30 * kSbTimeSecond;
int kMaxGarbageCollectionDurationThreshold = 240 * kSbTimeSecond;
int threshold = SbMediaGetBufferGarbageCollectionDurationThreshold();
EXPECT_GE(threshold, kMinGarbageCollectionDurationThreshold);
@@ -116,7 +183,9 @@
}
TEST(SbMediaBufferTest, MaxCapacity) {
- // TODO: set a reasonable upper bound.
+ // TODO: Limit EXPECT statements to only codecs and resolutions that are
+ // supported by the platform. If unsupported, still call
+ // SbMediaGetMaxBufferCapacity() to ensure there isn't a crash.
for (auto resolution : kVideoResolutions) {
for (auto bits_per_pixel : kBitsPerPixelValues) {
for (auto codec : kVideoCodecs) {
@@ -178,12 +247,10 @@
}
TEST(SbMediaBufferTest, VideoBudget) {
- // TODO: refine this lower bound.
- const int kMinVideoBudget = 1 * 1024 * 1024;
for (auto codec : kVideoCodecs) {
for (auto resolution : kVideoResolutions) {
for (auto bits_per_pixel : kBitsPerPixelValues) {
- EXPECT_GT(SbMediaGetVideoBufferBudget(codec, resolution[0],
+ EXPECT_GE(SbMediaGetVideoBufferBudget(codec, resolution[0],
resolution[1], bits_per_pixel),
kMinVideoBudget);
}
diff --git a/src/starboard/raspi/shared/BUILD.gn b/src/starboard/raspi/shared/BUILD.gn
index 3828973..2cc3d1c 100644
--- a/src/starboard/raspi/shared/BUILD.gn
+++ b/src/starboard/raspi/shared/BUILD.gn
@@ -375,6 +375,17 @@
sources += common_player_sources
+ if (sb_api_version == 12) {
+ sources += [
+ "//starboard/shared/stub/speech_recognizer_cancel.cc",
+ "//starboard/shared/stub/speech_recognizer_create.cc",
+ "//starboard/shared/stub/speech_recognizer_destroy.cc",
+ "//starboard/shared/stub/speech_recognizer_is_supported.cc",
+ "//starboard/shared/stub/speech_recognizer_start.cc",
+ "//starboard/shared/stub/speech_recognizer_stop.cc",
+ ]
+ }
+
configs += [
"//starboard/build/config:pedantic_warnings",
"//starboard/build/config:starboard_implementation",
diff --git a/src/starboard/raspi/shared/launcher.py b/src/starboard/raspi/shared/launcher.py
index 14e11e1..4617abc 100644
--- a/src/starboard/raspi/shared/launcher.py
+++ b/src/starboard/raspi/shared/launcher.py
@@ -365,3 +365,7 @@
def GetDeviceIp(self):
"""Gets the device IP."""
return self.device_id
+
+ def GetDeviceOutputPath(self):
+ """Writable path where test targets can output files"""
+ return '/tmp'
diff --git a/src/starboard/shared/dlmalloc/page_internal.h b/src/starboard/shared/dlmalloc/page_internal.h
index b4df31f..e72fd75 100644
--- a/src/starboard/shared/dlmalloc/page_internal.h
+++ b/src/starboard/shared/dlmalloc/page_internal.h
@@ -19,6 +19,7 @@
#ifndef STARBOARD_SHARED_DLMALLOC_PAGE_INTERNAL_H_
#define STARBOARD_SHARED_DLMALLOC_PAGE_INTERNAL_H_
+#include "starboard/memory.h"
#include "starboard/shared/internal_only.h"
#include "starboard/types.h"
@@ -115,6 +116,17 @@
// allocated by dlmalloc isn't counted twice.
void* SbPageMapUntracked(size_t size_bytes, int flags, const char* name);
+// Memory maps a file to the specified |addr| starting with |file_offset| and
+// mapping |size| bytes. The |addr| should be reserved before calling. If
+// NULL |addr| is passed a new memory block would be allocated and the address
+// returned. The file_offset must be a multiple of |kSbMemoryPageSize|.
+// On error returns NULL.
+void* SbPageMapFile(void* addr,
+ const char* path,
+ SbMemoryMapFlags flags,
+ int64_t file_offset,
+ int64_t size);
+
// Unmap |size_bytes| of physical pages starting from |virtual_address|,
// returning true on success. After this, [virtual_address, virtual_address +
// size_bytes) will not be read/writable. SbUnmap() can unmap multiple
diff --git a/src/starboard/shared/libdav1d/dav1d_video_decoder.cc b/src/starboard/shared/libdav1d/dav1d_video_decoder.cc
index ad5ffc5..80ce0d5 100644
--- a/src/starboard/shared/libdav1d/dav1d_video_decoder.cc
+++ b/src/starboard/shared/libdav1d/dav1d_video_decoder.cc
@@ -227,7 +227,7 @@
Dav1dSettings dav1d_settings{0};
dav1d_default_settings(&dav1d_settings);
// TODO: Verify this setting is optimal.
- dav1d_settings.n_frame_threads = 8;
+ dav1d_settings.n_threads = 8;
Dav1dPicAllocator allocator;
allocator.cookie = this; // dav1d refers to context pointers as "cookie".
diff --git a/src/starboard/shared/linux/page_internal.cc b/src/starboard/shared/linux/page_internal.cc
index de2ff6f..e708839 100644
--- a/src/starboard/shared/linux/page_internal.cc
+++ b/src/starboard/shared/linux/page_internal.cc
@@ -17,8 +17,10 @@
#include "starboard/shared/dlmalloc/page_internal.h"
+#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>
+#include <unistd.h>
#include "starboard/atomic.h"
#include "starboard/common/log.h"
@@ -86,6 +88,38 @@
return mem;
}
+void* SbPageMapFile(void* addr,
+ const char* path,
+ SbMemoryMapFlags flags,
+ int64_t file_offset,
+ int64_t size) {
+ int fd = open(path, O_RDONLY);
+ if (fd == -1) {
+ return nullptr;
+ }
+
+ void* p = nullptr;
+ if (addr != nullptr) {
+ p = mmap(addr, size, SbMemoryMapFlagsToMmapProtect(flags),
+ MAP_PRIVATE | MAP_FIXED, fd, file_offset);
+ if (p == MAP_FAILED) {
+ close(fd);
+ return nullptr;
+ }
+ } else {
+ p = mmap(addr, size, SbMemoryMapFlagsToMmapProtect(flags), MAP_PRIVATE, fd,
+ file_offset);
+ if (p == MAP_FAILED) {
+ close(fd);
+ return nullptr;
+ }
+ }
+ // It is OK to close the file descriptor as the memory
+ // mapping keeps the file open.
+ close(fd);
+ return p;
+}
+
bool SbPageUnmap(void* ptr, size_t size_bytes) {
SbAtomicNoBarrier_Increment(&s_tracked_page_count, -GetPageCount(size_bytes));
return SbPageUnmapUntracked(ptr, size_bytes);
diff --git a/src/starboard/shared/posix/memory_mapped_file.cc b/src/starboard/shared/posix/memory_mapped_file.cc
new file mode 100644
index 0000000..d9a3dfb
--- /dev/null
+++ b/src/starboard/shared/posix/memory_mapped_file.cc
@@ -0,0 +1,39 @@
+// Copyright 2021 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/posix/memory_mapped_file.h"
+
+#include "cobalt/extension/memory_mapped_file.h"
+#include "starboard/common/log.h"
+#include "starboard/shared/dlmalloc/page_internal.h"
+
+namespace starboard {
+namespace shared {
+namespace posix {
+
+namespace {
+
+const CobaltExtensionMemoryMappedFileApi kMemoryMappedFileApi = {
+ kCobaltExtensionMemoryMappedFileName, 1, &SbPageMapFile,
+};
+
+} // namespace
+
+const void* GetMemoryMappedFileApi() {
+ return &kMemoryMappedFileApi;
+}
+
+} // namespace posix
+} // namespace shared
+} // namespace starboard
diff --git a/src/starboard/shared/posix/memory_mapped_file.h b/src/starboard/shared/posix/memory_mapped_file.h
new file mode 100644
index 0000000..46e47fe
--- /dev/null
+++ b/src/starboard/shared/posix/memory_mapped_file.h
@@ -0,0 +1,28 @@
+// Copyright 2021 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_POSIX_MEMORY_MAPPED_FILE_H_
+#define STARBOARD_SHARED_POSIX_MEMORY_MAPPED_FILE_H_
+
+namespace starboard {
+namespace shared {
+namespace posix {
+
+const void* GetMemoryMappedFileApi();
+
+} // namespace posix
+} // namespace shared
+} // namespace starboard
+
+#endif // STARBOARD_SHARED_POSIX_MEMORY_MAPPED_FILE_H_
diff --git a/src/starboard/shared/starboard/media/avc_util.cc b/src/starboard/shared/starboard/media/avc_util.cc
index aaa677e..81e196b 100644
--- a/src/starboard/shared/starboard/media/avc_util.cc
+++ b/src/starboard/shared/starboard/media/avc_util.cc
@@ -38,8 +38,7 @@
if (annex_b_data_size < sizeof(kAnnexBHeader)) {
return false;
}
- return memcmp(annex_b_data, kAnnexBHeader, sizeof(kAnnexBHeader)) ==
- 0;
+ return memcmp(annex_b_data, kAnnexBHeader, sizeof(kAnnexBHeader)) == 0;
}
// UInt8Type can be "uint8_t", or "const uint8_t".
@@ -125,6 +124,26 @@
<< "AVC parameter set NALUs not found.";
}
+std::vector<uint8_t> AvcParameterSets::GetAllSpses() const {
+ std::vector<uint8_t> result;
+ for (const auto& parameter_set : parameter_sets_) {
+ if (parameter_set[4] == kSpsStartCode) {
+ result.insert(result.end(), parameter_set.begin(), parameter_set.end());
+ }
+ }
+ return result;
+}
+
+std::vector<uint8_t> AvcParameterSets::GetAllPpses() const {
+ std::vector<uint8_t> result;
+ for (const auto& parameter_set : parameter_sets_) {
+ if (parameter_set[4] == kPpsStartCode) {
+ result.insert(result.end(), parameter_set.begin(), parameter_set.end());
+ }
+ }
+ return result;
+}
+
AvcParameterSets AvcParameterSets::ConvertTo(Format new_format) const {
if (format_ == new_format) {
return *this;
@@ -204,7 +223,7 @@
avcc_destination[2] = static_cast<uint8_t>((payload_size & 0xff00) >> 8);
avcc_destination[3] = static_cast<uint8_t>(payload_size & 0xff);
memcpy(avcc_destination + kAvccLengthInBytes,
- last_source + kAnnexBHeaderSizeInBytes, payload_size);
+ last_source + kAnnexBHeaderSizeInBytes, payload_size);
avcc_destination += annex_b_source - last_source;
last_source = annex_b_source;
}
diff --git a/src/starboard/shared/starboard/media/avc_util.h b/src/starboard/shared/starboard/media/avc_util.h
index c9d7931..7def624 100644
--- a/src/starboard/shared/starboard/media/avc_util.h
+++ b/src/starboard/shared/starboard/media/avc_util.h
@@ -83,6 +83,9 @@
}
size_t combined_size_in_bytes() const { return combined_size_in_bytes_; }
+ std::vector<uint8_t> GetAllSpses() const;
+ std::vector<uint8_t> GetAllPpses() const;
+
AvcParameterSets ConvertTo(Format new_format) const;
bool operator==(const AvcParameterSets& that) const;
diff --git a/src/starboard/shared/starboard/media/media_util.cc b/src/starboard/shared/starboard/media/media_util.cc
index ab3db04..786e284 100644
--- a/src/starboard/shared/starboard/media/media_util.cc
+++ b/src/starboard/shared/starboard/media/media_util.cc
@@ -221,7 +221,7 @@
if (audio_specific_config_size > 0) {
audio_specific_config_storage.resize(audio_specific_config_size);
memcpy(audio_specific_config_storage.data(), audio_specific_config,
- audio_specific_config_size);
+ audio_specific_config_size);
audio_specific_config = audio_specific_config_storage.data();
}
#if SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
@@ -310,6 +310,51 @@
return true;
}
+bool IsSDRVideo(const char* mime) {
+ SB_DCHECK(mime);
+
+ if (!mime) {
+ SB_LOG(WARNING) << mime << " is empty, assuming sdr video.";
+ return true;
+ }
+
+ MimeType mime_type(mime);
+ if (!mime_type.is_valid()) {
+ SB_LOG(WARNING) << mime << " is not a valid mime type, assuming sdr video.";
+ return true;
+ }
+ const std::vector<std::string> codecs = mime_type.GetCodecs();
+ if (codecs.empty()) {
+ SB_LOG(WARNING) << mime << " contains no codecs, assuming sdr video.";
+ return true;
+ }
+ if (codecs.size() > 1) {
+ SB_LOG(WARNING) << mime
+ << " contains more than one codecs, assuming sdr video.";
+ return true;
+ }
+
+ SbMediaVideoCodec video_codec;
+ int profile = -1;
+ int level = -1;
+ int bit_depth = 8;
+ SbMediaPrimaryId primary_id = kSbMediaPrimaryIdUnspecified;
+ SbMediaTransferId transfer_id = kSbMediaTransferIdUnspecified;
+ SbMediaMatrixId matrix_id = kSbMediaMatrixIdUnspecified;
+
+ if (!ParseVideoCodec(codecs[0].c_str(), &video_codec, &profile, &level,
+ &bit_depth, &primary_id, &transfer_id, &matrix_id)) {
+ SB_LOG(WARNING) << "ParseVideoCodec() failed on mime: " << mime
+ << ", assuming sdr video.";
+ return true;
+ }
+
+ SB_DCHECK(video_codec != kSbMediaVideoCodecNone);
+ // TODO: Consider to consolidate the two IsSDRVideo() implementations by
+ // calling IsSDRVideo(bit_depth, primary_id, transfer_id, matrix_id).
+ return bit_depth == 8;
+}
+
SbMediaTransferId GetTransferIdFromString(const std::string& transfer_id) {
if (transfer_id == "bt709") {
return kSbMediaTransferIdBt709;
@@ -459,8 +504,7 @@
left.samples_per_second != right.samples_per_second ||
left.number_of_channels != right.number_of_channels ||
left.audio_specific_config_size != right.audio_specific_config_size ||
- memcmp(left.audio_specific_config,
- right.audio_specific_config,
+ memcmp(left.audio_specific_config, right.audio_specific_config,
left.audio_specific_config_size) != 0;
}
@@ -471,8 +515,7 @@
bool operator==(const SbMediaColorMetadata& metadata_1,
const SbMediaColorMetadata& metadata_2) {
- return memcmp(&metadata_1, &metadata_2,
- sizeof(SbMediaColorMetadata)) == 0;
+ return memcmp(&metadata_1, &metadata_2, sizeof(SbMediaColorMetadata)) == 0;
}
bool operator==(const SbMediaVideoSampleInfo& sample_info_1,
@@ -489,7 +532,7 @@
return false;
}
if (strcmp(sample_info_1.max_video_capabilities,
- sample_info_2.max_video_capabilities) != 0) {
+ sample_info_2.max_video_capabilities) != 0) {
return false;
}
#endif // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
diff --git a/src/starboard/shared/starboard/media/media_util.h b/src/starboard/shared/starboard/media/media_util.h
index 3f43cd5..a0ee728 100644
--- a/src/starboard/shared/starboard/media/media_util.h
+++ b/src/starboard/shared/starboard/media/media_util.h
@@ -58,6 +58,7 @@
SbMediaPrimaryId primary_id,
SbMediaTransferId transfer_id,
SbMediaMatrixId matrix_id);
+bool IsSDRVideo(const char* mime);
// Turns |eotf| into value of SbMediaTransferId. If |eotf| isn't recognized the
// function returns kSbMediaTransferIdReserved0.
diff --git a/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc b/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc
index 64f94ab..6a4b15e 100644
--- a/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc
+++ b/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc
@@ -161,7 +161,7 @@
player_components_ =
factory->CreateComponents(creation_parameters, error_message);
if (!player_components_) {
- SB_LOG(ERROR) << "Failed to create renderer with error: "
+ SB_LOG(ERROR) << "Failed to create player components with error: "
<< *error_message;
return false;
}
@@ -399,8 +399,7 @@
// only log when the other members of |bounds| have been changed to avoid
// spamming the log.
bounds_.z_index = bounds.z_index;
- bool bounds_changed =
- memcmp(&bounds_, &bounds, sizeof(bounds_)) != 0;
+ bool bounds_changed = memcmp(&bounds_, &bounds, sizeof(bounds_)) != 0;
SB_LOG_IF(INFO, bounds_changed)
<< "Set bounds to "
<< "x: " << bounds.x << ", y: " << bounds.y
diff --git a/src/starboard/tools/abstract_launcher.py b/src/starboard/tools/abstract_launcher.py
index 8a72a2e..85963cb 100644
--- a/src/starboard/tools/abstract_launcher.py
+++ b/src/starboard/tools/abstract_launcher.py
@@ -159,6 +159,11 @@
"""Gets the device IP. Must be implemented in subclasses."""
pass
+ @abc.abstractmethod
+ def GetDeviceOutputPath(self):
+ """Writable path where test targets can output files"""
+ pass
+
def SupportsSuspendResume(self):
return False
diff --git a/src/starboard/tools/app_launcher_packager.py b/src/starboard/tools/app_launcher_packager.py
index 53ff7d1..37a1e80 100644
--- a/src/starboard/tools/app_launcher_packager.py
+++ b/src/starboard/tools/app_launcher_packager.py
@@ -31,19 +31,18 @@
import _env # pylint: disable=unused-import
from paths import REPOSITORY_ROOT
from paths import THIRD_PARTY_ROOT
+
sys.path.append(THIRD_PARTY_ROOT)
-# pylint: disable=g-import-not-at-top,g-bad-import-order
+# pylint: disable=g-import-not-at-top,g-bad-import-order,wrong-import-position
from starboard.tools import command_line
from starboard.tools import log_level
from starboard.tools import port_symlink
import starboard.tools.platform
# Default python directories to app launcher resources.
-_INCLUDE_FILE_PATTERNS = [
- ('cobalt', '*.py'),
- ('starboard', '*.py'),
- ('starboard/tools', 'platform.py.template')
-]
+_INCLUDE_FILE_PATTERNS = [('cobalt', '*.py'), ('starboard', '*.py'),
+ ('starboard', '*.pfx'),
+ ('starboard/tools', 'platform.py.template')]
_INCLUDE_BLACK_BOX_TESTS_PATTERNS = [
# Black box and web platform tests have non-py assets, so everything
@@ -128,11 +127,11 @@
# Store posix paths even on Windows so MH Linux hosts can use them.
# The template has code to re-normalize them when used on Windows hosts.
platforms_map[p] = platform_path.replace('\\', '/')
- template = string.Template(
- open(os.path.join(current_dir, 'platform.py.template')).read())
- with open(os.path.join(dest_dir, 'platform.py'), 'w+') as f:
- sub = template.substitute(platforms_map=platforms_map)
- f.write(sub.encode('utf-8'))
+ with open(os.path.join(current_dir, 'platform.py.template')) as c:
+ template = string.Template(c.read())
+ with open(os.path.join(dest_dir, 'platform.py'), 'w+') as f:
+ sub = template.substitute(platforms_map=platforms_map)
+ f.write(sub.encode('utf-8'))
logging.info('Finished baking in platform info files.')
diff --git a/src/starboard/tools/net_args.py b/src/starboard/tools/net_args.py
index b77d658..1948633 100644
--- a/src/starboard/tools/net_args.py
+++ b/src/starboard/tools/net_args.py
@@ -12,37 +12,34 @@
# 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.
-
"""Example script for getting the Net Args."""
from __future__ import print_function
-import pprint
-
import argparse
import socket
import sys
-import thread
import time
import threading
+
# Returns |True| if a connection was made and the NetArg payload was delivered.
# Example:
# TryConnectAndSendNetArgs('1.2.3.4', '1234', ['--argument', '--switch=value'])
def TryConnectAndSendNetArgs(host, port, arg_list):
arg_string = '\n'.join(arg_list)
-
try:
- server_socket = socket.create_connection((host, port), timeout = .5)
- result = server_socket.sendall(arg_string)
+ server_socket = socket.create_connection((host, port), timeout=.5)
+ server_socket.sendall(arg_string)
server_socket.close()
return True
- except socket.timeout as err:
+ except socket.timeout:
return False
- except socket.error as (err_no, err_str):
- print(err_no, err_str)
+ except socket.error as e:
+ print(e.errno, e.strerror)
return False
+
class NetArgsThread(threading.Thread):
"""Threaded version of NetArgs"""
@@ -71,32 +68,36 @@
with self.mutex:
if self.join_called:
break
- connected_and_sent = TryConnectAndSendNetArgs(
- self.host, self.port, self.arg_list)
+ connected_and_sent = TryConnectAndSendNetArgs(self.host, self.port,
+ self.arg_list)
if connected_and_sent:
with self.mutex:
self.args_sent = True
break
+
def main(argv):
- parser = argparse.ArgumentParser(description = 'Connects to the weblog.')
- parser.add_argument('--host', type=str, required = False,
- default = 'localhost',
- help = "Example localhost or 1.2.3.4")
- parser.add_argument('--port', type=int, required = False, default = '49355')
- parser.add_argument('--arg', type=str, required = True)
+ parser = argparse.ArgumentParser(description='Connects to the weblog.')
+ parser.add_argument(
+ '--host',
+ type=str,
+ required=False,
+ default='localhost',
+ help='Example localhost or 1.2.3.4')
+ parser.add_argument('--port', type=int, required=False, default='49355')
+ parser.add_argument('--arg', type=str, required=True)
args = parser.parse_args(argv)
- net_args_thread = NetArgsThread(
- args.host, args.port, [args.arg])
+ net_args_thread = NetArgsThread(args.host, args.port, [args.arg])
while not net_args_thread.ArgsSent():
- print("Waiting to send arg " + args.arg + " to " + str(args.host) +
- ":" + str(args.port) + "...")
+ print('Waiting to send arg ' + args.arg + ' to ' + str(args.host) + ':' +
+ str(args.port) + '...')
time.sleep(.5)
- print("Argument", args.arg, "was sent to", \
- args.host + ":" + str(args.port))
+ print('Argument', args.arg, 'was sent to', \
+ args.host + ':' + str(args.port))
+
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
diff --git a/src/starboard/tools/net_log.py b/src/starboard/tools/net_log.py
index 0b85cfa..aaa9797 100644
--- a/src/starboard/tools/net_log.py
+++ b/src/starboard/tools/net_log.py
@@ -13,24 +13,24 @@
# 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.
-
"""Example script for getting the Net log."""
from __future__ import print_function
import argparse
-import pprint
import select
import socket
import sys
import time
import threading
+
class NetLog:
"""
Uses a non-blocking socket to establish a connection with a
NetLog and then will allow the log to be fetched.
"""
+
def __init__(self, host, port):
self.host = host
self.port = port
@@ -47,9 +47,9 @@
self.server_socket = None
else:
return log
- except socket.error as (err_no, err_str):
- print(__file__ + ": Socket error while reading log:" \
- + str(err_no) + " - " + str(err_str))
+ except socket.error as e:
+ print(__file__ + ': Socket error while reading log:' \
+ + str(e.errno) + ' - ' + str(e.strerror))
self.server_socket = None
return None
@@ -64,28 +64,31 @@
if len(result) == 0:
return None
return result
- except socket.error as (err_no, err_str):
- if err_no == 10035: # Data not ready yet.
+ except socket.error as e:
+ if e.errno == 10035: # Data not ready yet.
return ''
else:
raise
def _TryCreateSocketConnection(self):
try:
- print("Waiting for connection to " + str(self.host) + ':' + str(self.port))
+ print('Waiting for connection to ' + str(self.host) + ':' +
+ str(self.port))
- server_socket = socket.create_connection((self.host, self.port), timeout = 1)
+ server_socket = socket.create_connection((self.host, self.port),
+ timeout=1)
server_socket.setblocking(0)
return server_socket
- except socket.timeout as err:
+ except socket.timeout:
return None
except socket.error as err:
- print("Error while trying to create socket: " + str(err))
+ print('Error while trying to create socket: ' + str(err))
return None
class NetLogThread(threading.Thread):
"""Threaded version of NetLog"""
+
def __init__(self, host, port):
super(NetLogThread, self).__init__()
self.web_log = NetLog(host, port)
@@ -111,8 +114,9 @@
with self.log_mutex:
self.log.extend(new_log)
+
def TestNetLog(host, port):
- print("Started...")
+ print('Started...')
web_log = NetLog(host, port)
while True:
@@ -123,11 +127,14 @@
def main(argv):
- parser = argparse.ArgumentParser(description = 'Connects to the weblog.')
- parser.add_argument('--host', type=str, required = False,
- default = 'localhost',
- help = "Example localhost or 1.2.3.4")
- parser.add_argument('--port', type=int, required = False, default = '49353')
+ parser = argparse.ArgumentParser(description='Connects to the weblog.')
+ parser.add_argument(
+ '--host',
+ type=str,
+ required=False,
+ default='localhost',
+ help='Example localhost or 1.2.3.4')
+ parser.add_argument('--port', type=int, required=False, default='49353')
args = parser.parse_args(argv)
thread = NetLogThread(args.host, args.port)
@@ -136,13 +143,14 @@
while True:
print(thread.GetLog(), end='')
time.sleep(.1)
- except KeyboardInterrupt as ki:
- print("\nUser canceled.")
+ except KeyboardInterrupt:
+ print('\nUser canceled.')
pass
- print("Waiting to join...")
+ print('Waiting to join...')
thread.join()
return 0
+
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
diff --git a/src/starboard/tools/testing/test_runner.py b/src/starboard/tools/testing/test_runner.py
index 1ae0133..7a08bd2 100755
--- a/src/starboard/tools/testing/test_runner.py
+++ b/src/starboard/tools/testing/test_runner.py
@@ -190,14 +190,12 @@
self.launcher.target_name))
traceback.print_exc(file=sys.stderr)
- self.return_code_lock.acquire()
- self.return_code = return_code
- self.return_code_lock.release()
+ with self.return_code_lock:
+ self.return_code = return_code
def GetReturnCode(self):
- self.return_code_lock.acquire()
- return_code = self.return_code
- self.return_code_lock.release()
+ with self.return_code_lock:
+ return_code = self.return_code
return return_code
@@ -233,7 +231,8 @@
self.out_directory = paths.BuildOutputDirectory(self.platform,
self.config)
self.coverage_directory = os.path.join(self.out_directory, "coverage")
- if not self.loader_out_directory and self.loader_platform and self.loader_config:
+ if (not self.loader_out_directory and self.loader_platform and
+ self.loader_config):
self.loader_out_directory = paths.BuildOutputDirectory(
self.loader_platform, self.loader_config)
@@ -272,13 +271,13 @@
logging.info(msg)
if output_file:
with open(output_file, "wb") as out:
- p = subprocess.Popen(
+ p = subprocess.Popen( # pylint: disable=consider-using-with
cmd_list,
stdout=out,
universal_newlines=True,
cwd=self.out_directory)
else:
- p = subprocess.Popen(
+ p = subprocess.Popen( # pylint: disable=consider-using-with
cmd_list,
stderr=subprocess.STDOUT,
universal_newlines=True,
@@ -401,10 +400,32 @@
if gtest_filter_value:
test_params.append("--gtest_filter=" + gtest_filter_value)
+ def MakeLauncher():
+ return abstract_launcher.LauncherFactory(
+ self.platform,
+ target_name,
+ self.config,
+ device_id=self.device_id,
+ target_params=test_params,
+ output_file=write_pipe,
+ out_directory=self.out_directory,
+ coverage_directory=self.coverage_directory,
+ env_variables=env,
+ loader_platform=self.loader_platform,
+ loader_config=self.loader_config,
+ loader_out_directory=self.loader_out_directory,
+ launcher_args=self.launcher_args)
+
if self.log_xml_results:
- # Log the xml results
- test_params.append("--gtest_output=xml:log")
- logging.info("Xml results for this test will be logged.")
+ out_path = MakeLauncher().GetDeviceOutputPath()
+ xml_filename = "{}_testoutput.xml".format(target_name)
+ if out_path:
+ xml_path = os.path.join(out_path, xml_filename)
+ else:
+ xml_path = xml_filename
+ test_params.append("--gtest_output=xml:{}".format(xml_path))
+ logging.info(("Xml results for this test will "
+ "be logged to '%s'."), xml_path)
elif self.xml_output_dir:
# Have gtest create and save a test result xml
xml_output_subdir = os.path.join(self.xml_output_dir, target_name)
@@ -424,20 +445,9 @@
if self.dry_run:
test_params.extend(["--gtest_list_tests"])
- launcher = abstract_launcher.LauncherFactory(
- self.platform,
- target_name,
- self.config,
- device_id=self.device_id,
- target_params=test_params,
- output_file=write_pipe,
- out_directory=self.out_directory,
- coverage_directory=self.coverage_directory,
- env_variables=env,
- loader_platform=self.loader_platform,
- loader_config=self.loader_config,
- loader_out_directory=self.loader_out_directory,
- launcher_args=self.launcher_args)
+ logging.info("Initializing launcher")
+ launcher = MakeLauncher()
+ logging.info("Launcher initialized")
test_reader = TestLineReader(read_pipe)
test_launcher = TestLauncher(launcher)
diff --git a/src/testing/gtest/src/gtest.cc b/src/testing/gtest/src/gtest.cc
index 50717b7..e561a3c 100644
--- a/src/testing/gtest/src/gtest.cc
+++ b/src/testing/gtest/src/gtest.cc
@@ -3450,6 +3450,19 @@
GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter);
};
+#if GTEST_OS_STARBOARD
+void WriteOuputFile(const std::string &output_file, const std::string &data) {
+ SbFileError err;
+ starboard::ScopedFile cache_file(
+ output_file.c_str(), kSbFileCreateAlways | kSbFileWrite, NULL, &err);
+ // TODO: Change to SB_DCHECK once all platforms are verified
+ if(err != kSbFileOk) {
+ SB_LOG(ERROR) << "Unable to open file " << output_file << " for XML output";
+ }
+ cache_file.WriteAll(data.c_str(), static_cast<int>(data.size()));
+}
+#endif
+
// Creates a new XmlUnitTestResultPrinter.
XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
: output_file_(output_file) {
@@ -3458,6 +3471,10 @@
fflush(stderr);
exit(EXIT_FAILURE);
}
+#if GTEST_OS_STARBOARD
+ // Ensure file contents get reset between runs, to avoid stale results
+ WriteOuputFile(output_file,"");
+#endif
}
// Called after the unit test ends.
@@ -3466,10 +3483,8 @@
#if GTEST_OS_STARBOARD
std::stringstream stream;
PrintXmlUnitTest(&stream, unit_test);
- starboard::ScopedFile cache_file(
- output_file_.c_str(), kSbFileCreateAlways | kSbFileWrite, NULL, NULL);
- cache_file.WriteAll(StringStreamToString(&stream).c_str(),
- static_cast<int>(StringStreamToString(&stream).size()));
+
+ WriteOuputFile(output_file_, StringStreamToString(&stream));
#else
FILE* xmlout = NULL;
FilePath output_file(output_file_);
diff --git a/src/third_party/libdav1d/include/dav1d/common.h b/src/third_party/libdav1d/include/dav1d/common.h
index b55e939..d81775d 100644
--- a/src/third_party/libdav1d/include/dav1d/common.h
+++ b/src/third_party/libdav1d/include/dav1d/common.h
@@ -1,81 +1,81 @@
-/*
- * Copyright © 2018, VideoLAN and dav1d authors
- * Copyright © 2018, Two Orioles, LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DAV1D_COMMON_H
-#define DAV1D_COMMON_H
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#ifndef DAV1D_API
- #if defined _WIN32
- #if defined DAV1D_BUILDING_DLL
- #define DAV1D_API __declspec(dllexport)
- #else
- #define DAV1D_API
- #endif
- #else
- #if __GNUC__ >= 4
- #define DAV1D_API __attribute__ ((visibility ("default")))
- #else
- #define DAV1D_API
- #endif
- #endif
-#endif
-
-#if EPERM > 0
-#define DAV1D_ERR(e) (-(e)) ///< Negate POSIX error code.
-#else
-#define DAV1D_ERR(e) (e)
-#endif
-
-/**
- * A reference-counted object wrapper for a user-configurable pointer.
- */
-typedef struct Dav1dUserData {
- const uint8_t *data; ///< data pointer
- struct Dav1dRef *ref; ///< allocation origin
-} Dav1dUserData;
-
-/**
- * Input packet metadata which are copied from the input data used to
- * decode each image into the matching structure of the output image
- * returned back to the user. Since these are metadata fields, they
- * can be used for other purposes than the documented ones, they will
- * still be passed from input data to output picture without being
- * used internally.
- */
-typedef struct Dav1dDataProps {
- int64_t timestamp; ///< container timestamp of input data, INT64_MIN if unknown (default)
- int64_t duration; ///< container duration of input data, 0 if unknown (default)
- int64_t offset; ///< stream offset of input data, -1 if unknown (default)
- size_t size; ///< packet size, default Dav1dData.sz
- struct Dav1dUserData user_data; ///< user-configurable data, default NULL members
-} Dav1dDataProps;
-
-#endif /* DAV1D_COMMON_H */
+/*
+ * Copyright © 2018, VideoLAN and dav1d authors
+ * Copyright © 2018, Two Orioles, LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DAV1D_COMMON_H
+#define DAV1D_COMMON_H
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#ifndef DAV1D_API
+ #if defined _WIN32
+ #if defined DAV1D_BUILDING_DLL
+ #define DAV1D_API __declspec(dllexport)
+ #else
+ #define DAV1D_API
+ #endif
+ #else
+ #if __GNUC__ >= 4
+ #define DAV1D_API __attribute__ ((visibility ("default")))
+ #else
+ #define DAV1D_API
+ #endif
+ #endif
+#endif
+
+#if EPERM > 0
+#define DAV1D_ERR(e) (-(e)) ///< Negate POSIX error code.
+#else
+#define DAV1D_ERR(e) (e)
+#endif
+
+/**
+ * A reference-counted object wrapper for a user-configurable pointer.
+ */
+typedef struct Dav1dUserData {
+ const uint8_t *data; ///< data pointer
+ struct Dav1dRef *ref; ///< allocation origin
+} Dav1dUserData;
+
+/**
+ * Input packet metadata which are copied from the input data used to
+ * decode each image into the matching structure of the output image
+ * returned back to the user. Since these are metadata fields, they
+ * can be used for other purposes than the documented ones, they will
+ * still be passed from input data to output picture without being
+ * used internally.
+ */
+typedef struct Dav1dDataProps {
+ int64_t timestamp; ///< container timestamp of input data, INT64_MIN if unknown (default)
+ int64_t duration; ///< container duration of input data, 0 if unknown (default)
+ int64_t offset; ///< stream offset of input data, -1 if unknown (default)
+ size_t size; ///< packet size, default Dav1dData.sz
+ struct Dav1dUserData user_data; ///< user-configurable data, default NULL members
+} Dav1dDataProps;
+
+#endif /* DAV1D_COMMON_H */
diff --git a/src/third_party/libdav1d/include/dav1d/data.h b/src/third_party/libdav1d/include/dav1d/data.h
index f945a04..b532474 100644
--- a/src/third_party/libdav1d/include/dav1d/data.h
+++ b/src/third_party/libdav1d/include/dav1d/data.h
@@ -1,109 +1,109 @@
-/*
- * Copyright © 2018, VideoLAN and dav1d authors
- * Copyright © 2018, Two Orioles, LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DAV1D_DATA_H
-#define DAV1D_DATA_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "common.h"
-
-typedef struct Dav1dData {
- const uint8_t *data; ///< data pointer
- size_t sz; ///< data size
- struct Dav1dRef *ref; ///< allocation origin
- Dav1dDataProps m; ///< user provided metadata passed to the output picture
-} Dav1dData;
-
-/**
- * Allocate data.
- *
- * @param data Input context.
- * @param sz Size of the data that should be allocated.
- *
- * @return Pointer to the allocated buffer on success. NULL on error.
- */
-DAV1D_API uint8_t * dav1d_data_create(Dav1dData *data, size_t sz);
-
-/**
- * Wrap an existing data array.
- *
- * @param data Input context.
- * @param buf The data to be wrapped.
- * @param sz Size of the data.
- * @param free_callback Function to be called when we release our last
- * reference to this data. In this callback, $buf will be
- * the $buf argument to this function, and $cookie will
- * be the $cookie input argument to this function.
- * @param cookie Opaque parameter passed to free_callback().
- *
- * @return 0 on success. A negative DAV1D_ERR value on error.
- */
-DAV1D_API int dav1d_data_wrap(Dav1dData *data, const uint8_t *buf, size_t sz,
- void (*free_callback)(const uint8_t *buf, void *cookie),
- void *cookie);
-
-/**
- * Wrap a user-provided data pointer into a reference counted object.
- *
- * data->m.user_data field will initialized to wrap the provided $user_data
- * pointer.
- *
- * $free_callback will be called on the same thread that released the last
- * reference. If frame threading is used, make sure $free_callback is
- * thread-safe.
- *
- * @param data Input context.
- * @param user_data The user data to be wrapped.
- * @param free_callback Function to be called when we release our last
- * reference to this data. In this callback, $user_data
- * will be the $user_data argument to this function, and
- * $cookie will be the $cookie input argument to this
- * function.
- * @param cookie Opaque parameter passed to $free_callback.
- *
- * @return 0 on success. A negative DAV1D_ERR value on error.
- */
-DAV1D_API int dav1d_data_wrap_user_data(Dav1dData *data,
- const uint8_t *user_data,
- void (*free_callback)(const uint8_t *user_data,
- void *cookie),
- void *cookie);
-
-/**
- * Free the data reference.
- *
- * The reference count for data->m.user_data will be decremented (if it has been
- * initialized with dav1d_data_wrap_user_data). The $data object will be memset
- * to 0.
- *
- * @param data Input context.
- */
-DAV1D_API void dav1d_data_unref(Dav1dData *data);
-
-#endif /* DAV1D_DATA_H */
+/*
+ * Copyright © 2018, VideoLAN and dav1d authors
+ * Copyright © 2018, Two Orioles, LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DAV1D_DATA_H
+#define DAV1D_DATA_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "common.h"
+
+typedef struct Dav1dData {
+ const uint8_t *data; ///< data pointer
+ size_t sz; ///< data size
+ struct Dav1dRef *ref; ///< allocation origin
+ Dav1dDataProps m; ///< user provided metadata passed to the output picture
+} Dav1dData;
+
+/**
+ * Allocate data.
+ *
+ * @param data Input context.
+ * @param sz Size of the data that should be allocated.
+ *
+ * @return Pointer to the allocated buffer on success. NULL on error.
+ */
+DAV1D_API uint8_t * dav1d_data_create(Dav1dData *data, size_t sz);
+
+/**
+ * Wrap an existing data array.
+ *
+ * @param data Input context.
+ * @param buf The data to be wrapped.
+ * @param sz Size of the data.
+ * @param free_callback Function to be called when we release our last
+ * reference to this data. In this callback, $buf will be
+ * the $buf argument to this function, and $cookie will
+ * be the $cookie input argument to this function.
+ * @param cookie Opaque parameter passed to free_callback().
+ *
+ * @return 0 on success. A negative DAV1D_ERR value on error.
+ */
+DAV1D_API int dav1d_data_wrap(Dav1dData *data, const uint8_t *buf, size_t sz,
+ void (*free_callback)(const uint8_t *buf, void *cookie),
+ void *cookie);
+
+/**
+ * Wrap a user-provided data pointer into a reference counted object.
+ *
+ * data->m.user_data field will initialized to wrap the provided $user_data
+ * pointer.
+ *
+ * $free_callback will be called on the same thread that released the last
+ * reference. If frame threading is used, make sure $free_callback is
+ * thread-safe.
+ *
+ * @param data Input context.
+ * @param user_data The user data to be wrapped.
+ * @param free_callback Function to be called when we release our last
+ * reference to this data. In this callback, $user_data
+ * will be the $user_data argument to this function, and
+ * $cookie will be the $cookie input argument to this
+ * function.
+ * @param cookie Opaque parameter passed to $free_callback.
+ *
+ * @return 0 on success. A negative DAV1D_ERR value on error.
+ */
+DAV1D_API int dav1d_data_wrap_user_data(Dav1dData *data,
+ const uint8_t *user_data,
+ void (*free_callback)(const uint8_t *user_data,
+ void *cookie),
+ void *cookie);
+
+/**
+ * Free the data reference.
+ *
+ * The reference count for data->m.user_data will be decremented (if it has been
+ * initialized with dav1d_data_wrap_user_data). The $data object will be memset
+ * to 0.
+ *
+ * @param data Input context.
+ */
+DAV1D_API void dav1d_data_unref(Dav1dData *data);
+
+#endif /* DAV1D_DATA_H */
diff --git a/src/third_party/libdav1d/include/dav1d/dav1d.h b/src/third_party/libdav1d/include/dav1d/dav1d.h
index 76558cf..8d3d97c 100644
--- a/src/third_party/libdav1d/include/dav1d/dav1d.h
+++ b/src/third_party/libdav1d/include/dav1d/dav1d.h
@@ -1,210 +1,244 @@
-/*
- * Copyright © 2018, VideoLAN and dav1d authors
- * Copyright © 2018, Two Orioles, LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DAV1D_H
-#define DAV1D_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <errno.h>
-#include <stdarg.h>
-
-#include "common.h"
-#include "picture.h"
-#include "data.h"
-
-#define DAV1D_API_VERSION_MAJOR 3
-#define DAV1D_API_VERSION_MINOR 1
-#define DAV1D_API_VERSION_PATCH 0
-
-typedef struct Dav1dContext Dav1dContext;
-typedef struct Dav1dRef Dav1dRef;
-
-#define DAV1D_MAX_FRAME_THREADS 256
-#define DAV1D_MAX_TILE_THREADS 64
-
-typedef struct Dav1dLogger {
- void *cookie; ///< Custom data to pass to the callback.
- /**
- * Logger callback. Default prints to stderr. May be NULL to disable logging.
- *
- * @param cookie Custom pointer passed to all calls.
- * @param format The vprintf compatible format string.
- * @param ap List of arguments referenced by the format string.
- */
- void (*callback)(void *cookie, const char *format, va_list ap);
-} Dav1dLogger;
-
-typedef struct Dav1dSettings {
- int n_frame_threads;
- int n_tile_threads;
- int apply_grain;
- int operating_point; ///< select an operating point for scalable AV1 bitstreams (0 - 31)
- int all_layers; ///< output all spatial layers of a scalable AV1 biststream
- unsigned frame_size_limit; ///< maximum frame size, in pixels (0 = unlimited)
- uint8_t reserved[32]; ///< reserved for future use
- Dav1dPicAllocator allocator;
- Dav1dLogger logger;
-} Dav1dSettings;
-
-/**
- * Get library version.
- */
-DAV1D_API const char *dav1d_version(void);
-
-/**
- * Initialize settings to default values.
- *
- * @param s Input settings context.
- */
-DAV1D_API void dav1d_default_settings(Dav1dSettings *s);
-
-/**
- * Allocate and open a decoder instance.
- *
- * @param c_out The decoder instance to open. *c_out will be set to the
- * allocated context.
- * @param s Input settings context.
- *
- * @note The context must be freed using dav1d_close() when decoding is
- * finished.
- *
- * @return 0 on success, or < 0 (a negative DAV1D_ERR code) on error.
- */
-DAV1D_API int dav1d_open(Dav1dContext **c_out, const Dav1dSettings *s);
-
-/**
- * Parse a Sequence Header OBU from bitstream data.
- *
- * @param out Output Sequence Header.
- * @param buf The data to be parser.
- * @param sz Size of the data.
- *
- * @return 0 on success, or < 0 (a negative DAV1D_ERR code) on error.
- *
- * @note It is safe to feed this function data containing other OBUs than a
- * Sequence Header, as they will simply be ignored. If there is more than
- * one Sequence Header OBU present, only the last will be returned.
- */
-DAV1D_API int dav1d_parse_sequence_header(Dav1dSequenceHeader *out,
- const uint8_t *buf, const size_t sz);
-
-/**
- * Feed bitstream data to the decoder.
- *
- * @param c Input decoder instance.
- * @param in Input bitstream data. On success, ownership of the reference is
- * passed to the library.
- *
- * @return
- * 0: Success, and the data was consumed.
- * DAV1D_ERR(EAGAIN): The data can't be consumed. dav1d_get_picture() should
- * be called to get one or more frames before the function
- * can consume new data.
- * other negative DAV1D_ERR codes: Error during decoding or because of invalid
- * passed-in arguments.
- */
-DAV1D_API int dav1d_send_data(Dav1dContext *c, Dav1dData *in);
-
-/**
- * Return a decoded picture.
- *
- * @param c Input decoder instance.
- * @param out Output frame. The caller assumes ownership of the returned
- * reference.
- *
- * @return
- * 0: Success, and a frame is returned.
- * DAV1D_ERR(EAGAIN): Not enough data to output a frame. dav1d_send_data()
- * should be called with new input.
- * other negative DAV1D_ERR codes: Error during decoding or because of invalid
- * passed-in arguments.
- *
- * @note To drain buffered frames from the decoder (i.e. on end of stream),
- * call this function until it returns DAV1D_ERR(EAGAIN).
- *
- * @code{.c}
- * Dav1dData data = { 0 };
- * Dav1dPicture p = { 0 };
- * int res;
- *
- * read_data(&data);
- * do {
- * res = dav1d_send_data(c, &data);
- * // Keep going even if the function can't consume the current data
- * packet. It eventually will after one or more frames have been
- * returned in this loop.
- * if (res < 0 && res != DAV1D_ERR(EAGAIN))
- * free_and_abort();
- * res = dav1d_get_picture(c, &p);
- * if (res < 0) {
- * if (res != DAV1D_ERR(EAGAIN))
- * free_and_abort();
- * } else
- * output_and_unref_picture(&p);
- * // Stay in the loop as long as there's data to consume.
- * } while (data.sz || read_data(&data) == SUCCESS);
- *
- * // Handle EOS by draining all buffered frames.
- * do {
- * res = dav1d_get_picture(c, &p);
- * if (res < 0) {
- * if (res != DAV1D_ERR(EAGAIN))
- * free_and_abort();
- * } else
- * output_and_unref_picture(&p);
- * } while (res == 0);
- * @endcode
- */
-DAV1D_API int dav1d_get_picture(Dav1dContext *c, Dav1dPicture *out);
-
-/**
- * Close a decoder instance and free all associated memory.
- *
- * @param c_out The decoder instance to close. *c_out will be set to NULL.
- */
-DAV1D_API void dav1d_close(Dav1dContext **c_out);
-
-/**
- * Flush all delayed frames in decoder and clear internal decoder state,
- * to be used when seeking.
- *
- * @param c Input decoder instance.
- *
- * @note Decoding will start only after a valid sequence header OBU is
- * delivered to dav1d_send_data().
- *
- */
-DAV1D_API void dav1d_flush(Dav1dContext *c);
-
-# ifdef __cplusplus
-}
-# endif
-
-#endif /* DAV1D_H */
+/*
+ * Copyright © 2018-2021, VideoLAN and dav1d authors
+ * Copyright © 2018, Two Orioles, LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DAV1D_H
+#define DAV1D_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <errno.h>
+#include <stdarg.h>
+
+#include "common.h"
+#include "picture.h"
+#include "data.h"
+
+#define DAV1D_API_VERSION_MAJOR 3
+#define DAV1D_API_VERSION_MINOR 1
+#define DAV1D_API_VERSION_PATCH 0
+
+typedef struct Dav1dContext Dav1dContext;
+typedef struct Dav1dRef Dav1dRef;
+
+#define DAV1D_MAX_THREADS 256
+#define DAV1D_MAX_FRAME_DELAY 256
+
+typedef struct Dav1dLogger {
+ void *cookie; ///< Custom data to pass to the callback.
+ /**
+ * Logger callback. May be NULL to disable logging.
+ *
+ * @param cookie Custom pointer passed to all calls.
+ * @param format The vprintf compatible format string.
+ * @param ap List of arguments referenced by the format string.
+ */
+ void (*callback)(void *cookie, const char *format, va_list ap);
+} Dav1dLogger;
+
+typedef struct Dav1dSettings {
+ int n_threads; ///< number of threads (0 = auto)
+ int max_frame_delay; ///< Set to 1 for low-latency decoding (0 = auto)
+ int apply_grain;
+ int operating_point; ///< select an operating point for scalable AV1 bitstreams (0 - 31)
+ int all_layers; ///< output all spatial layers of a scalable AV1 biststream
+ unsigned frame_size_limit; ///< maximum frame size, in pixels (0 = unlimited)
+ Dav1dPicAllocator allocator; ///< Picture allocator callback.
+ Dav1dLogger logger; ///< Logger callback.
+ uint8_t reserved[32]; ///< reserved for future use
+} Dav1dSettings;
+
+/**
+ * Get library version.
+ */
+DAV1D_API const char *dav1d_version(void);
+
+/**
+ * Initialize settings to default values.
+ *
+ * @param s Input settings context.
+ */
+DAV1D_API void dav1d_default_settings(Dav1dSettings *s);
+
+/**
+ * Allocate and open a decoder instance.
+ *
+ * @param c_out The decoder instance to open. *c_out will be set to the
+ * allocated context.
+ * @param s Input settings context.
+ *
+ * @note The context must be freed using dav1d_close() when decoding is
+ * finished.
+ *
+ * @return 0 on success, or < 0 (a negative DAV1D_ERR code) on error.
+ */
+DAV1D_API int dav1d_open(Dav1dContext **c_out, const Dav1dSettings *s);
+
+/**
+ * Parse a Sequence Header OBU from bitstream data.
+ *
+ * @param out Output Sequence Header.
+ * @param buf The data to be parser.
+ * @param sz Size of the data.
+ *
+ * @return
+ * 0: Success, and out is filled with the parsed Sequence Header
+ * OBU parameters.
+ * DAV1D_ERR(ENOENT): No Sequence Header OBUs were found in the buffer.
+ * other negative DAV1D_ERR codes: Invalid data in the buffer, invalid passed-in
+ * arguments, and other errors during parsing.
+ *
+ * @note It is safe to feed this function data containing other OBUs than a
+ * Sequence Header, as they will simply be ignored. If there is more than
+ * one Sequence Header OBU present, only the last will be returned.
+ */
+DAV1D_API int dav1d_parse_sequence_header(Dav1dSequenceHeader *out,
+ const uint8_t *buf, const size_t sz);
+
+/**
+ * Feed bitstream data to the decoder.
+ *
+ * @param c Input decoder instance.
+ * @param in Input bitstream data. On success, ownership of the reference is
+ * passed to the library.
+ *
+ * @return
+ * 0: Success, and the data was consumed.
+ * DAV1D_ERR(EAGAIN): The data can't be consumed. dav1d_get_picture() should
+ * be called to get one or more frames before the function
+ * can consume new data.
+ * other negative DAV1D_ERR codes: Error during decoding or because of invalid
+ * passed-in arguments.
+ */
+DAV1D_API int dav1d_send_data(Dav1dContext *c, Dav1dData *in);
+
+/**
+ * Return a decoded picture.
+ *
+ * @param c Input decoder instance.
+ * @param out Output frame. The caller assumes ownership of the returned
+ * reference.
+ *
+ * @return
+ * 0: Success, and a frame is returned.
+ * DAV1D_ERR(EAGAIN): Not enough data to output a frame. dav1d_send_data()
+ * should be called with new input.
+ * other negative DAV1D_ERR codes: Error during decoding or because of invalid
+ * passed-in arguments.
+ *
+ * @note To drain buffered frames from the decoder (i.e. on end of stream),
+ * call this function until it returns DAV1D_ERR(EAGAIN).
+ *
+ * @code{.c}
+ * Dav1dData data = { 0 };
+ * Dav1dPicture p = { 0 };
+ * int res;
+ *
+ * read_data(&data);
+ * do {
+ * res = dav1d_send_data(c, &data);
+ * // Keep going even if the function can't consume the current data
+ * packet. It eventually will after one or more frames have been
+ * returned in this loop.
+ * if (res < 0 && res != DAV1D_ERR(EAGAIN))
+ * free_and_abort();
+ * res = dav1d_get_picture(c, &p);
+ * if (res < 0) {
+ * if (res != DAV1D_ERR(EAGAIN))
+ * free_and_abort();
+ * } else
+ * output_and_unref_picture(&p);
+ * // Stay in the loop as long as there's data to consume.
+ * } while (data.sz || read_data(&data) == SUCCESS);
+ *
+ * // Handle EOS by draining all buffered frames.
+ * do {
+ * res = dav1d_get_picture(c, &p);
+ * if (res < 0) {
+ * if (res != DAV1D_ERR(EAGAIN))
+ * free_and_abort();
+ * } else
+ * output_and_unref_picture(&p);
+ * } while (res == 0);
+ * @endcode
+ */
+DAV1D_API int dav1d_get_picture(Dav1dContext *c, Dav1dPicture *out);
+
+/**
+ * Close a decoder instance and free all associated memory.
+ *
+ * @param c_out The decoder instance to close. *c_out will be set to NULL.
+ */
+DAV1D_API void dav1d_close(Dav1dContext **c_out);
+
+/**
+ * Flush all delayed frames in decoder and clear internal decoder state,
+ * to be used when seeking.
+ *
+ * @param c Input decoder instance.
+ *
+ * @note Decoding will start only after a valid sequence header OBU is
+ * delivered to dav1d_send_data().
+ *
+ */
+DAV1D_API void dav1d_flush(Dav1dContext *c);
+
+enum Dav1dEventFlags {
+ /**
+ * The last returned picture contains a reference to a new Sequence Header,
+ * either because it's the start of a new coded sequence, or the decoder was
+ * flushed before it was generated.
+ */
+ DAV1D_EVENT_FLAG_NEW_SEQUENCE = 1 << 0,
+ /**
+ * The last returned picture contains a reference to a Sequence Header with
+ * new operating parameters information for the current coded sequence.
+ */
+ DAV1D_EVENT_FLAG_NEW_OP_PARAMS_INFO = 1 << 1,
+};
+
+/**
+ * Fetch a combination of DAV1D_EVENT_FLAG_* event flags generated by the decoding
+ * process.
+ *
+ * @param c Input decoder instance.
+ * @param flags Where to write the flags.
+ *
+ * @return 0 on success, or < 0 (a negative DAV1D_ERR code) on error.
+ *
+ * @note Calling this function will clear all the event flags currently stored in
+ * the decoder.
+ *
+ */
+DAV1D_API int dav1d_get_event_flags(Dav1dContext *c, enum Dav1dEventFlags *flags);
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* DAV1D_H */
diff --git a/src/third_party/libdav1d/include/dav1d/headers.h b/src/third_party/libdav1d/include/dav1d/headers.h
index 4e3bf9e..7ec6cef 100644
--- a/src/third_party/libdav1d/include/dav1d/headers.h
+++ b/src/third_party/libdav1d/include/dav1d/headers.h
@@ -1,430 +1,435 @@
-/*
- * Copyright © 2018, VideoLAN and dav1d authors
- * Copyright © 2018, Two Orioles, LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DAV1D_HEADERS_H
-#define DAV1D_HEADERS_H
-
-#include <stddef.h>
-
-// Constants from Section 3. "Symbols and abbreviated terms"
-#define DAV1D_MAX_CDEF_STRENGTHS 8
-#define DAV1D_MAX_OPERATING_POINTS 32
-#define DAV1D_MAX_TILE_COLS 64
-#define DAV1D_MAX_TILE_ROWS 64
-#define DAV1D_MAX_SEGMENTS 8
-#define DAV1D_NUM_REF_FRAMES 8
-#define DAV1D_PRIMARY_REF_NONE 7
-#define DAV1D_REFS_PER_FRAME 7
-#define DAV1D_TOTAL_REFS_PER_FRAME (DAV1D_REFS_PER_FRAME + 1)
-
-enum Dav1dObuType {
- DAV1D_OBU_SEQ_HDR = 1,
- DAV1D_OBU_TD = 2,
- DAV1D_OBU_FRAME_HDR = 3,
- DAV1D_OBU_TILE_GRP = 4,
- DAV1D_OBU_METADATA = 5,
- DAV1D_OBU_FRAME = 6,
- DAV1D_OBU_REDUNDANT_FRAME_HDR = 7,
- DAV1D_OBU_PADDING = 15,
-};
-
-enum Dav1dTxfmMode {
- DAV1D_TX_4X4_ONLY,
- DAV1D_TX_LARGEST,
- DAV1D_TX_SWITCHABLE,
- DAV1D_N_TX_MODES,
-};
-
-enum Dav1dFilterMode {
- DAV1D_FILTER_8TAP_REGULAR,
- DAV1D_FILTER_8TAP_SMOOTH,
- DAV1D_FILTER_8TAP_SHARP,
- DAV1D_N_SWITCHABLE_FILTERS,
- DAV1D_FILTER_BILINEAR = DAV1D_N_SWITCHABLE_FILTERS,
- DAV1D_N_FILTERS,
- DAV1D_FILTER_SWITCHABLE = DAV1D_N_FILTERS,
-};
-
-enum Dav1dAdaptiveBoolean {
- DAV1D_OFF = 0,
- DAV1D_ON = 1,
- DAV1D_ADAPTIVE = 2,
-};
-
-enum Dav1dRestorationType {
- DAV1D_RESTORATION_NONE,
- DAV1D_RESTORATION_SWITCHABLE,
- DAV1D_RESTORATION_WIENER,
- DAV1D_RESTORATION_SGRPROJ,
-};
-
-enum Dav1dWarpedMotionType {
- DAV1D_WM_TYPE_IDENTITY,
- DAV1D_WM_TYPE_TRANSLATION,
- DAV1D_WM_TYPE_ROT_ZOOM,
- DAV1D_WM_TYPE_AFFINE,
-};
-
-typedef struct Dav1dWarpedMotionParams {
- enum Dav1dWarpedMotionType type;
- int32_t matrix[6];
- union {
- struct {
- int16_t alpha, beta, gamma, delta;
- };
- int16_t abcd[4];
- };
-} Dav1dWarpedMotionParams;
-
-enum Dav1dPixelLayout {
- DAV1D_PIXEL_LAYOUT_I400, ///< monochrome
- DAV1D_PIXEL_LAYOUT_I420, ///< 4:2:0 planar
- DAV1D_PIXEL_LAYOUT_I422, ///< 4:2:2 planar
- DAV1D_PIXEL_LAYOUT_I444, ///< 4:4:4 planar
-};
-
-enum Dav1dFrameType {
- DAV1D_FRAME_TYPE_KEY = 0, ///< Key Intra frame
- DAV1D_FRAME_TYPE_INTER = 1, ///< Inter frame
- DAV1D_FRAME_TYPE_INTRA = 2, ///< Non key Intra frame
- DAV1D_FRAME_TYPE_SWITCH = 3, ///< Switch Inter frame
-};
-
-enum Dav1dColorPrimaries {
- DAV1D_COLOR_PRI_BT709 = 1,
- DAV1D_COLOR_PRI_UNKNOWN = 2,
- DAV1D_COLOR_PRI_BT470M = 4,
- DAV1D_COLOR_PRI_BT470BG = 5,
- DAV1D_COLOR_PRI_BT601 = 6,
- DAV1D_COLOR_PRI_SMPTE240 = 7,
- DAV1D_COLOR_PRI_FILM = 8,
- DAV1D_COLOR_PRI_BT2020 = 9,
- DAV1D_COLOR_PRI_XYZ = 10,
- DAV1D_COLOR_PRI_SMPTE431 = 11,
- DAV1D_COLOR_PRI_SMPTE432 = 12,
- DAV1D_COLOR_PRI_EBU3213 = 22,
-};
-
-enum Dav1dTransferCharacteristics {
- DAV1D_TRC_BT709 = 1,
- DAV1D_TRC_UNKNOWN = 2,
- DAV1D_TRC_BT470M = 4,
- DAV1D_TRC_BT470BG = 5,
- DAV1D_TRC_BT601 = 6,
- DAV1D_TRC_SMPTE240 = 7,
- DAV1D_TRC_LINEAR = 8,
- DAV1D_TRC_LOG100 = 9, ///< logarithmic (100:1 range)
- DAV1D_TRC_LOG100_SQRT10 = 10, ///< lograithmic (100*sqrt(10):1 range)
- DAV1D_TRC_IEC61966 = 11,
- DAV1D_TRC_BT1361 = 12,
- DAV1D_TRC_SRGB = 13,
- DAV1D_TRC_BT2020_10BIT = 14,
- DAV1D_TRC_BT2020_12BIT = 15,
- DAV1D_TRC_SMPTE2084 = 16, ///< PQ
- DAV1D_TRC_SMPTE428 = 17,
- DAV1D_TRC_HLG = 18, ///< hybrid log/gamma (BT.2100 / ARIB STD-B67)
-};
-
-enum Dav1dMatrixCoefficients {
- DAV1D_MC_IDENTITY = 0,
- DAV1D_MC_BT709 = 1,
- DAV1D_MC_UNKNOWN = 2,
- DAV1D_MC_FCC = 4,
- DAV1D_MC_BT470BG = 5,
- DAV1D_MC_BT601 = 6,
- DAV1D_MC_SMPTE240 = 7,
- DAV1D_MC_SMPTE_YCGCO = 8,
- DAV1D_MC_BT2020_NCL = 9,
- DAV1D_MC_BT2020_CL = 10,
- DAV1D_MC_SMPTE2085 = 11,
- DAV1D_MC_CHROMAT_NCL = 12, ///< Chromaticity-derived
- DAV1D_MC_CHROMAT_CL = 13,
- DAV1D_MC_ICTCP = 14,
-};
-
-enum Dav1dChromaSamplePosition {
- DAV1D_CHR_UNKNOWN = 0,
- DAV1D_CHR_VERTICAL = 1, ///< Horizontally co-located with luma(0, 0)
- ///< sample, between two vertical samples
- DAV1D_CHR_COLOCATED = 2, ///< Co-located with luma(0, 0) sample
-};
-
-typedef struct Dav1dContentLightLevel {
- int max_content_light_level;
- int max_frame_average_light_level;
-} Dav1dContentLightLevel;
-
-typedef struct Dav1dMasteringDisplay {
- ///< 0.16 fixed point
- uint16_t primaries[3][2];
- ///< 0.16 fixed point
- uint16_t white_point[2];
- ///< 24.8 fixed point
- uint32_t max_luminance;
- ///< 18.14 fixed point
- uint32_t min_luminance;
-} Dav1dMasteringDisplay;
-
-typedef struct Dav1dITUTT35 {
- uint8_t country_code;
- uint8_t country_code_extension_byte;
- size_t payload_size;
- uint8_t *payload;
-} Dav1dITUTT35;
-
-typedef struct Dav1dSequenceHeader {
- /**
- * Stream profile, 0 for 8-10 bits/component 4:2:0 or monochrome;
- * 1 for 8-10 bits/component 4:4:4; 2 for 4:2:2 at any bits/component,
- * or 12 bits/component at any chroma subsampling.
- */
- int profile;
- /**
- * Maximum dimensions for this stream. In non-scalable streams, these
- * are often the actual dimensions of the stream, although that is not
- * a normative requirement.
- */
- int max_width, max_height;
- enum Dav1dPixelLayout layout; ///< format of the picture
- enum Dav1dColorPrimaries pri; ///< color primaries (av1)
- enum Dav1dTransferCharacteristics trc; ///< transfer characteristics (av1)
- enum Dav1dMatrixCoefficients mtrx; ///< matrix coefficients (av1)
- enum Dav1dChromaSamplePosition chr; ///< chroma sample position (av1)
- /**
- * 0, 1 and 2 mean 8, 10 or 12 bits/component, respectively. This is not
- * exactly the same as 'hbd' from the spec; the spec's hbd distinguishes
- * between 8 (0) and 10-12 (1) bits/component, and another element
- * (twelve_bit) to distinguish between 10 and 12 bits/component. To get
- * the spec's hbd, use !!our_hbd, and to get twelve_bit, use hbd == 2.
- */
- int hbd;
- /**
- * Pixel data uses JPEG pixel range ([0,255] for 8bits) instead of
- * MPEG pixel range ([16,235] for 8bits luma, [16,240] for 8bits chroma).
- */
- int color_range;
-
- int num_operating_points;
- struct Dav1dSequenceHeaderOperatingPoint {
- int major_level, minor_level;
- int initial_display_delay;
- int idc;
- int tier;
- int decoder_model_param_present;
- int display_model_param_present;
- } operating_points[DAV1D_MAX_OPERATING_POINTS];
-
- int still_picture;
- int reduced_still_picture_header;
- int timing_info_present;
- int num_units_in_tick;
- int time_scale;
- int equal_picture_interval;
- unsigned num_ticks_per_picture;
- int decoder_model_info_present;
- int encoder_decoder_buffer_delay_length;
- int num_units_in_decoding_tick;
- int buffer_removal_delay_length;
- int frame_presentation_delay_length;
- int display_model_info_present;
- int width_n_bits, height_n_bits;
- int frame_id_numbers_present;
- int delta_frame_id_n_bits;
- int frame_id_n_bits;
- int sb128;
- int filter_intra;
- int intra_edge_filter;
- int inter_intra;
- int masked_compound;
- int warped_motion;
- int dual_filter;
- int order_hint;
- int jnt_comp;
- int ref_frame_mvs;
- enum Dav1dAdaptiveBoolean screen_content_tools;
- enum Dav1dAdaptiveBoolean force_integer_mv;
- int order_hint_n_bits;
- int super_res;
- int cdef;
- int restoration;
- int ss_hor, ss_ver, monochrome;
- int color_description_present;
- int separate_uv_delta_q;
- int film_grain_present;
-
- // Dav1dSequenceHeaders of the same sequence are required to be
- // bit-identical until this offset. See 7.5 "Ordering of OBUs":
- // Within a particular coded video sequence, the contents of
- // sequence_header_obu must be bit-identical each time the
- // sequence header appears except for the contents of
- // operating_parameters_info.
- struct Dav1dSequenceHeaderOperatingParameterInfo {
- int decoder_buffer_delay;
- int encoder_buffer_delay;
- int low_delay_mode;
- } operating_parameter_info[DAV1D_MAX_OPERATING_POINTS];
-} Dav1dSequenceHeader;
-
-typedef struct Dav1dSegmentationData {
- int delta_q;
- int delta_lf_y_v, delta_lf_y_h, delta_lf_u, delta_lf_v;
- int ref;
- int skip;
- int globalmv;
-} Dav1dSegmentationData;
-
-typedef struct Dav1dSegmentationDataSet {
- Dav1dSegmentationData d[DAV1D_MAX_SEGMENTS];
- int preskip;
- int last_active_segid;
-} Dav1dSegmentationDataSet;
-
-typedef struct Dav1dLoopfilterModeRefDeltas {
- int mode_delta[2 /* is_zeromv */];
- int ref_delta[DAV1D_TOTAL_REFS_PER_FRAME];
-} Dav1dLoopfilterModeRefDeltas;
-
-typedef struct Dav1dFilmGrainData {
- unsigned seed;
- int num_y_points;
- uint8_t y_points[14][2 /* value, scaling */];
- int chroma_scaling_from_luma;
- int num_uv_points[2];
- uint8_t uv_points[2][10][2 /* value, scaling */];
- int scaling_shift;
- int ar_coeff_lag;
- int8_t ar_coeffs_y[24];
- int8_t ar_coeffs_uv[2][25];
- int ar_coeff_shift;
- int grain_scale_shift;
- int uv_mult[2];
- int uv_luma_mult[2];
- int uv_offset[2];
- int overlap_flag;
- int clip_to_restricted_range;
-} Dav1dFilmGrainData;
-
-typedef struct Dav1dFrameHeader {
- enum Dav1dFrameType frame_type; ///< type of the picture
- int width[2 /* { coded_width, superresolution_upscaled_width } */], height;
- int frame_offset; ///< frame number
- struct {
- int present, update;
- Dav1dFilmGrainData data;
- } film_grain; ///< film grain parameters
- int temporal_id, spatial_id; ///< spatial and temporal id of the frame for SVC
-
- int show_existing_frame;
- int existing_frame_idx;
- int frame_id;
- int frame_presentation_delay;
- int show_frame;
- int showable_frame;
- int error_resilient_mode;
- int disable_cdf_update;
- int allow_screen_content_tools;
- int force_integer_mv;
- int frame_size_override;
- int primary_ref_frame;
- int buffer_removal_time_present;
- struct Dav1dFrameHeaderOperatingPoint {
- int buffer_removal_time;
- } operating_points[DAV1D_MAX_OPERATING_POINTS];
- int refresh_frame_flags;
- int render_width, render_height;
- struct {
- int width_scale_denominator;
- int enabled;
- } super_res;
- int have_render_size;
- int allow_intrabc;
- int frame_ref_short_signaling;
- int refidx[DAV1D_REFS_PER_FRAME];
- int hp;
- enum Dav1dFilterMode subpel_filter_mode;
- int switchable_motion_mode;
- int use_ref_frame_mvs;
- int refresh_context;
- struct {
- int uniform;
- unsigned n_bytes;
- int min_log2_cols, max_log2_cols, log2_cols, cols;
- int min_log2_rows, max_log2_rows, log2_rows, rows;
- uint16_t col_start_sb[DAV1D_MAX_TILE_COLS + 1];
- uint16_t row_start_sb[DAV1D_MAX_TILE_ROWS + 1];
- int update;
- } tiling;
- struct {
- int yac;
- int ydc_delta;
- int udc_delta, uac_delta, vdc_delta, vac_delta;
- int qm, qm_y, qm_u, qm_v;
- } quant;
- struct {
- int enabled, update_map, temporal, update_data;
- Dav1dSegmentationDataSet seg_data;
- int lossless[DAV1D_MAX_SEGMENTS], qidx[DAV1D_MAX_SEGMENTS];
- } segmentation;
- struct {
- struct {
- int present;
- int res_log2;
- } q;
- struct {
- int present;
- int res_log2;
- int multi;
- } lf;
- } delta;
- int all_lossless;
- struct {
- int level_y[2 /* dir */];
- int level_u, level_v;
- int mode_ref_delta_enabled;
- int mode_ref_delta_update;
- Dav1dLoopfilterModeRefDeltas mode_ref_deltas;
- int sharpness;
- } loopfilter;
- struct {
- int damping;
- int n_bits;
- int y_strength[DAV1D_MAX_CDEF_STRENGTHS];
- int uv_strength[DAV1D_MAX_CDEF_STRENGTHS];
- } cdef;
- struct {
- enum Dav1dRestorationType type[3 /* plane */];
- int unit_size[2 /* y, uv */];
- } restoration;
- enum Dav1dTxfmMode txfm_mode;
- int switchable_comp_refs;
- int skip_mode_allowed, skip_mode_enabled, skip_mode_refs[2];
- int warp_motion;
- int reduced_txtp_set;
- Dav1dWarpedMotionParams gmv[DAV1D_REFS_PER_FRAME];
-} Dav1dFrameHeader;
-
-#endif /* DAV1D_HEADERS_H */
+/*
+ * Copyright © 2018-2020, VideoLAN and dav1d authors
+ * Copyright © 2018, Two Orioles, LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DAV1D_HEADERS_H
+#define DAV1D_HEADERS_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+// Constants from Section 3. "Symbols and abbreviated terms"
+#define DAV1D_MAX_CDEF_STRENGTHS 8
+#define DAV1D_MAX_OPERATING_POINTS 32
+#define DAV1D_MAX_TILE_COLS 64
+#define DAV1D_MAX_TILE_ROWS 64
+#define DAV1D_MAX_SEGMENTS 8
+#define DAV1D_NUM_REF_FRAMES 8
+#define DAV1D_PRIMARY_REF_NONE 7
+#define DAV1D_REFS_PER_FRAME 7
+#define DAV1D_TOTAL_REFS_PER_FRAME (DAV1D_REFS_PER_FRAME + 1)
+
+enum Dav1dObuType {
+ DAV1D_OBU_SEQ_HDR = 1,
+ DAV1D_OBU_TD = 2,
+ DAV1D_OBU_FRAME_HDR = 3,
+ DAV1D_OBU_TILE_GRP = 4,
+ DAV1D_OBU_METADATA = 5,
+ DAV1D_OBU_FRAME = 6,
+ DAV1D_OBU_REDUNDANT_FRAME_HDR = 7,
+ DAV1D_OBU_PADDING = 15,
+};
+
+enum Dav1dTxfmMode {
+ DAV1D_TX_4X4_ONLY,
+ DAV1D_TX_LARGEST,
+ DAV1D_TX_SWITCHABLE,
+ DAV1D_N_TX_MODES,
+};
+
+enum Dav1dFilterMode {
+ DAV1D_FILTER_8TAP_REGULAR,
+ DAV1D_FILTER_8TAP_SMOOTH,
+ DAV1D_FILTER_8TAP_SHARP,
+ DAV1D_N_SWITCHABLE_FILTERS,
+ DAV1D_FILTER_BILINEAR = DAV1D_N_SWITCHABLE_FILTERS,
+ DAV1D_N_FILTERS,
+ DAV1D_FILTER_SWITCHABLE = DAV1D_N_FILTERS,
+};
+
+enum Dav1dAdaptiveBoolean {
+ DAV1D_OFF = 0,
+ DAV1D_ON = 1,
+ DAV1D_ADAPTIVE = 2,
+};
+
+enum Dav1dRestorationType {
+ DAV1D_RESTORATION_NONE,
+ DAV1D_RESTORATION_SWITCHABLE,
+ DAV1D_RESTORATION_WIENER,
+ DAV1D_RESTORATION_SGRPROJ,
+};
+
+enum Dav1dWarpedMotionType {
+ DAV1D_WM_TYPE_IDENTITY,
+ DAV1D_WM_TYPE_TRANSLATION,
+ DAV1D_WM_TYPE_ROT_ZOOM,
+ DAV1D_WM_TYPE_AFFINE,
+};
+
+typedef struct Dav1dWarpedMotionParams {
+ enum Dav1dWarpedMotionType type;
+ int32_t matrix[6];
+ union {
+ struct {
+ int16_t alpha, beta, gamma, delta;
+ } p;
+ int16_t abcd[4];
+ } u;
+} Dav1dWarpedMotionParams;
+
+enum Dav1dPixelLayout {
+ DAV1D_PIXEL_LAYOUT_I400, ///< monochrome
+ DAV1D_PIXEL_LAYOUT_I420, ///< 4:2:0 planar
+ DAV1D_PIXEL_LAYOUT_I422, ///< 4:2:2 planar
+ DAV1D_PIXEL_LAYOUT_I444, ///< 4:4:4 planar
+};
+
+enum Dav1dFrameType {
+ DAV1D_FRAME_TYPE_KEY = 0, ///< Key Intra frame
+ DAV1D_FRAME_TYPE_INTER = 1, ///< Inter frame
+ DAV1D_FRAME_TYPE_INTRA = 2, ///< Non key Intra frame
+ DAV1D_FRAME_TYPE_SWITCH = 3, ///< Switch Inter frame
+};
+
+enum Dav1dColorPrimaries {
+ DAV1D_COLOR_PRI_BT709 = 1,
+ DAV1D_COLOR_PRI_UNKNOWN = 2,
+ DAV1D_COLOR_PRI_BT470M = 4,
+ DAV1D_COLOR_PRI_BT470BG = 5,
+ DAV1D_COLOR_PRI_BT601 = 6,
+ DAV1D_COLOR_PRI_SMPTE240 = 7,
+ DAV1D_COLOR_PRI_FILM = 8,
+ DAV1D_COLOR_PRI_BT2020 = 9,
+ DAV1D_COLOR_PRI_XYZ = 10,
+ DAV1D_COLOR_PRI_SMPTE431 = 11,
+ DAV1D_COLOR_PRI_SMPTE432 = 12,
+ DAV1D_COLOR_PRI_EBU3213 = 22,
+ DAV1D_COLOR_PRI_RESERVED = 255,
+};
+
+enum Dav1dTransferCharacteristics {
+ DAV1D_TRC_BT709 = 1,
+ DAV1D_TRC_UNKNOWN = 2,
+ DAV1D_TRC_BT470M = 4,
+ DAV1D_TRC_BT470BG = 5,
+ DAV1D_TRC_BT601 = 6,
+ DAV1D_TRC_SMPTE240 = 7,
+ DAV1D_TRC_LINEAR = 8,
+ DAV1D_TRC_LOG100 = 9, ///< logarithmic (100:1 range)
+ DAV1D_TRC_LOG100_SQRT10 = 10, ///< lograithmic (100*sqrt(10):1 range)
+ DAV1D_TRC_IEC61966 = 11,
+ DAV1D_TRC_BT1361 = 12,
+ DAV1D_TRC_SRGB = 13,
+ DAV1D_TRC_BT2020_10BIT = 14,
+ DAV1D_TRC_BT2020_12BIT = 15,
+ DAV1D_TRC_SMPTE2084 = 16, ///< PQ
+ DAV1D_TRC_SMPTE428 = 17,
+ DAV1D_TRC_HLG = 18, ///< hybrid log/gamma (BT.2100 / ARIB STD-B67)
+ DAV1D_TRC_RESERVED = 255,
+};
+
+enum Dav1dMatrixCoefficients {
+ DAV1D_MC_IDENTITY = 0,
+ DAV1D_MC_BT709 = 1,
+ DAV1D_MC_UNKNOWN = 2,
+ DAV1D_MC_FCC = 4,
+ DAV1D_MC_BT470BG = 5,
+ DAV1D_MC_BT601 = 6,
+ DAV1D_MC_SMPTE240 = 7,
+ DAV1D_MC_SMPTE_YCGCO = 8,
+ DAV1D_MC_BT2020_NCL = 9,
+ DAV1D_MC_BT2020_CL = 10,
+ DAV1D_MC_SMPTE2085 = 11,
+ DAV1D_MC_CHROMAT_NCL = 12, ///< Chromaticity-derived
+ DAV1D_MC_CHROMAT_CL = 13,
+ DAV1D_MC_ICTCP = 14,
+ DAV1D_MC_RESERVED = 255,
+};
+
+enum Dav1dChromaSamplePosition {
+ DAV1D_CHR_UNKNOWN = 0,
+ DAV1D_CHR_VERTICAL = 1, ///< Horizontally co-located with luma(0, 0)
+ ///< sample, between two vertical samples
+ DAV1D_CHR_COLOCATED = 2, ///< Co-located with luma(0, 0) sample
+};
+
+typedef struct Dav1dContentLightLevel {
+ int max_content_light_level;
+ int max_frame_average_light_level;
+} Dav1dContentLightLevel;
+
+typedef struct Dav1dMasteringDisplay {
+ ///< 0.16 fixed point
+ uint16_t primaries[3][2];
+ ///< 0.16 fixed point
+ uint16_t white_point[2];
+ ///< 24.8 fixed point
+ uint32_t max_luminance;
+ ///< 18.14 fixed point
+ uint32_t min_luminance;
+} Dav1dMasteringDisplay;
+
+typedef struct Dav1dITUTT35 {
+ uint8_t country_code;
+ uint8_t country_code_extension_byte;
+ size_t payload_size;
+ uint8_t *payload;
+} Dav1dITUTT35;
+
+typedef struct Dav1dSequenceHeader {
+ /**
+ * Stream profile, 0 for 8-10 bits/component 4:2:0 or monochrome;
+ * 1 for 8-10 bits/component 4:4:4; 2 for 4:2:2 at any bits/component,
+ * or 12 bits/component at any chroma subsampling.
+ */
+ int profile;
+ /**
+ * Maximum dimensions for this stream. In non-scalable streams, these
+ * are often the actual dimensions of the stream, although that is not
+ * a normative requirement.
+ */
+ int max_width, max_height;
+ enum Dav1dPixelLayout layout; ///< format of the picture
+ enum Dav1dColorPrimaries pri; ///< color primaries (av1)
+ enum Dav1dTransferCharacteristics trc; ///< transfer characteristics (av1)
+ enum Dav1dMatrixCoefficients mtrx; ///< matrix coefficients (av1)
+ enum Dav1dChromaSamplePosition chr; ///< chroma sample position (av1)
+ /**
+ * 0, 1 and 2 mean 8, 10 or 12 bits/component, respectively. This is not
+ * exactly the same as 'hbd' from the spec; the spec's hbd distinguishes
+ * between 8 (0) and 10-12 (1) bits/component, and another element
+ * (twelve_bit) to distinguish between 10 and 12 bits/component. To get
+ * the spec's hbd, use !!our_hbd, and to get twelve_bit, use hbd == 2.
+ */
+ int hbd;
+ /**
+ * Pixel data uses JPEG pixel range ([0,255] for 8bits) instead of
+ * MPEG pixel range ([16,235] for 8bits luma, [16,240] for 8bits chroma).
+ */
+ int color_range;
+
+ int num_operating_points;
+ struct Dav1dSequenceHeaderOperatingPoint {
+ int major_level, minor_level;
+ int initial_display_delay;
+ int idc;
+ int tier;
+ int decoder_model_param_present;
+ int display_model_param_present;
+ } operating_points[DAV1D_MAX_OPERATING_POINTS];
+
+ int still_picture;
+ int reduced_still_picture_header;
+ int timing_info_present;
+ int num_units_in_tick;
+ int time_scale;
+ int equal_picture_interval;
+ unsigned num_ticks_per_picture;
+ int decoder_model_info_present;
+ int encoder_decoder_buffer_delay_length;
+ int num_units_in_decoding_tick;
+ int buffer_removal_delay_length;
+ int frame_presentation_delay_length;
+ int display_model_info_present;
+ int width_n_bits, height_n_bits;
+ int frame_id_numbers_present;
+ int delta_frame_id_n_bits;
+ int frame_id_n_bits;
+ int sb128;
+ int filter_intra;
+ int intra_edge_filter;
+ int inter_intra;
+ int masked_compound;
+ int warped_motion;
+ int dual_filter;
+ int order_hint;
+ int jnt_comp;
+ int ref_frame_mvs;
+ enum Dav1dAdaptiveBoolean screen_content_tools;
+ enum Dav1dAdaptiveBoolean force_integer_mv;
+ int order_hint_n_bits;
+ int super_res;
+ int cdef;
+ int restoration;
+ int ss_hor, ss_ver, monochrome;
+ int color_description_present;
+ int separate_uv_delta_q;
+ int film_grain_present;
+
+ // Dav1dSequenceHeaders of the same sequence are required to be
+ // bit-identical until this offset. See 7.5 "Ordering of OBUs":
+ // Within a particular coded video sequence, the contents of
+ // sequence_header_obu must be bit-identical each time the
+ // sequence header appears except for the contents of
+ // operating_parameters_info.
+ struct Dav1dSequenceHeaderOperatingParameterInfo {
+ int decoder_buffer_delay;
+ int encoder_buffer_delay;
+ int low_delay_mode;
+ } operating_parameter_info[DAV1D_MAX_OPERATING_POINTS];
+} Dav1dSequenceHeader;
+
+typedef struct Dav1dSegmentationData {
+ int delta_q;
+ int delta_lf_y_v, delta_lf_y_h, delta_lf_u, delta_lf_v;
+ int ref;
+ int skip;
+ int globalmv;
+} Dav1dSegmentationData;
+
+typedef struct Dav1dSegmentationDataSet {
+ Dav1dSegmentationData d[DAV1D_MAX_SEGMENTS];
+ int preskip;
+ int last_active_segid;
+} Dav1dSegmentationDataSet;
+
+typedef struct Dav1dLoopfilterModeRefDeltas {
+ int mode_delta[2 /* is_zeromv */];
+ int ref_delta[DAV1D_TOTAL_REFS_PER_FRAME];
+} Dav1dLoopfilterModeRefDeltas;
+
+typedef struct Dav1dFilmGrainData {
+ unsigned seed;
+ int num_y_points;
+ uint8_t y_points[14][2 /* value, scaling */];
+ int chroma_scaling_from_luma;
+ int num_uv_points[2];
+ uint8_t uv_points[2][10][2 /* value, scaling */];
+ int scaling_shift;
+ int ar_coeff_lag;
+ int8_t ar_coeffs_y[24];
+ int8_t ar_coeffs_uv[2][25 + 3 /* padding for alignment purposes */];
+ uint64_t ar_coeff_shift;
+ int grain_scale_shift;
+ int uv_mult[2];
+ int uv_luma_mult[2];
+ int uv_offset[2];
+ int overlap_flag;
+ int clip_to_restricted_range;
+} Dav1dFilmGrainData;
+
+typedef struct Dav1dFrameHeader {
+ struct {
+ Dav1dFilmGrainData data;
+ int present, update;
+ } film_grain; ///< film grain parameters
+ enum Dav1dFrameType frame_type; ///< type of the picture
+ int width[2 /* { coded_width, superresolution_upscaled_width } */], height;
+ int frame_offset; ///< frame number
+ int temporal_id; ///< temporal id of the frame for SVC
+ int spatial_id; ///< spatial id of the frame for SVC
+
+ int show_existing_frame;
+ int existing_frame_idx;
+ int frame_id;
+ int frame_presentation_delay;
+ int show_frame;
+ int showable_frame;
+ int error_resilient_mode;
+ int disable_cdf_update;
+ int allow_screen_content_tools;
+ int force_integer_mv;
+ int frame_size_override;
+ int primary_ref_frame;
+ int buffer_removal_time_present;
+ struct Dav1dFrameHeaderOperatingPoint {
+ int buffer_removal_time;
+ } operating_points[DAV1D_MAX_OPERATING_POINTS];
+ int refresh_frame_flags;
+ int render_width, render_height;
+ struct {
+ int width_scale_denominator;
+ int enabled;
+ } super_res;
+ int have_render_size;
+ int allow_intrabc;
+ int frame_ref_short_signaling;
+ int refidx[DAV1D_REFS_PER_FRAME];
+ int hp;
+ enum Dav1dFilterMode subpel_filter_mode;
+ int switchable_motion_mode;
+ int use_ref_frame_mvs;
+ int refresh_context;
+ struct {
+ int uniform;
+ unsigned n_bytes;
+ int min_log2_cols, max_log2_cols, log2_cols, cols;
+ int min_log2_rows, max_log2_rows, log2_rows, rows;
+ uint16_t col_start_sb[DAV1D_MAX_TILE_COLS + 1];
+ uint16_t row_start_sb[DAV1D_MAX_TILE_ROWS + 1];
+ int update;
+ } tiling;
+ struct {
+ int yac;
+ int ydc_delta;
+ int udc_delta, uac_delta, vdc_delta, vac_delta;
+ int qm, qm_y, qm_u, qm_v;
+ } quant;
+ struct {
+ int enabled, update_map, temporal, update_data;
+ Dav1dSegmentationDataSet seg_data;
+ int lossless[DAV1D_MAX_SEGMENTS], qidx[DAV1D_MAX_SEGMENTS];
+ } segmentation;
+ struct {
+ struct {
+ int present;
+ int res_log2;
+ } q;
+ struct {
+ int present;
+ int res_log2;
+ int multi;
+ } lf;
+ } delta;
+ int all_lossless;
+ struct {
+ int level_y[2 /* dir */];
+ int level_u, level_v;
+ int mode_ref_delta_enabled;
+ int mode_ref_delta_update;
+ Dav1dLoopfilterModeRefDeltas mode_ref_deltas;
+ int sharpness;
+ } loopfilter;
+ struct {
+ int damping;
+ int n_bits;
+ int y_strength[DAV1D_MAX_CDEF_STRENGTHS];
+ int uv_strength[DAV1D_MAX_CDEF_STRENGTHS];
+ } cdef;
+ struct {
+ enum Dav1dRestorationType type[3 /* plane */];
+ int unit_size[2 /* y, uv */];
+ } restoration;
+ enum Dav1dTxfmMode txfm_mode;
+ int switchable_comp_refs;
+ int skip_mode_allowed, skip_mode_enabled, skip_mode_refs[2];
+ int warp_motion;
+ int reduced_txtp_set;
+ Dav1dWarpedMotionParams gmv[DAV1D_REFS_PER_FRAME];
+} Dav1dFrameHeader;
+
+#endif /* DAV1D_HEADERS_H */
diff --git a/src/third_party/libdav1d/include/dav1d/picture.h b/src/third_party/libdav1d/include/dav1d/picture.h
index 08746f3..68ef6d5 100644
--- a/src/third_party/libdav1d/include/dav1d/picture.h
+++ b/src/third_party/libdav1d/include/dav1d/picture.h
@@ -1,141 +1,144 @@
-/*
- * Copyright © 2018, VideoLAN and dav1d authors
- * Copyright © 2018, Two Orioles, LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DAV1D_PICTURE_H
-#define DAV1D_PICTURE_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "common.h"
-#include "headers.h"
-
-/* Number of bytes to align AND pad picture memory buffers by, so that SIMD
- * implementations can over-read by a few bytes, and use aligned read/write
- * instructions. */
-#define DAV1D_PICTURE_ALIGNMENT 64
-
-typedef struct Dav1dPictureParameters {
- int w; ///< width (in pixels)
- int h; ///< height (in pixels)
- enum Dav1dPixelLayout layout; ///< format of the picture
- int bpc; ///< bits per pixel component (8 or 10)
-} Dav1dPictureParameters;
-
-typedef struct Dav1dPicture {
- Dav1dSequenceHeader *seq_hdr;
- Dav1dFrameHeader *frame_hdr;
-
- /**
- * Pointers to planar image data (Y is [0], U is [1], V is [2]). The data
- * should be bytes (for 8 bpc) or words (for 10 bpc). In case of words
- * containing 10 bpc image data, the pixels should be located in the LSB
- * bits, so that values range between [0, 1023]; the upper bits should be
- * zero'ed out.
- */
- void *data[3];
-
- /**
- * Number of bytes between 2 lines in data[] for luma [0] or chroma [1].
- */
- ptrdiff_t stride[2];
-
- Dav1dPictureParameters p;
- Dav1dDataProps m;
-
- /**
- * High Dynamic Range Content Light Level metadata applying to this picture,
- * as defined in section 5.8.3 and 6.7.3
- */
- Dav1dContentLightLevel *content_light;
- /**
- * High Dynamic Range Mastering Display Color Volume metadata applying to
- * this picture, as defined in section 5.8.4 and 6.7.4
- */
- Dav1dMasteringDisplay *mastering_display;
- /**
- * ITU-T T.35 metadata as defined in section 5.8.2 and 6.7.2
- */
- Dav1dITUTT35 *itut_t35;
-
- uintptr_t reserved[4]; ///< reserved for future use
-
- struct Dav1dRef *frame_hdr_ref, *seq_hdr_ref; ///< Frame parameter allocation origins
- struct Dav1dRef *content_light_ref, *mastering_display_ref, *itut_t35_ref; ///< Metadata allocation origins
- uintptr_t reserved_ref[4]; ///< reserved for future use
- struct Dav1dRef *ref; ///< Frame data allocation origin
-
- void *allocator_data; ///< pointer managed by the allocator
-} Dav1dPicture;
-
-typedef struct Dav1dPicAllocator {
- void *cookie; ///< custom data to pass to the allocator callbacks.
- /**
- * Allocate the picture buffer based on the Dav1dPictureParameters.
- *
- * The data[0], data[1] and data[2] must be DAV1D_PICTURE_ALIGNMENT byte
- * aligned and with a pixel width/height multiple of 128 pixels. Any
- * allocated memory area should also be padded by DAV1D_PICTURE_ALIGNMENT
- * bytes.
- * data[1] and data[2] must share the same stride[1].
- *
- * This function will be called on the main thread (the thread which calls
- * dav1d_get_picture()).
- *
- * @param pic The picture to allocate the buffer for. The callback needs to
- * fill the picture data[0], data[1], data[2], stride[0] and
- * stride[1].
- * The allocator can fill the pic allocator_data pointer with
- * a custom pointer that will be passed to
- * release_picture_callback().
- * @param cookie Custom pointer passed to all calls.
- *
- * @note No fields other than data, stride and allocator_data must be filled
- * by this callback.
- * @return 0 on success. A negative DAV1D_ERR value on error.
- */
- int (*alloc_picture_callback)(Dav1dPicture *pic, void *cookie);
- /**
- * Release the picture buffer.
- *
- * If frame threading is used, this function may be called by the main
- * thread (the thread which calls dav1d_get_picture()) or any of the frame
- * threads and thus must be thread-safe. If frame threading is not used,
- * this function will only be called on the main thread.
- *
- * @param pic The picture that was filled by alloc_picture_callback().
- * @param cookie Custom pointer passed to all calls.
- */
- void (*release_picture_callback)(Dav1dPicture *pic, void *cookie);
-} Dav1dPicAllocator;
-
-/**
- * Release reference to a picture.
- */
-DAV1D_API void dav1d_picture_unref(Dav1dPicture *p);
-
-#endif /* DAV1D_PICTURE_H */
+/*
+ * Copyright © 2018-2020, VideoLAN and dav1d authors
+ * Copyright © 2018, Two Orioles, LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DAV1D_PICTURE_H
+#define DAV1D_PICTURE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "common.h"
+#include "headers.h"
+
+/* Number of bytes to align AND pad picture memory buffers by, so that SIMD
+ * implementations can over-read by a few bytes, and use aligned read/write
+ * instructions. */
+#define DAV1D_PICTURE_ALIGNMENT 64
+
+typedef struct Dav1dPictureParameters {
+ int w; ///< width (in pixels)
+ int h; ///< height (in pixels)
+ enum Dav1dPixelLayout layout; ///< format of the picture
+ int bpc; ///< bits per pixel component (8 or 10)
+} Dav1dPictureParameters;
+
+typedef struct Dav1dPicture {
+ Dav1dSequenceHeader *seq_hdr;
+ Dav1dFrameHeader *frame_hdr;
+
+ /**
+ * Pointers to planar image data (Y is [0], U is [1], V is [2]). The data
+ * should be bytes (for 8 bpc) or words (for 10 bpc). In case of words
+ * containing 10 bpc image data, the pixels should be located in the LSB
+ * bits, so that values range between [0, 1023]; the upper bits should be
+ * zero'ed out.
+ */
+ void *data[3];
+
+ /**
+ * Number of bytes between 2 lines in data[] for luma [0] or chroma [1].
+ */
+ ptrdiff_t stride[2];
+
+ Dav1dPictureParameters p;
+ Dav1dDataProps m;
+
+ /**
+ * High Dynamic Range Content Light Level metadata applying to this picture,
+ * as defined in section 5.8.3 and 6.7.3
+ */
+ Dav1dContentLightLevel *content_light;
+ /**
+ * High Dynamic Range Mastering Display Color Volume metadata applying to
+ * this picture, as defined in section 5.8.4 and 6.7.4
+ */
+ Dav1dMasteringDisplay *mastering_display;
+ /**
+ * ITU-T T.35 metadata as defined in section 5.8.2 and 6.7.2
+ */
+ Dav1dITUTT35 *itut_t35;
+
+ uintptr_t reserved[4]; ///< reserved for future use
+
+ struct Dav1dRef *frame_hdr_ref; ///< Dav1dFrameHeader allocation origin
+ struct Dav1dRef *seq_hdr_ref; ///< Dav1dSequenceHeader allocation origin
+ struct Dav1dRef *content_light_ref; ///< Dav1dContentLightLevel allocation origin
+ struct Dav1dRef *mastering_display_ref; ///< Dav1dMasteringDisplay allocation origin
+ struct Dav1dRef *itut_t35_ref; ///< Dav1dITUTT35 allocation origin
+ uintptr_t reserved_ref[4]; ///< reserved for future use
+ struct Dav1dRef *ref; ///< Frame data allocation origin
+
+ void *allocator_data; ///< pointer managed by the allocator
+} Dav1dPicture;
+
+typedef struct Dav1dPicAllocator {
+ void *cookie; ///< custom data to pass to the allocator callbacks.
+ /**
+ * Allocate the picture buffer based on the Dav1dPictureParameters.
+ *
+ * The data[0], data[1] and data[2] must be DAV1D_PICTURE_ALIGNMENT byte
+ * aligned and with a pixel width/height multiple of 128 pixels. Any
+ * allocated memory area should also be padded by DAV1D_PICTURE_ALIGNMENT
+ * bytes.
+ * data[1] and data[2] must share the same stride[1].
+ *
+ * This function will be called on the main thread (the thread which calls
+ * dav1d_get_picture()).
+ *
+ * @param pic The picture to allocate the buffer for. The callback needs to
+ * fill the picture data[0], data[1], data[2], stride[0] and
+ * stride[1].
+ * The allocator can fill the pic allocator_data pointer with
+ * a custom pointer that will be passed to
+ * release_picture_callback().
+ * @param cookie Custom pointer passed to all calls.
+ *
+ * @note No fields other than data, stride and allocator_data must be filled
+ * by this callback.
+ * @return 0 on success. A negative DAV1D_ERR value on error.
+ */
+ int (*alloc_picture_callback)(Dav1dPicture *pic, void *cookie);
+ /**
+ * Release the picture buffer.
+ *
+ * If frame threading is used, this function may be called by the main
+ * thread (the thread which calls dav1d_get_picture()) or any of the frame
+ * threads and thus must be thread-safe. If frame threading is not used,
+ * this function will only be called on the main thread.
+ *
+ * @param pic The picture that was filled by alloc_picture_callback().
+ * @param cookie Custom pointer passed to all calls.
+ */
+ void (*release_picture_callback)(Dav1dPicture *pic, void *cookie);
+} Dav1dPicAllocator;
+
+/**
+ * Release reference to a picture.
+ */
+DAV1D_API void dav1d_picture_unref(Dav1dPicture *p);
+
+#endif /* DAV1D_PICTURE_H */
diff --git a/src/third_party/libdav1d/platforms/linux-x64/libdav1d.a b/src/third_party/libdav1d/platforms/linux-x64/libdav1d.a
index bb3473f..5189375 100644
--- a/src/third_party/libdav1d/platforms/linux-x64/libdav1d.a
+++ b/src/third_party/libdav1d/platforms/linux-x64/libdav1d.a
Binary files differ
diff --git a/src/tools/download_from_gcs.py b/src/tools/download_from_gcs.py
index 9c79dfb..4a49502 100755
--- a/src/tools/download_from_gcs.py
+++ b/src/tools/download_from_gcs.py
@@ -57,11 +57,13 @@
context = create_default_context()
try:
- res = urllib.urlopen(url, context=context) if context else urllib.urlopen(url)
+ res = urllib.urlopen(
+ url, context=context) if context else urllib.urlopen(url)
except urllib.URLError:
- from ssl import _create_unverified_context
+ from ssl import _create_unverified_context # pylint:disable=import-outside-toplevel
context = _create_unverified_context()
- res = urllib.urlopen(url, context=context) if context else urllib.urlopen(url)
+ res = urllib.urlopen(
+ url, context=context) if context else urllib.urlopen(url)
if not res:
logging.error('Could not reach %s', url)
diff --git a/src/tools/download_from_gcs_test.py b/src/tools/download_from_gcs_test.py
index 6c5b4b8..65a0eaf 100755
--- a/src/tools/download_from_gcs_test.py
+++ b/src/tools/download_from_gcs_test.py
@@ -18,7 +18,7 @@
import tempfile
import unittest
-import tools.download_from_gcs as download_from_gcs
+from tools import download_from_gcs
_BUCKET = 'chromium-clang-format'
_HASH_FILE_EXT = '.sha1'
@@ -52,7 +52,7 @@
def setUp(self):
self.test_file = os.path.join(_TEST_PATH, _TEST_FILE)
- self.output_directory = tempfile.TemporaryDirectory()
+ self.output_directory = tempfile.TemporaryDirectory() # pylint:disable=consider-using-with
self.output_file = os.path.join(self.output_directory.name, 'output')
self.bucket = _BUCKET
@@ -74,7 +74,7 @@
def setUp(self):
self.test_directory = os.path.join(_TEST_PATH, _TEST_DIRECTORY)
- self.output_directory = tempfile.TemporaryDirectory()
+ self.output_directory = tempfile.TemporaryDirectory() # pylint:disable=consider-using-with
self.bucket = _BUCKET
def tearDown(self):
diff --git a/src/tools/gyp/pylib/gyp/msvs_emulation.py b/src/tools/gyp/pylib/gyp/msvs_emulation.py
index 84f4ff6..ba2812c 100755
--- a/src/tools/gyp/pylib/gyp/msvs_emulation.py
+++ b/src/tools/gyp/pylib/gyp/msvs_emulation.py
@@ -747,7 +747,8 @@
'cell_.*',
'sn_.*',
'sce_.*',
- 'is_docker', # TODO(agmenon): needed for ninja to invoke docker-specific logic
+ 'is_docker', # needed for ninja to invoke docker-specific logic
+ 'is_ci', # needed for ninja to exlcude some logic on GKE
)
env = {}
for line in output_of_set.splitlines():