Import Cobalt 13.95843
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index 96e2ce3..6b70bdc 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-95615
\ No newline at end of file
+95843
\ No newline at end of file
diff --git a/src/cobalt/build/config/base.gni b/src/cobalt/build/config/base.gni
index 2bc87b6..834371c 100644
--- a/src/cobalt/build/config/base.gni
+++ b/src/cobalt/build/config/base.gni
@@ -241,7 +241,7 @@
# The URL of default build time splash screen - see
# cobalt/doc/splash_screen.md for information about this.
if (!defined(fallback_splash_screen_url)) {
- fallback_splash_screen_url = "h5vcc-embedded://youtube_splash_screen.html"
+ fallback_splash_screen_url = "none"
}
# Cache parameters
diff --git a/src/cobalt/build/config/base.gypi b/src/cobalt/build/config/base.gypi
index 110e70d..77cba3a 100644
--- a/src/cobalt/build/config/base.gypi
+++ b/src/cobalt/build/config/base.gypi
@@ -291,7 +291,7 @@
# The URL of default build time splash screen - see
# cobalt/doc/splash_screen.md for information about this.
- 'fallback_splash_screen_url%': 'h5vcc-embedded://youtube_splash_screen.html',
+ 'fallback_splash_screen_url%': 'none',
# Cache parameters
diff --git a/src/cobalt/media/base/sbplayer_pipeline.cc b/src/cobalt/media/base/sbplayer_pipeline.cc
index 5752961..bf397d8 100644
--- a/src/cobalt/media/base/sbplayer_pipeline.cc
+++ b/src/cobalt/media/base/sbplayer_pipeline.cc
@@ -227,6 +227,7 @@
scoped_ptr<StarboardPlayer> player_;
bool suspended_;
bool stopped_;
+ bool ended_;
VideoDumper video_dumper_;
@@ -250,6 +251,7 @@
set_bounds_helper_(new SbPlayerSetBoundsHelper),
suspended_(false),
stopped_(false),
+ ended_(false),
video_dumper_(kVideoDumpFileName) {}
SbPlayerPipeline::~SbPlayerPipeline() { DCHECK(!player_); }
@@ -364,6 +366,7 @@
}
player_->PrepareForSeek();
+ ended_ = false;
DCHECK(seek_cb_.is_null());
DCHECK(!seek_cb.is_null());
@@ -429,6 +432,9 @@
if (!player_) {
return TimeDelta();
}
+ if (ended_) {
+ return duration_;
+ }
base::TimeDelta media_time;
player_->GetInfo(&statistics_.video_frames_decoded,
&statistics_.video_frames_dropped, &media_time);
@@ -826,6 +832,7 @@
break;
case kSbPlayerStateEndOfStream:
ended_cb_.Run(PIPELINE_OK);
+ ended_ = true;
break;
case kSbPlayerStateDestroyed:
break;
diff --git a/src/cobalt/renderer/rasterizer/lib/exported/graphics.h b/src/cobalt/renderer/rasterizer/lib/exported/graphics.h
index 7b1d4bd..69e2125 100644
--- a/src/cobalt/renderer/rasterizer/lib/exported/graphics.h
+++ b/src/cobalt/renderer/rasterizer/lib/exported/graphics.h
@@ -14,6 +14,12 @@
// All imported functions defined below MUST be implemented by client
// applications.
+// All of callbacks in here will happen on Cobalt's rasterization thread
+// (i.e. the thread which owns the GL context). To guarantee no callbacks
+// are missed, all callbacks should be set before the rasterization thread
+// has started. Any other functions in here (e.g.
+// CbLibGrapicsGetMainTextureHandle) are also not thread-safe and should only be
+// invoked on the rasterization thread during one of the provided callbacks.
#ifndef COBALT_RENDERER_RASTERIZER_LIB_EXPORTED_GRAPHICS_H_
#define COBALT_RENDERER_RASTERIZER_LIB_EXPORTED_GRAPHICS_H_
@@ -26,8 +32,7 @@
#endif
typedef void (*CbLibGraphicsContextCreatedCallback)(void* context);
-typedef void (*CbLibGraphicsBeginRenderFrameCallback)(
- void* context, intptr_t render_tree_texture_handle);
+typedef void (*CbLibGraphicsBeginRenderFrameCallback)(void* context);
typedef void (*CbLibGraphicsEndRenderFrameCallback)(void* context);
// Sets a callback which will be called from the rasterization thread once the
@@ -36,12 +41,19 @@
void* context, CbLibGraphicsContextCreatedCallback callback);
// Sets a callback which will be called as often as the platform can swap
-// buffers from the rasterization thread. |render_tree_texture_handle| which is
-// provided to the callback corresponds to a GLint texture ID for the current
-// RenderTree.
+// buffers from the rasterization thread.
SB_EXPORT_PLATFORM void CbLibGraphicsSetBeginRenderFrameCallback(
void* context, CbLibGraphicsBeginRenderFrameCallback callback);
+// Returns the texture ID for the current RenderTree. This should be
+// re-retrieved each frame in the event that the underlying texture has
+// changed. This method will return 0 if there is not yet a valid texture ID.
+// This will never return anything other than 0 until after the first frame is
+// started / the CbLibGraphicsBeginRenderFrameCallback is invoked (assuming the
+// callback is set). This is not thread-safe and should be invoked on the
+// rasterization thread only.
+SB_EXPORT_PLATFORM intptr_t CbLibGrapicsGetMainTextureHandle();
+
// Sets a callback which will be called at the end of rendering, after swap
// buffers has been called.
SB_EXPORT_PLATFORM void CbLibGraphicsSetEndRenderFrameCallback(
diff --git a/src/cobalt/renderer/rasterizer/lib/external_rasterizer.cc b/src/cobalt/renderer/rasterizer/lib/external_rasterizer.cc
index 00dc1ee..fb2acaa 100644
--- a/src/cobalt/renderer/rasterizer/lib/external_rasterizer.cc
+++ b/src/cobalt/renderer/rasterizer/lib/external_rasterizer.cc
@@ -126,6 +126,8 @@
EndRenderFrame::LazyCallback g_end_render_frame_callback =
LAZY_INSTANCE_INITIALIZER;
+ExternalRasterizer::Impl* g_external_rasterizer_impl = nullptr;
+
} // namespace
namespace cobalt {
@@ -148,6 +150,8 @@
void MakeCurrent() { hardware_rasterizer_.MakeCurrent(); }
+ intptr_t GetMainTextureHandle();
+
private:
void RenderOffscreenVideo(render_tree::FilterNode* map_to_mesh_filter_node);
@@ -196,6 +200,8 @@
video_projection_type_(kCbLibVideoProjectionTypeNone),
video_stereo_mode_(render_tree::StereoMode::kMono),
video_texture_rgb_(0) {
+ CHECK(!g_external_rasterizer_impl);
+ g_external_rasterizer_impl = this;
options_.flags = Rasterizer::kSubmitFlags_Clear;
graphics_context_->MakeCurrent();
@@ -322,8 +328,7 @@
// TODO: Allow clients to specify arbitrary subtrees to render into
// different textures?
- const intptr_t texture_handle = main_texture_->GetPlatformHandle();
- g_begin_render_frame_callback.Get().Run(texture_handle);
+ g_begin_render_frame_callback.Get().Run();
graphics_context_->SwapBuffers(render_target_egl);
g_end_render_frame_callback.Get().Run();
}
@@ -332,6 +337,10 @@
return hardware_rasterizer_.GetResourceProvider();
}
+intptr_t ExternalRasterizer::Impl::GetMainTextureHandle() {
+ return main_texture_->GetPlatformHandle();
+}
+
void ExternalRasterizer::Impl::RenderOffscreenVideo(
render_tree::FilterNode* map_to_mesh_filter_node) {
DCHECK(map_to_mesh_filter_node);
@@ -483,3 +492,14 @@
callback ? base::Bind(callback, context)
: base::Bind(&EndRenderFrame::DefaultImplementation);
}
+
+intptr_t CbLibGrapicsGetMainTextureHandle() {
+ DCHECK(g_external_rasterizer_impl);
+ if (!g_external_rasterizer_impl) {
+ LOG(WARNING) << __FUNCTION__
+ << "ExternalRasterizer not yet created; unable to progress.";
+ return 0;
+ }
+
+ return g_external_rasterizer_impl->GetMainTextureHandle();
+}
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 6882f4a..5489d25 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
@@ -312,8 +312,9 @@
(*player_worker_.*update_player_state_cb_)(kSbPlayerStateEndOfStream);
}
- scoped_refptr<VideoFrame> frame =
- video_renderer_->GetCurrentFrame(audio_renderer_->GetCurrentTime());
+ scoped_refptr<VideoFrame> frame = video_renderer_->GetCurrentFrame(
+ audio_renderer_->GetCurrentTime(),
+ audio_renderer_->IsEndOfStreamPlayed());
player_worker_->UpdateDroppedVideoFrames(
video_renderer_->GetDroppedFrames());
diff --git a/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.cc b/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.cc
index badd1f1..65f9bc9 100644
--- a/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.cc
+++ b/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.cc
@@ -87,7 +87,8 @@
}
scoped_refptr<VideoFrame> VideoRendererImpl::GetCurrentFrame(
- SbMediaTime media_time) {
+ SbMediaTime media_time,
+ bool audio_eos_reached) {
SB_DCHECK(thread_checker_.CalledOnValidThread());
ScopedLock lock(mutex_);
@@ -103,6 +104,12 @@
frames_.pop_front();
}
+ if (audio_eos_reached) {
+ while (frames_.size() > 1) {
+ frames_.pop_back();
+ }
+ }
+
last_displayed_frame_ = frames_.front();
return last_displayed_frame_;
}
diff --git a/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.h b/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.h
index c69aa8b..58e8fd6 100644
--- a/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.h
+++ b/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.h
@@ -49,7 +49,8 @@
void Seek(SbMediaTime seek_to_pts) SB_OVERRIDE;
- scoped_refptr<VideoFrame> GetCurrentFrame(SbMediaTime media_time) SB_OVERRIDE;
+ scoped_refptr<VideoFrame> GetCurrentFrame(SbMediaTime media_time,
+ bool audio_eos_reached) SB_OVERRIDE;
bool IsEndOfStreamWritten() const SB_OVERRIDE {
return end_of_stream_written_;
diff --git a/src/starboard/shared/starboard/player/filter/video_renderer_internal.h b/src/starboard/shared/starboard/player/filter/video_renderer_internal.h
index 85906bf..5f1a284 100644
--- a/src/starboard/shared/starboard/player/filter/video_renderer_internal.h
+++ b/src/starboard/shared/starboard/player/filter/video_renderer_internal.h
@@ -39,7 +39,8 @@
virtual void WriteSample(const scoped_refptr<InputBuffer>& input_buffer) = 0;
virtual void WriteEndOfStream() = 0;
virtual void Seek(SbMediaTime seek_to_pts) = 0;
- virtual scoped_refptr<VideoFrame> GetCurrentFrame(SbMediaTime media_time) = 0;
+ virtual scoped_refptr<VideoFrame> GetCurrentFrame(SbMediaTime media_time,
+ bool audio_eos_reached) = 0;
virtual bool IsEndOfStreamWritten() const = 0;
virtual bool IsEndOfStreamPlayed() const = 0;
virtual bool CanAcceptMoreData() const = 0;
diff --git a/src/third_party/mozjs-45/js/src/gc/GCTrace.cpp b/src/third_party/mozjs-45/js/src/gc/GCTrace.cpp
index 48d9e7c..747e6ab 100644
--- a/src/third_party/mozjs-45/js/src/gc/GCTrace.cpp
+++ b/src/third_party/mozjs-45/js/src/gc/GCTrace.cpp
@@ -4,7 +4,155 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifdef JS_GC_TRACE
+#if defined(COBALT) && defined(COBALT_JS_GC_TRACE)
+
+#include "gc/GCTrace.h"
+#include "jscntxt.h"
+#include "jsfriendapi.h"
+#include "vm/Runtime.h"
+
+#include "nb/thread_local_object.h"
+#include "starboard/log.h"
+
+#include <unordered_map>
+
+namespace js {
+namespace gc {
+
+namespace {
+
+// A simple struct to bundle up both when and where a |GCThing| was allocated.
+struct AllocationInfo {
+ std::string stack;
+ SbTimeMonotonic time;
+};
+
+// A simple struct to bundle up all information relevant to the current thread
+// that we are tracing allocations for, which includes a mapping from |Cell|s
+// to their corresponding |AllocationInfo|, as well as the last time that we
+// dumped |thing2info|.
+struct TraceData {
+ std::unordered_map<Cell*, AllocationInfo> thing2info;
+ SbTimeMonotonic last_dump_time;
+};
+nb::ThreadLocalObject<TraceData> tlo_trace_data;
+
+const SbTimeMonotonic kDumpInterval = 15 * 60 * 1000 * 1000;
+const int kStackSize = 10;
+
+// Return the top first |n| stack frames of |cx| as a single string. |cx|
+// must not be NULL.
+std::string DumpBacktrace(JSContext* cx, int n) {
+ SB_DCHECK(cx != NULL);
+
+ Sprinter sprinter(cx);
+ sprinter.init();
+ size_t depth = 0;
+
+ for (AllFramesIter it(cx); !it.done(); ++it, ++depth) {
+ if (depth > n) {
+ break;
+ }
+
+ const char* filename = JS_GetScriptFilename(it.script());
+ unsigned column = 0;
+ unsigned line = PCToLineNumber(it.script(), it.pc(), &column);
+
+ if (depth != 0) {
+ sprinter.printf(" ");
+ }
+
+ sprinter.printf("#%d %s:%d:%d", depth, filename, line, column);
+ }
+
+ return std::string(sprinter.string(),
+ sprinter.string() + sprinter.getOffset());
+}
+
+// Add |thing| and its corresponding |AllocationInfo| to |thing2info|.
+void StartTrackingThing(Cell* thing) {
+ if (!thing) {
+ return;
+ }
+
+ auto* rt = thing->runtimeFromMainThread();
+ auto* cx = rt->contextList.getFirst();
+ // JavaScript allocations can still happen during the brief period of time
+ // in between when we destroy the sole |JSContext| and then finally destroy
+ // the entire |JSRuntime|. They should be counted as having had no stack.
+ auto stack = cx ? DumpBacktrace(cx, kStackSize) : "";
+ auto& thing2info = tlo_trace_data.GetOrCreate()->thing2info;
+ thing2info[thing] = {stack, SbTimeGetMonotonicNow()};
+}
+
+// Remove |thing| from |tlo_thing2info|. |tlo_thing2info| is expected to
+// actually contain |thing|, and will error if it does not.
+void StopTrackingThing(Cell* thing) {
+ if (!thing) {
+ return;
+ }
+
+ auto& thing2info = tlo_trace_data.GetOrCreate()->thing2info;
+ auto erased_count = thing2info.erase(thing);
+ SB_DCHECK(erased_count == 1);
+}
+
+// Dump the current state of the heap if |kDumpInterval| time has passed since
+// the last dump.
+void MaybeDump() {
+ auto& trace_data = *tlo_trace_data.GetOrCreate();
+ auto now = SbTimeGetMonotonicNow();
+ auto diff = now - trace_data.last_dump_time;
+ if (diff > kDumpInterval) {
+ trace_data.last_dump_time = now;
+ auto thread_id = SbThreadGetId();
+ SB_LOG(INFO) << "BEGIN_HEAP_DUMP: " << thread_id << " " << now;
+ for (const auto& pair : trace_data.thing2info) {
+ SB_LOG(INFO) << "HEAP_DUMP: " << thread_id << " "
+ << static_cast<void*>(pair.first) << " "
+ << pair.second.time << " " << pair.second.stack;
+ }
+ SB_LOG(INFO) << "END_HEAP_DUMP: " << thread_id << " " << now;
+ }
+}
+
+} // namespace
+
+bool InitTrace(GCRuntime& gc) { return true; }
+
+void FinishTrace() {}
+
+bool TraceEnabled() { return true; }
+
+void TraceNurseryAlloc(Cell* thing, size_t size) {
+ // Don't do anything. We will trace |thing| if it ends up getting
+ // tenured.
+}
+
+void TraceTenuredAlloc(Cell* thing, AllocKind kind) {
+ StartTrackingThing(thing);
+}
+
+void TraceCreateObject(JSObject* object) {}
+
+void TraceMinorGCStart() {}
+
+void TracePromoteToTenured(Cell* src, Cell* dst) { StartTrackingThing(dst); }
+
+void TraceMinorGCEnd() { MaybeDump(); }
+
+void TraceMajorGCStart() {}
+
+void TraceTenuredFinalize(Cell* thing) { StopTrackingThing(thing); }
+
+void TraceMajorGCEnd() { MaybeDump(); }
+
+void TraceTypeNewScript(js::ObjectGroup* group) {}
+
+} // namespace gc
+} // namespace js
+
+#elif defined(JS_GC_TRACE)
#include "gc/GCTrace.h"
diff --git a/src/third_party/mozjs-45/js/src/gc/GCTrace.h b/src/third_party/mozjs-45/js/src/gc/GCTrace.h
index c34f6c5..30c2129 100644
--- a/src/third_party/mozjs-45/js/src/gc/GCTrace.h
+++ b/src/third_party/mozjs-45/js/src/gc/GCTrace.h
@@ -15,7 +15,7 @@
namespace gc {
-#ifdef JS_GC_TRACE
+#if (defined(COBALT) && defined(COBALT_JS_GC_TRACE)) || defined(JS_GC_TRACE)
extern bool InitTrace(GCRuntime& gc);
extern void FinishTrace();
diff --git a/src/third_party/mozjs-45/mozjs-45.gyp b/src/third_party/mozjs-45/mozjs-45.gyp
index 4bc4c17..54fe066 100644
--- a/src/third_party/mozjs-45/mozjs-45.gyp
+++ b/src/third_party/mozjs-45/mozjs-45.gyp
@@ -34,6 +34,9 @@
# See vm/Probes.h for different values. This was the value set by the
# configure script when building for linux-release.
'JS_DEFAULT_JITREPORT_GRANULARITY=3',
+ # |COBALT_JS_GC_TRACE| can be set here to enable the JSGCThingTracer,
+ # which logs GCThings that are alive in the JavaScript heap, along with
+ # where each thing was allocated, every 15 minutes.
],
'common_include_dirs': [
'<(DEPTH)/third_party/mozjs-45/js/src',