Import Cobalt 9.174384 Change-Id: I66ce364c297afdd454e8db4e2d947f070dbf2f8b
diff --git a/src/base/message_pump_io_starboard.cc b/src/base/message_pump_io_starboard.cc index e08ddb8..bb1b1de 100644 --- a/src/base/message_pump_io_starboard.cc +++ b/src/base/message_pump_io_starboard.cc
@@ -28,7 +28,8 @@ namespace base { MessagePumpIOStarboard::SocketWatcher::SocketWatcher() - : socket_(kSbSocketInvalid), + : interests_(kSbSocketWaiterInterestNone), + socket_(kSbSocketInvalid), pump_(NULL), watcher_(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {} @@ -48,6 +49,7 @@ } pump_ = NULL; watcher_ = NULL; + interests_ = kSbSocketWaiterInterestNone; return result; } @@ -147,6 +149,7 @@ controller->Init(socket, persistent); controller->set_watcher(delegate); controller->set_pump(this); + controller->set_interests(interests); return true; }
diff --git a/src/base/message_pump_io_starboard.h b/src/base/message_pump_io_starboard.h index c840181..028115f 100644 --- a/src/base/message_pump_io_starboard.h +++ b/src/base/message_pump_io_starboard.h
@@ -83,6 +83,7 @@ SbSocket Release(); int interests() const { return interests_; } + void set_interests(int interests) { interests_ = interests; } void set_pump(MessagePumpIOStarboard* pump) { pump_ = pump; } MessagePumpIOStarboard* pump() const { return pump_; }
diff --git a/src/cobalt/browser/application.h b/src/cobalt/browser/application.h index e700d83..776d48b 100644 --- a/src/cobalt/browser/application.h +++ b/src/cobalt/browser/application.h
@@ -143,7 +143,7 @@ base::CVal<base::cval::SizeInBytes, base::CValPublic> exe_memory; #endif - base::CVal<int64> app_start_time; + base::CVal<int64, base::CValPublic> app_start_time; base::CVal<base::TimeDelta, base::CValPublic> app_lifetime; };
diff --git a/src/cobalt/browser/browser_module.h b/src/cobalt/browser/browser_module.h index 5712937..8e6b08d 100644 --- a/src/cobalt/browser/browser_module.h +++ b/src/cobalt/browser/browser_module.h
@@ -312,10 +312,10 @@ // The time when a URL navigation starts. This is recorded after the previous // WebModule is destroyed. - base::CVal<int64> navigate_time_; + base::CVal<int64, base::CValPublic> navigate_time_; // The time when the WebModule's Window.onload event is fired. - base::CVal<int64> on_load_event_time_; + base::CVal<int64, base::CValPublic> on_load_event_time_; #if defined(ENABLE_DEBUG_CONSOLE) // Possibly null, but if not, will contain a reference to an instance of
diff --git a/src/cobalt/browser/splash_screen.cc b/src/cobalt/browser/splash_screen.cc index 0ba834c..6df2dbe 100644 --- a/src/cobalt/browser/splash_screen.cc +++ b/src/cobalt/browser/splash_screen.cc
@@ -22,7 +22,11 @@ // Static const char SplashScreen::Options::kDefaultSplashScreenURL[] = - "h5vcc-embedded://splash_screen.html"; +#if defined(COBALT_USE_YOUTUBE_SPLASH_SCREEN) + "h5vcc-embedded://youtube_splash_screen.html"; +#else + "h5vcc-embedded://black_splash_screen.html"; +#endif // COBALT_USE_YOUTUBE_SPLASH_SCREEN SplashScreen::SplashScreen( const WebModule::OnRenderTreeProducedCallback&
diff --git a/src/cobalt/browser/web_module.cc b/src/cobalt/browser/web_module.cc index b575c58..3183d8b 100644 --- a/src/cobalt/browser/web_module.cc +++ b/src/cobalt/browser/web_module.cc
@@ -226,6 +226,9 @@ } } + void OnStartDispatchEvent(const scoped_refptr<dom::Event>& event); + void OnStopDispatchEvent(const scoped_refptr<dom::Event>& event); + // Thread checker ensures all calls to the WebModule are made from the same // thread that it is created in. base::ThreadChecker thread_checker_; @@ -499,6 +502,9 @@ data.window_close_callback, data.window_minimize_callback, data.system_window_, data.options.input_poller, media_session_client_->GetMediaSession(), + base::Bind(&WebModule::Impl::OnStartDispatchEvent, + base::Unretained(this)), + base::Bind(&WebModule::Impl::OnStopDispatchEvent, base::Unretained(this)), data.options.csp_insecure_allowed_token, data.dom_max_element_depth); DCHECK(window_); @@ -614,17 +620,11 @@ scoped_refptr<dom::KeyboardEvent> keyboard_event( new dom::KeyboardEvent(event)); - web_module_stat_tracker_->OnStartInjectEvent(keyboard_event); - if (element) { element->DispatchEvent(keyboard_event); } else { window_->InjectEvent(keyboard_event); } - - web_module_stat_tracker_->OnEndInjectEvent( - window_->HasPendingAnimationFrameCallbacks(), - layout_manager_->IsRenderTreePending()); } void WebModule::Impl::ExecuteJavascript( @@ -753,6 +753,18 @@ } } +void WebModule::Impl::OnStartDispatchEvent( + const scoped_refptr<dom::Event>& event) { + web_module_stat_tracker_->OnStartDispatchEvent(event); +} + +void WebModule::Impl::OnStopDispatchEvent( + const scoped_refptr<dom::Event>& event) { + web_module_stat_tracker_->OnStopDispatchEvent( + event, window_->HasPendingAnimationFrameCallbacks(), + layout_manager_->IsRenderTreePending()); +} + void WebModule::Impl::SuspendLoaders() { TRACE_EVENT0("cobalt::browser", "WebModule::Impl::SuspendLoaders()");
diff --git a/src/cobalt/browser/web_module_stat_tracker.cc b/src/cobalt/browser/web_module_stat_tracker.cc index 4151969..28905c9 100644 --- a/src/cobalt/browser/web_module_stat_tracker.cc +++ b/src/cobalt/browser/web_module_stat_tracker.cc
@@ -34,6 +34,7 @@ layout_stat_tracker_(new layout::LayoutStatTracker(name)), should_track_event_stats_(should_track_event_stats), current_event_type_(kEventTypeInvalid), + current_event_dispatched_event_(NULL), name_(name), event_is_processing_(StringPrintf("Event.%s.IsProcessing", name.c_str()), false, "Nonzero when an event is being processed.") { @@ -56,7 +57,7 @@ WebModuleStatTracker::~WebModuleStatTracker() { EndCurrentEvent(false); } -void WebModuleStatTracker::OnStartInjectEvent( +void WebModuleStatTracker::OnStartDispatchEvent( const scoped_refptr<dom::Event>& event) { if (!should_track_event_stats_) { return; @@ -81,28 +82,30 @@ if (current_event_type_ != kEventTypeInvalid) { event_is_processing_ = true; event_start_time_ = base::TimeTicks::Now(); + current_event_dispatched_event_ = event; dom_stat_tracker_->OnStartEvent(); layout_stat_tracker_->OnStartEvent(); stop_watch_durations_[kStopWatchTypeEvent] = base::TimeDelta(); - stop_watch_durations_[kStopWatchTypeInjectEvent] = base::TimeDelta(); + stop_watch_durations_[kStopWatchTypeDispatchEvent] = base::TimeDelta(); stop_watches_[kStopWatchTypeEvent].Start(); - stop_watches_[kStopWatchTypeInjectEvent].Start(); + stop_watches_[kStopWatchTypeDispatchEvent].Start(); } } -void WebModuleStatTracker::OnEndInjectEvent( +void WebModuleStatTracker::OnStopDispatchEvent( + const scoped_refptr<dom::Event>& event, bool are_animation_frame_callbacks_pending, bool is_new_render_tree_pending) { - // If the injection isn't currently being timed, then this event injection - // isn't being tracked. Simply return. - if (!stop_watches_[kStopWatchTypeInjectEvent].IsCounting()) { + // Verify that this dispatched event is the one currently being tracked. + if (event != current_event_dispatched_event_) { return; } - stop_watches_[kStopWatchTypeInjectEvent].Stop(); + current_event_dispatched_event_ = NULL; + stop_watches_[kStopWatchTypeDispatchEvent].Stop(); if (!are_animation_frame_callbacks_pending && !is_new_render_tree_pending) { EndCurrentEvent(false); @@ -119,7 +122,9 @@ void WebModuleStatTracker::OnRenderTreeProduced() { EndCurrentEvent(true); } WebModuleStatTracker::EventStats::EventStats(const std::string& name) - : produced_render_tree_( + : start_time(StringPrintf("Event.Time.%s.Start", name.c_str()), 0, + "The time that the event started."), + produced_render_tree( StringPrintf("Event.%s.ProducedRenderTree", name.c_str()), false, "Nonzero when the event produced a render tree."), count_dom_html_elements_created( @@ -175,12 +180,12 @@ duration_total(StringPrintf("Event.Duration.%s", name.c_str()), base::TimeDelta(), "Total duration of the event (in microseconds). This is " - "the time elapsed from the event injection until the " + "the time elapsed from the event dispatch until the " "render tree is produced."), - duration_dom_inject_event( - StringPrintf("Event.Duration.%s.DOM.InjectEvent", name.c_str()), + duration_dom_dispatch_event( + StringPrintf("Event.Duration.%s.DOM.DispatchEvent", name.c_str()), base::TimeDelta(), - "Injection duration, which includes JS, for event (in " + "Dispatch duration, which includes JS, for event (in " "microseconds). This does not include subsequent DOM and Layout " "processing."), duration_dom_run_animation_frame_callbacks( @@ -242,7 +247,8 @@ stop_watches_[kStopWatchTypeEvent].Stop(); EventStats* event_stats = event_stats_[current_event_type_]; - event_stats->produced_render_tree_ = was_render_tree_produced; + event_stats->start_time = event_start_time_.ToInternalValue(); + event_stats->produced_render_tree = was_render_tree_produced; // Update event counts event_stats->count_dom_html_elements_created = @@ -274,8 +280,8 @@ // Update event durations event_stats->duration_total = stop_watch_durations_[kStopWatchTypeEvent]; - event_stats->duration_dom_inject_event = - stop_watch_durations_[kStopWatchTypeInjectEvent]; + event_stats->duration_dom_dispatch_event = + stop_watch_durations_[kStopWatchTypeDispatchEvent]; event_stats->duration_dom_run_animation_frame_callbacks = dom_stat_tracker_->GetStopWatchTypeDuration( dom::DomStatTracker::kStopWatchTypeRunAnimationFrameCallbacks); @@ -345,7 +351,7 @@ << "\"DurTotalUs\":" << stop_watch_durations_[kStopWatchTypeEvent].InMicroseconds() << ", " << "\"DurDomInjectEventUs\":" - << stop_watch_durations_[kStopWatchTypeInjectEvent].InMicroseconds() + << stop_watch_durations_[kStopWatchTypeDispatchEvent].InMicroseconds() << ", " << "\"DurDomRunAnimationFrameCallbacksUs\":" << dom_stat_tracker_
diff --git a/src/cobalt/browser/web_module_stat_tracker.h b/src/cobalt/browser/web_module_stat_tracker.h index 08ae658..5417e06 100644 --- a/src/cobalt/browser/web_module_stat_tracker.h +++ b/src/cobalt/browser/web_module_stat_tracker.h
@@ -34,7 +34,7 @@ class WebModuleStatTracker : public base::StopWatchOwner { public: WebModuleStatTracker(const std::string& name, - bool should_track_injected_events); + bool should_track_dispatched_events); ~WebModuleStatTracker(); dom::DomStatTracker* dom_stat_tracker() const { @@ -45,15 +45,16 @@ return layout_stat_tracker_.get(); } - // |OnStartInjectEvent| starts event stat tracking if - // |should_track_injected_events_| is true. Otherwise, it does nothing. - void OnStartInjectEvent(const scoped_refptr<dom::Event>& event); + // |OnStartDispatchEvent| starts event stat tracking if + // |should_track_dispatched_events_| is true. Otherwise, it does nothing. + void OnStartDispatchEvent(const scoped_refptr<dom::Event>& event); - // |OnEndInjectEvent| notifies the event stat tracking that the event has - // finished being injected. If no animation frame callbacks and also no render - // tree is pending, it also ends tracking of the event. - void OnEndInjectEvent(bool are_animation_frame_callbacks_pending, - bool is_new_render_tree_pending); + // |OnStopDispatchEvent| notifies the event stat tracking that |event| has + // finished being dispatched. If this is the event currently being tracked + // and nothing is pending, then it also ends tracking of the event. + void OnStopDispatchEvent(const scoped_refptr<dom::Event>& event, + bool are_animation_frame_callbacks_pending, + bool is_new_render_tree_pending); // |OnRanAnimationFrameCallbacks| ends stat tracking for the current event // if no render tree is pending. @@ -72,14 +73,15 @@ enum StopWatchType { kStopWatchTypeEvent, - kStopWatchTypeInjectEvent, + kStopWatchTypeDispatchEvent, kNumStopWatchTypes, }; struct EventStats { explicit EventStats(const std::string& name); - base::CVal<bool, base::CValPublic> produced_render_tree_; + base::CVal<int64, base::CValPublic> start_time; + base::CVal<bool, base::CValPublic> produced_render_tree; // Count-related base::CVal<int, base::CValPublic> count_dom_html_elements_created; @@ -100,7 +102,7 @@ // Duration-related base::CVal<base::TimeDelta, base::CValPublic> duration_total; - base::CVal<base::TimeDelta, base::CValPublic> duration_dom_inject_event; + base::CVal<base::TimeDelta, base::CValPublic> duration_dom_dispatch_event; base::CVal<base::TimeDelta, base::CValPublic> duration_dom_run_animation_frame_callbacks; base::CVal<base::TimeDelta, base::CValPublic> @@ -138,6 +140,10 @@ // Event-related const bool should_track_event_stats_; EventType current_event_type_; + // Raw pointer to the current event. This is used to verify that the event in + // |OnStopDispatchEvent| is the dispatched event being tracked. + dom::Event* current_event_dispatched_event_; + // Each individual |EventType| has its own entry in the vector. ScopedVector<EventStats> event_stats_;
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id index 2f807b4..c10f57f 100644 --- a/src/cobalt/build/build.id +++ b/src/cobalt/build/build.id
@@ -1 +1 @@ -140119 \ No newline at end of file +174384 \ No newline at end of file
diff --git a/src/cobalt/build/config/base.gypi b/src/cobalt/build/config/base.gypi index da47e25..3cdcb28 100644 --- a/src/cobalt/build/config/base.gypi +++ b/src/cobalt/build/config/base.gypi
@@ -429,6 +429,17 @@ # re-download video data. Note that the JavaScript app may experience # significant difficulty if this value is too low. 'cobalt_media_buffer_video_budget_4k%': 60 * 1024 * 1024, + + # Specifies the duration threshold of media source garbage collection. When + # the accumulated duration in a source buffer exceeds this value, the media + # source implementation will try to eject existing buffers from the cache. + # This is usually triggered when the video being played has a simple content + # and the encoded data is small. In such case this can limit how much is + # allocated for the book keeping data of the media buffers and avoid OOM of + # system heap. + # This should be set to 170 for most of the platforms. But it can be + # further reduced on systems with extremely low memory. + 'cobalt_media_source_garbage_collection_duration_threshold_in_seconds%': 170, }, 'target_defaults': { @@ -451,6 +462,7 @@ 'COBALT_MEDIA_BUFFER_VIDEO_BUDGET_4K=<(cobalt_media_buffer_video_budget_4k)', 'COBALT_MEDIA_BUFFER_INITIAL_CAPACITY=<(cobalt_media_buffer_initial_capacity)', 'COBALT_MEDIA_BUFFER_ALLOCATION_UNIT=<(cobalt_media_buffer_allocation_unit)', + 'COBALT_MEDIA_SOURCE_GARBAGE_COLLECTION_DURATION_THRESHOLD_IN_SECONDS=<(cobalt_media_source_garbage_collection_duration_threshold_in_seconds)', ], 'cflags': [ '<@(compiler_flags)' ], 'ldflags': [ '<@(linker_flags)' ],
diff --git a/src/cobalt/build/copy_icu_data.gypi b/src/cobalt/build/copy_icu_data.gypi index c2bfac3..9b9ba27 100644 --- a/src/cobalt/build/copy_icu_data.gypi +++ b/src/cobalt/build/copy_icu_data.gypi
@@ -39,15 +39,21 @@ 'little_endian%': '<(little_endian)', 'use_icu_dat_file%': '<(use_icu_dat_file)', }, + 'little_endian%': '<(little_endian)', }, - #'inputs_icu%': [ '<(inputs_icu)' ], - 'inputs_icu%': [ '<(static_contents_source_dir)/icu/' ], + 'conditions': [ + ['little_endian==1', { + 'inputs_icu%': [ '<(static_contents_source_dir)/icu/icudt56l' ], + }, { + 'inputs_icu%': [ '<(static_contents_source_dir)/icu/icudt56b' ], + }], + ], }, 'copies': [ { - 'destination': '<(static_contents_output_data_dir)/', + 'destination': '<(static_contents_output_data_dir)/icu/', 'files': [ '<(inputs_icu)' ], }, ],
diff --git a/src/cobalt/cssom/css_declared_style_data.h b/src/cobalt/cssom/css_declared_style_data.h index 0ac19c7..3263fa2 100644 --- a/src/cobalt/cssom/css_declared_style_data.h +++ b/src/cobalt/cssom/css_declared_style_data.h
@@ -17,10 +17,11 @@ #include <bitset> #include <functional> +#include <map> #include <string> #include "base/compiler_specific.h" -#include "base/hash_tables.h" +#include "base/containers/small_map.h" #include "base/memory/ref_counted.h" #include "cobalt/base/unused.h" #include "cobalt/cssom/css_declaration_data.h" @@ -36,7 +37,10 @@ public: CSSDeclaredStyleData(); - typedef base::hash_map<PropertyKey, scoped_refptr<PropertyValue> > + // NOTE: The array size of base::SmallMap is based on extensive testing. Do + // not change it unless additional profiling data justifies it. + typedef base::SmallMap<std::map<PropertyKey, scoped_refptr<PropertyValue> >, + 8, std::equal_to<PropertyKey> > PropertyValues; // The length attribute must return the number of CSS declarations in the
diff --git a/src/cobalt/debug/debug_web_server.cc b/src/cobalt/debug/debug_web_server.cc index 6ffd152..84e3885 100644 --- a/src/cobalt/debug/debug_web_server.cc +++ b/src/cobalt/debug/debug_web_server.cc
@@ -188,6 +188,11 @@ // Construct the local disk path corresponding to the request path. FilePath file_path(content_root_dir_); + if (!IsStringASCII(url_path)) { + LOG(WARNING) << "Got HTTP request with non-ASCII URL path."; + server_->Send404(connection_id); + return; + } file_path = file_path.AppendASCII(url_path); // If the disk path is a directory, look for an index file.
diff --git a/src/cobalt/dom/dom_stat_tracker.h b/src/cobalt/dom/dom_stat_tracker.h index 35cedb7..e967385 100644 --- a/src/cobalt/dom/dom_stat_tracker.h +++ b/src/cobalt/dom/dom_stat_tracker.h
@@ -104,11 +104,11 @@ // Tracking of videos produced by an event. base::StopWatch event_video_start_delay_stop_watch_; - base::CVal<base::TimeDelta> event_video_start_delay_; + base::CVal<base::TimeDelta, base::CValPublic> event_video_start_delay_; // Count of HtmlScriptElement::Execute() calls and time of last call. - base::CVal<int> script_element_execute_count_; - base::CVal<int64> script_element_execute_time_; + base::CVal<int, base::CValPublic> script_element_execute_count_; + base::CVal<int64, base::CValPublic> script_element_execute_time_; // Periodic counts. The counts are cleared after the CVals are updated in // |FlushPeriodicTracking|.
diff --git a/src/cobalt/dom/html_link_element.cc b/src/cobalt/dom/html_link_element.cc index ade761c..52285ae 100644 --- a/src/cobalt/dom/html_link_element.cc +++ b/src/cobalt/dom/html_link_element.cc
@@ -106,25 +106,19 @@ document->IncreaseLoadingCounter(); } -void HTMLLinkElement::OnLoadingDone(const std::string& content) { - TRACK_MEMORY_SCOPE("DOM"); +void HTMLLinkElement::OnLoadingDone(scoped_ptr<std::string> content) { DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(content); + TRACK_MEMORY_SCOPE("DOM"); TRACE_EVENT0("cobalt::dom", "HTMLLinkElement::OnLoadingDone()"); Document* document = node_document(); scoped_refptr<cssom::CSSStyleSheet> style_sheet = document->html_element_context()->css_parser()->ParseStyleSheet( - content, base::SourceLocation(href(), 1, 1)); + *content, base::SourceLocation(href(), 1, 1)); style_sheet->SetLocationUrl(absolute_url_); document->style_sheets()->Append(style_sheet); - // Once the attempts to obtain the resource and its critical subresources are - // complete, the user agent must, if the loads were successful, queue a task - // to fire a simple event named load at the link element, or, if the resource - // or one of its critical subresources failed to completely load for any - // reason (e.g. DNS error, HTTP 404 response, a connection being prematurely - // closed, unsupported Content-Type), queue a task to fire a simple event - // named error at the link element. PostToDispatchEvent(FROM_HERE, base::Tokens::load()); // The element must delay the load event of the element's document until all
diff --git a/src/cobalt/dom/html_link_element.h b/src/cobalt/dom/html_link_element.h index 6f2e021..18860a8 100644 --- a/src/cobalt/dom/html_link_element.h +++ b/src/cobalt/dom/html_link_element.h
@@ -66,7 +66,7 @@ // From the spec: HTMLLinkElement. void Obtain(); - void OnLoadingDone(const std::string& content); + void OnLoadingDone(scoped_ptr<std::string> content); void OnLoadingError(const std::string& error); void ReleaseLoader();
diff --git a/src/cobalt/dom/html_media_element.cc b/src/cobalt/dom/html_media_element.cc index 0dbebf1..70a3f3f 100644 --- a/src/cobalt/dom/html_media_element.cc +++ b/src/cobalt/dom/html_media_element.cc
@@ -1573,10 +1573,15 @@ ScheduleOwnEvent(base::Tokens::durationchange()); - float now = current_time(NULL); - float dur = duration(); - if (now > dur) { - Seek(dur); + double now = current_time(NULL); + // Reset and update |duration_|. + duration_ = std::numeric_limits<double>::quiet_NaN(); + if (player_ && ready_state_ >= WebMediaPlayer::kReadyStateHaveMetadata) { + duration_ = player_->GetDuration(); + } + + if (now > duration_) { + Seek(static_cast<float>(duration_)); } EndProcessingMediaPlayerCallback();
diff --git a/src/cobalt/dom/html_script_element.cc b/src/cobalt/dom/html_script_element.cc index 9af2bcc..6976ad3 100644 --- a/src/cobalt/dom/html_script_element.cc +++ b/src/cobalt/dom/html_script_element.cc
@@ -15,6 +15,7 @@ #include "cobalt/dom/html_script_element.h" #include <deque> +#include <utility> #include "base/bind.h" #include "base/compiler_specific.h" @@ -265,6 +266,8 @@ PreventGarbageCollection(); ExecuteExternal(); AllowGarbageCollection(); + // Release the content string now that we're finished with it. + content_.reset(); } else { // Executing the script block must just consist of firing a simple event // named error at the element. @@ -346,9 +349,9 @@ } } -void HTMLScriptElement::OnSyncLoadingDone(const std::string& content) { +void HTMLScriptElement::OnSyncLoadingDone(scoped_ptr<std::string> content) { TRACE_EVENT0("cobalt::dom", "HTMLScriptElement::OnSyncLoadingDone()"); - content_ = content; + content_ = content.Pass(); is_sync_load_successful_ = true; } @@ -359,16 +362,18 @@ // Algorithm for OnLoadingDone: // https://www.w3.org/TR/html5/scripting-1.html#prepare-a-script -void HTMLScriptElement::OnLoadingDone(const std::string& content) { +void HTMLScriptElement::OnLoadingDone(scoped_ptr<std::string> content) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(load_option_ == 4 || load_option_ == 5); + DCHECK(content); TRACE_EVENT0("cobalt::dom", "HTMLScriptElement::OnLoadingDone()"); if (!document_) { AllowGarbageCollection(); return; } - content_ = content; + content_ = content.Pass(); + switch (load_option_) { case 4: { // If the element has a src attribute, does not have an async attribute, @@ -445,6 +450,13 @@ document_->DecreaseLoadingCounterAndMaybeDispatchLoadEvent(); } break; } + + // Release the content string now that we're finished with it. + content_.reset(); + + // Post a task to release the loader. + MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(&HTMLScriptElement::ReleaseLoader, this)); } // Algorithm for OnLoadingError: @@ -489,6 +501,19 @@ // document until the task that is queued by the networking task source // once the resource has been fetched (defined above) has been run. document_->DecreaseLoadingCounterAndMaybeDispatchLoadEvent(); + + // Post a task to release the loader. + MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(&HTMLScriptElement::ReleaseLoader, this)); +} + +void HTMLScriptElement::ExecuteExternal() { + DCHECK(content_); + Execute(*content_, base::SourceLocation(url_.spec(), 1, 1), true); +} + +void HTMLScriptElement::ExecuteInternal() { + Execute(text_content().value(), inline_script_location_, false); } // Algorithm for Execute: @@ -584,5 +609,11 @@ } } +void HTMLScriptElement::ReleaseLoader() { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(loader_); + loader_.reset(); +} + } // namespace dom } // namespace cobalt
diff --git a/src/cobalt/dom/html_script_element.h b/src/cobalt/dom/html_script_element.h index 8307158..d121d34 100644 --- a/src/cobalt/dom/html_script_element.h +++ b/src/cobalt/dom/html_script_element.h
@@ -89,18 +89,14 @@ // void Prepare(); - void OnSyncLoadingDone(const std::string& content); + void OnSyncLoadingDone(scoped_ptr<std::string> content); void OnSyncLoadingError(const std::string& error); - void OnLoadingDone(const std::string& content); + void OnLoadingDone(scoped_ptr<std::string> content); void OnLoadingError(const std::string& error); - void ExecuteExternal() { - Execute(content_, base::SourceLocation(url_.spec(), 1, 1), true); - } - void ExecuteInternal() { - Execute(text_content().value(), inline_script_location_, false); - } + void ExecuteExternal(); + void ExecuteInternal(); void Execute(const std::string& content, const base::SourceLocation& script_location, bool is_external); @@ -108,6 +104,7 @@ const tracked_objects::Location& location, const base::Token& token); void PreventGarbageCollection(); void AllowGarbageCollection(); + void ReleaseLoader(); // Whether the script has been started. bool is_already_started_; @@ -131,8 +128,8 @@ bool is_sync_load_successful_; // Resolved URL of the script. GURL url_; - // Content of the script. - std::string content_; + // Content of the script. Released after Execute is called. + scoped_ptr<std::string> content_; // Active requests disabling garbage collection. int prevent_garbage_collection_count_;
diff --git a/src/cobalt/dom/node.cc b/src/cobalt/dom/node.cc index 6b15337..dc553cd 100644 --- a/src/cobalt/dom/node.cc +++ b/src/cobalt/dom/node.cc
@@ -36,6 +36,7 @@ #include "cobalt/dom/node_list_live.h" #include "cobalt/dom/rule_matching.h" #include "cobalt/dom/text.h" +#include "cobalt/dom/window.h" #if defined(OS_STARBOARD) #include "starboard/configuration.h" #if SB_HAS(CORE_DUMP_HANDLER_SUPPORT) @@ -102,6 +103,16 @@ // The event is now being dispatched. Track it in the global stats. GlobalStats::GetInstance()->StartJavaScriptEvent(); + scoped_refptr<Window> window; + if (IsInDocument()) { + DCHECK(node_document()); + window = node_document()->default_view(); + } + + if (window) { + window->OnStartDispatchEvent(event); + } + typedef std::vector<scoped_refptr<Node> > Ancestors; Ancestors ancestors; for (scoped_refptr<Node> current = this->parent_node(); current != NULL; @@ -137,6 +148,10 @@ event->set_event_phase(Event::kNone); + if (window) { + window->OnStopDispatchEvent(event); + } + // The event has completed being dispatched. Stop tracking it in the global // stats. GlobalStats::GetInstance()->StopJavaScriptEvent();
diff --git a/src/cobalt/dom/testing/stub_window.h b/src/cobalt/dom/testing/stub_window.h index ffe7834..418c7a0 100644 --- a/src/cobalt/dom/testing/stub_window.h +++ b/src/cobalt/dom/testing/stub_window.h
@@ -63,8 +63,9 @@ base::Closure() /* csp_policy_changed */, base::Closure() /* ran_animation_frame_callbacks */, base::Closure() /* window_close */, - base::Closure() /* window_minimize */, - NULL, NULL, NULL); + base::Closure() /* window_minimize */, NULL, NULL, NULL, + dom::Window::OnStartDispatchEventCallback(), + dom::Window::OnStopDispatchEventCallback()); global_environment_->CreateGlobalObject(window_, &environment_settings_); }
diff --git a/src/cobalt/dom/window.cc b/src/cobalt/dom/window.cc index 89dd4ff..e11ae87 100644 --- a/src/cobalt/dom/window.cc +++ b/src/cobalt/dom/window.cc
@@ -74,38 +74,41 @@ const int64_t kPerformanceTimerMinResolutionInMicroseconds = 20; } // namespace -Window::Window(int width, int height, cssom::CSSParser* css_parser, - Parser* dom_parser, loader::FetcherFactory* fetcher_factory, - render_tree::ResourceProvider** resource_provider, - loader::image::AnimatedImageTracker* animated_image_tracker, - loader::image::ImageCache* image_cache, - loader::image::ReducedCacheCapacityManager* - reduced_image_cache_capacity_manager, - loader::font::RemoteTypefaceCache* remote_typeface_cache, - loader::mesh::MeshCache* mesh_cache, - LocalStorageDatabase* local_storage_database, - media::CanPlayTypeHandler* can_play_type_handler, - media::WebMediaPlayerFactory* web_media_player_factory, - script::ExecutionState* execution_state, - script::ScriptRunner* script_runner, - script::ScriptValueFactory* script_value_factory, - MediaSource::Registry* media_source_registry, - DomStatTracker* dom_stat_tracker, const GURL& url, - const std::string& user_agent, const std::string& language, - const base::Callback<void(const GURL&)> navigation_callback, - const base::Callback<void(const std::string&)>& error_callback, - network_bridge::CookieJar* cookie_jar, - const network_bridge::PostSender& post_sender, - const std::string& default_security_policy, - CspEnforcementType csp_enforcement_mode, - const base::Closure& csp_policy_changed_callback, - const base::Closure& ran_animation_frame_callbacks_callback, - const base::Closure& window_close_callback, - const base::Closure& window_minimize_callback, - system_window::SystemWindow* system_window, - const scoped_refptr<input::InputPoller>& input_poller, - const scoped_refptr<MediaSession>& media_session, - int csp_insecure_allowed_token, int dom_max_element_depth) +Window::Window( + int width, int height, cssom::CSSParser* css_parser, Parser* dom_parser, + loader::FetcherFactory* fetcher_factory, + render_tree::ResourceProvider** resource_provider, + loader::image::AnimatedImageTracker* animated_image_tracker, + loader::image::ImageCache* image_cache, + loader::image::ReducedCacheCapacityManager* + reduced_image_cache_capacity_manager, + loader::font::RemoteTypefaceCache* remote_typeface_cache, + loader::mesh::MeshCache* mesh_cache, + LocalStorageDatabase* local_storage_database, + media::CanPlayTypeHandler* can_play_type_handler, + media::WebMediaPlayerFactory* web_media_player_factory, + script::ExecutionState* execution_state, + script::ScriptRunner* script_runner, + script::ScriptValueFactory* script_value_factory, + MediaSource::Registry* media_source_registry, + DomStatTracker* dom_stat_tracker, const GURL& url, + const std::string& user_agent, const std::string& language, + const base::Callback<void(const GURL&)> navigation_callback, + const base::Callback<void(const std::string&)>& error_callback, + network_bridge::CookieJar* cookie_jar, + const network_bridge::PostSender& post_sender, + const std::string& default_security_policy, + CspEnforcementType csp_enforcement_mode, + const base::Closure& csp_policy_changed_callback, + const base::Closure& ran_animation_frame_callbacks_callback, + const base::Closure& window_close_callback, + const base::Closure& window_minimize_callback, + system_window::SystemWindow* system_window, + const scoped_refptr<input::InputPoller>& input_poller, + const scoped_refptr<MediaSession>& media_session, + const OnStartDispatchEventCallback& on_start_dispatch_event_callback, + const OnStopDispatchEventCallback& on_stop_dispatch_event_callback, + int csp_insecure_allowed_token, int dom_max_element_depth) : width_(width), height_(height), html_element_context_(new HTMLElementContext( @@ -116,8 +119,8 @@ remote_typeface_cache, mesh_cache, dom_stat_tracker, language)), performance_(new Performance(new base::MinimumResolutionClock( new base::SystemMonotonicClock(), - base::TimeDelta::FromMicroseconds( - kPerformanceTimerMinResolutionInMicroseconds)))), + base::TimeDelta::FromMicroseconds( + kPerformanceTimerMinResolutionInMicroseconds)))), ALLOW_THIS_IN_INITIALIZER_LIST(document_(new Document( html_element_context_.get(), Document::Options( @@ -151,7 +154,9 @@ ran_animation_frame_callbacks_callback), window_close_callback_(window_close_callback), window_minimize_callback_(window_minimize_callback), - system_window_(system_window) { + system_window_(system_window), + on_start_dispatch_event_callback_(on_start_dispatch_event_callback), + on_stop_dispatch_event_callback_(on_stop_dispatch_event_callback) { #if defined(ENABLE_TEST_RUNNER) test_runner_ = new TestRunner(); #endif // ENABLE_TEST_RUNNER @@ -431,6 +436,18 @@ document_->set_synchronous_layout_callback(synchronous_layout_callback); } +void Window::OnStartDispatchEvent(const scoped_refptr<dom::Event>& event) { + if (!on_start_dispatch_event_callback_.is_null()) { + on_start_dispatch_event_callback_.Run(event); + } +} + +void Window::OnStopDispatchEvent(const scoped_refptr<dom::Event>& event) { + if (!on_stop_dispatch_event_callback_.is_null()) { + on_stop_dispatch_event_callback_.Run(event); + } +} + void Window::TraceMembers(script::Tracer* tracer) { tracer->Trace(performance_); tracer->Trace(document_);
diff --git a/src/cobalt/dom/window.h b/src/cobalt/dom/window.h index 4752a01..f43bfc3 100644 --- a/src/cobalt/dom/window.h +++ b/src/cobalt/dom/window.h
@@ -99,6 +99,10 @@ const base::SourceLocation&, const base::Closure&, const base::Callback<void(const std::string&)>&)> HTMLDecoderCreatorCallback; + typedef base::Callback<void(const scoped_refptr<dom::Event>& event)> + OnStartDispatchEventCallback; + typedef base::Callback<void(const scoped_refptr<dom::Event>& event)> + OnStopDispatchEventCallback; typedef UrlRegistry<MediaSource> MediaSourceRegistry; Window( @@ -133,6 +137,9 @@ system_window::SystemWindow* system_window, const scoped_refptr<input::InputPoller>& input_poller, const scoped_refptr<cobalt::media_session::MediaSession>& media_session, + const OnStartDispatchEventCallback& + start_tracking_dispatch_event_callback, + const OnStopDispatchEventCallback& stop_tracking_dispatch_event_callback, int csp_insecure_allowed_token = 0, int dom_max_element_depth = 0); // Web API: Window @@ -280,6 +287,9 @@ void TraceMembers(script::Tracer* tracer) OVERRIDE; + void OnStartDispatchEvent(const scoped_refptr<dom::Event>& event); + void OnStopDispatchEvent(const scoped_refptr<dom::Event>& event); + DEFINE_WRAPPABLE_TYPE(Window); private: @@ -331,6 +341,9 @@ scoped_refptr<TestRunner> test_runner_; #endif // ENABLE_TEST_RUNNER + OnStartDispatchEventCallback on_start_dispatch_event_callback_; + OnStopDispatchEventCallback on_stop_dispatch_event_callback_; + DISALLOW_COPY_AND_ASSIGN(Window); };
diff --git a/src/cobalt/dom/window_test.cc b/src/cobalt/dom/window_test.cc index f087c28..3487ac4 100644 --- a/src/cobalt/dom/window_test.cc +++ b/src/cobalt/dom/window_test.cc
@@ -64,7 +64,9 @@ base::Closure() /* ran_animation_frame_callbacks */, base::Closure() /* window_close */, base::Closure() /* window_minimize */, - stub_media_module_->system_window(), NULL, NULL)) {} + stub_media_module_->system_window(), NULL, NULL, + dom::Window::OnStartDispatchEventCallback(), + dom::Window::OnStopDispatchEventCallback())) {} ~WindowTest() OVERRIDE {}
diff --git a/src/cobalt/layout_tests/testdata/web-platform-tests/content-security-policy/web_platform_tests.txt b/src/cobalt/layout_tests/testdata/web-platform-tests/content-security-policy/web_platform_tests.txt index 48b16c9..47bb2bd 100644 --- a/src/cobalt/layout_tests/testdata/web-platform-tests/content-security-policy/web_platform_tests.txt +++ b/src/cobalt/layout_tests/testdata/web-platform-tests/content-security-policy/web_platform_tests.txt
@@ -165,7 +165,7 @@ blink-contrib/policy-does-not-affect-child.sub.html,DISABLE blink-contrib/report-blocked-data-uri.sub.html,PASS -blink-contrib/report-cross-origin-no-cookies.sub.html,PASS +blink-contrib/report-cross-origin-no-cookies.sub.html,DISABLE blink-contrib/report-disallowed-from-meta.sub.html,PASS blink-contrib/report-same-origin-with-cookies.sub.html,PASS
diff --git a/src/cobalt/loader/embedded_resources/splash_screen.html b/src/cobalt/loader/embedded_resources/black_splash_screen.html similarity index 100% rename from src/cobalt/loader/embedded_resources/splash_screen.html rename to src/cobalt/loader/embedded_resources/black_splash_screen.html
diff --git a/src/cobalt/loader/embedded_resources/splash_screen.css b/src/cobalt/loader/embedded_resources/splash_screen.css deleted file mode 100644 index 9fbe2a3..0000000 --- a/src/cobalt/loader/embedded_resources/splash_screen.css +++ /dev/null
@@ -1,142 +0,0 @@ -body { - overflow: hidden; - font-size: 1.4815vh; /* Corresponds to 16px at 1080p. */ -} - -#splash { - background-color: #e62117; - background-image: url("h5vcc-embedded://you_tube_logo.png"); - background-position: center center; - background-repeat: no-repeat; - background-size: 50%; - height: 100%; - left: 0; - position: absolute; - top: 0; - width: 100%; -} - -#loading { - position: absolute; - top: 52em; - width: 100%; -} - -#spinner { - /* The spinner starts with display set to none, and JavaScript will set this - to 'block' after some time has passed, if the splash screen is still - visible. */ - display: none; - - height: 5.33em; - margin: 0 auto; - position: relative; - width: 5.33em; -} - -.dot { - background-color: #cbcbcb; - border-radius: 50%; - height: 1.17em; - position: absolute; - width: 1.17em; -} - -@keyframes fade1 { - 0%,100% {opacity: 0} - 50% {opacity: 1} -} - -@keyframes fade2 { - 0%,100% {opacity: .25} - 37.5% {opacity: 1} - 87.5% {opacity: 0} -} - -@keyframes fade3 { - 0%,100% {opacity: .5} - 25% {opacity: 1} - 75% {opacity: 0} -} - -@keyframes fade4 { - 0%,100% {opacity: .75} - 12.5% {opacity: 1} - 62.5% {opacity: 0} -} - -@keyframes fade5 { - 0%,100% {opacity: 1} - 50% {opacity: 0} -} - -@keyframes fade6 { - 0%,100% {opacity: .75} - 37.5% {opacity: 0} - 87.5% {opacity: 1} -} - -@keyframes fade7 { - 0%,100% {opacity: .5} - 25% {opacity: 0} - 75% {opacity: 1} -} - -@keyframes fade8 { - 0%,100% {opacity: .25} - 12.5% {opacity: 0} - 62.5% {opacity: 1} -} - -#dot1 { - animation: fade8 .72s infinite ease; - left: 0; - top: 2.09em; -} - -#dot2 { - animation: fade7 .72s infinite ease; - left: .61em; - top: .61em; -} - -#dot3 { - animation: fade6 .72s infinite ease; - left: 2.09em; - top: 0; -} - -#dot4 { - animation: fade5 .72s infinite ease; - right: .61em; - top: .61em; -} - -#dot5 { - animation: fade4 .72s infinite ease; - right: 0; - top: 2.09em; -} - -#dot6 { - animation: fade3 .72s infinite ease; - bottom: .61em; - right: .61em; -} - -#dot7 { - animation: fade2 .72s infinite ease; - bottom: 0; - left: 2.09em; -} - -#dot8 { - animation: fade1 .72s infinite ease; - bottom: .61em; - left: .61em; -} - -.hidden { - height: 0; - visibility: hidden; -}
diff --git a/src/cobalt/loader/embedded_resources/splash_screen.js b/src/cobalt/loader/embedded_resources/splash_screen.js deleted file mode 100644 index 0d30edc..0000000 --- a/src/cobalt/loader/embedded_resources/splash_screen.js +++ /dev/null
@@ -1,5 +0,0 @@ - // Enable the spinner after 3 seconds have passed. - window.setTimeout(function() { - var spinner = document.getElementById('spinner'); - spinner.style.display = 'block'; - }, 3000);
diff --git a/src/cobalt/loader/embedded_resources/you_tube_logo.png b/src/cobalt/loader/embedded_resources/you_tube_logo.png deleted file mode 100644 index 14563d0..0000000 --- a/src/cobalt/loader/embedded_resources/you_tube_logo.png +++ /dev/null Binary files differ
diff --git a/src/cobalt/loader/loader.gyp b/src/cobalt/loader/loader.gyp index 0c9edff..aeebef5 100644 --- a/src/cobalt/loader/loader.gyp +++ b/src/cobalt/loader/loader.gyp
@@ -175,11 +175,17 @@ 'input_directory': 'embedded_resources', }, 'sources': [ + '<(input_directory)/black_splash_screen.html', '<(input_directory)/equirectangular_40_40.msh', - '<(input_directory)/splash_screen.css', - '<(input_directory)/splash_screen.html', - '<(input_directory)/splash_screen.js', - '<(input_directory)/you_tube_logo.png', + ], + 'conditions': [ + ['target_arch == "ps3"', { + 'sources': [ + '<(input_directory)/youtube_splash_screen.css', + '<(input_directory)/youtube_splash_screen.html', + '<(input_directory)/youtube_splash_screen.png', + ], + }], ], 'actions': [ {
diff --git a/src/cobalt/loader/loader_test.cc b/src/cobalt/loader/loader_test.cc index 1e7872a..570d839 100644 --- a/src/cobalt/loader/loader_test.cc +++ b/src/cobalt/loader/loader_test.cc
@@ -16,6 +16,7 @@ #include "base/bind.h" #include "base/file_util.h" +#include "base/memory/scoped_ptr.h" #include "base/message_loop.h" #include "base/path_service.h" #include "base/run_loop.h" @@ -40,8 +41,8 @@ public: explicit TextDecoderCallback(base::RunLoop* run_loop) : run_loop_(run_loop) {} - void OnDone(const std::string& text) { - text_ = text; + void OnDone(scoped_ptr<std::string> text) { + text_ = *text; MessageLoop::current()->PostTask(FROM_HERE, run_loop_->QuitClosure()); }
diff --git a/src/cobalt/loader/resource_cache.h b/src/cobalt/loader/resource_cache.h index 024cc55..5573eac 100644 --- a/src/cobalt/loader/resource_cache.h +++ b/src/cobalt/loader/resource_cache.h
@@ -513,12 +513,13 @@ base::CVal<base::cval::SizeInBytes, base::CValPublic> memory_size_in_bytes_; base::CVal<base::cval::SizeInBytes, base::CValPublic> memory_capacity_in_bytes_; - base::CVal<base::cval::SizeInBytes> memory_resources_loaded_in_bytes_; + base::CVal<base::cval::SizeInBytes, base::CValPublic> + memory_resources_loaded_in_bytes_; - base::CVal<int> count_resources_requested_; - base::CVal<int> count_resources_loading_; - base::CVal<int> count_resources_loaded_; - base::CVal<int> count_pending_callbacks_; + base::CVal<int, base::CValPublic> count_resources_requested_; + base::CVal<int, base::CValPublic> count_resources_loading_; + base::CVal<int, base::CValPublic> count_resources_loaded_; + base::CVal<int, base::CValPublic> count_pending_callbacks_; DISALLOW_COPY_AND_ASSIGN(ResourceCache); };
diff --git a/src/cobalt/loader/text_decoder.h b/src/cobalt/loader/text_decoder.h index 11b78d4..2c1761c 100644 --- a/src/cobalt/loader/text_decoder.h +++ b/src/cobalt/loader/text_decoder.h
@@ -17,6 +17,7 @@ #include <algorithm> #include <string> +#include <utility> #include "base/callback.h" #include "base/compiler_specific.h" @@ -32,13 +33,14 @@ // results. class TextDecoder : public Decoder { public: - explicit TextDecoder(base::Callback<void(const std::string&)> done_callback) + explicit TextDecoder( + base::Callback<void(scoped_ptr<std::string>)> done_callback) : done_callback_(done_callback), suspended_(false) {} ~TextDecoder() OVERRIDE {} // This function is used for binding callback for creating TextDecoder. static scoped_ptr<Decoder> Create( - base::Callback<void(const std::string&)> done_callback) { + base::Callback<void(scoped_ptr<std::string>)> done_callback) { return scoped_ptr<Decoder>(new TextDecoder(done_callback)); } @@ -48,7 +50,10 @@ if (suspended_) { return; } - text_.append(data, size); + if (!text_) { + text_.reset(new std::string); + } + text_->append(data, size); } void DecodeChunkPassed(scoped_ptr<std::string> data) OVERRIDE { @@ -58,10 +63,10 @@ return; } - if (text_.empty()) { - std::swap(*data, text_); + if (!text_) { + text_ = data.Pass(); } else { - text_.append(*data); + text_->append(*data); } } @@ -70,11 +75,14 @@ if (suspended_) { return; } - done_callback_.Run(text_); + if (!text_) { + text_.reset(new std::string); + } + done_callback_.Run(text_.Pass()); } bool Suspend() OVERRIDE { suspended_ = true; - text_.clear(); + text_.reset(); return true; } void Resume(render_tree::ResourceProvider* /*resource_provider*/) OVERRIDE { @@ -83,8 +91,8 @@ private: base::ThreadChecker thread_checker_; - std::string text_; - base::Callback<void(const std::string&)> done_callback_; + base::Callback<void(scoped_ptr<std::string>)> done_callback_; + scoped_ptr<std::string> text_; bool suspended_; };
diff --git a/src/cobalt/loader/text_decoder_test.cc b/src/cobalt/loader/text_decoder_test.cc index 7c62696..29402dd 100644 --- a/src/cobalt/loader/text_decoder_test.cc +++ b/src/cobalt/loader/text_decoder_test.cc
@@ -15,6 +15,7 @@ #include "cobalt/loader/text_decoder.h" #include "base/bind.h" +#include "base/memory/scoped_ptr.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -23,7 +24,7 @@ namespace { struct TextDecoderCallback { - void Callback(const std::string& value) { text = value; } + void Callback(scoped_ptr<std::string> value) { text = *value; } std::string text; };
diff --git a/src/cobalt/media/base/decoder_buffer.cc b/src/cobalt/media/base/decoder_buffer.cc index b01b364..93c85d9 100644 --- a/src/cobalt/media/base/decoder_buffer.cc +++ b/src/cobalt/media/base/decoder_buffer.cc
@@ -68,15 +68,19 @@ return; } - SbMemoryCopy(data_.get(), data, size_); + if (has_data()) { + SbMemoryCopy(data_.get(), data, size_); + } if (!side_data) { CHECK_EQ(side_data_size, 0u); return; } - DCHECK_GT(side_data_size_, 0u); - SbMemoryCopy(side_data_.get(), side_data, side_data_size_); + if (has_side_data()) { + DCHECK_GT(side_data_size_, 0u); + SbMemoryCopy(side_data_.get(), side_data, side_data_size_); + } } DecoderBuffer::~DecoderBuffer() {}
diff --git a/src/cobalt/media/base/stream_parser_buffer.cc b/src/cobalt/media/base/stream_parser_buffer.cc index 3680f9c..0656fb8 100644 --- a/src/cobalt/media/base/stream_parser_buffer.cc +++ b/src/cobalt/media/base/stream_parser_buffer.cc
@@ -45,8 +45,13 @@ scoped_refptr<StreamParserBuffer> StreamParserBuffer::CopyFrom( Allocator* allocator, const uint8_t* data, int data_size, bool is_key_frame, Type type, TrackId track_id) { - return make_scoped_refptr(new StreamParserBuffer( - allocator, data, data_size, NULL, 0, is_key_frame, type, track_id)); + scoped_refptr<StreamParserBuffer> stream_parser_buffer = + make_scoped_refptr(new StreamParserBuffer( + allocator, data, data_size, NULL, 0, is_key_frame, type, track_id)); + if (stream_parser_buffer->has_data()) { + return stream_parser_buffer; + } + return NULL; } scoped_refptr<StreamParserBuffer> StreamParserBuffer::CopyFrom( @@ -93,6 +98,10 @@ set_duration(kNoTimestamp); } + if (!has_data()) { + return; + } + if (is_key_frame) set_is_key_frame(true); }
diff --git a/src/cobalt/media/filters/source_buffer_stream.cc b/src/cobalt/media/filters/source_buffer_stream.cc index 2602fd0..8ab87ce 100644 --- a/src/cobalt/media/filters/source_buffer_stream.cc +++ b/src/cobalt/media/filters/source_buffer_stream.cc
@@ -730,10 +730,30 @@ return false; } - // Return if we're under or at the memory limit. - if (ranges_size + newDataSize <= memory_limit_) return true; + base::TimeDelta duration = GetBufferedDurationForGarbageCollection(); - size_t bytes_to_free = ranges_size + newDataSize - memory_limit_; + size_t bytes_to_free = 0; + + // Check if we're under or at the memory/duration limit. + const int64 kGcDurationThresholdInMilliseconds = + COBALT_MEDIA_SOURCE_GARBAGE_COLLECTION_DURATION_THRESHOLD_IN_SECONDS * + 1000; + + if (ranges_size + newDataSize > memory_limit_) { + bytes_to_free = ranges_size + newDataSize - memory_limit_; + } else if (duration.InMilliseconds() > kGcDurationThresholdInMilliseconds) { + // Estimate the size to free. + int64 duration_to_free = + duration.InMilliseconds() - kGcDurationThresholdInMilliseconds; + bytes_to_free = static_cast<size_t>(ranges_size * duration_to_free / + duration.InMilliseconds()); + } + + if (bytes_to_free == 0) { + return true; + } + + DCHECK_GT(bytes_to_free, 0); DVLOG(2) << __func__ << " " << GetStreamTypeName() << ": Before GC media_time=" << media_time.InSecondsF() @@ -1833,5 +1853,15 @@ return true; } +base::TimeDelta SourceBufferStream::GetBufferedDurationForGarbageCollection() + const { + base::TimeDelta duration; + for (RangeList::const_iterator itr = ranges_.begin(); itr != ranges_.end(); + ++itr) { + duration += (*itr)->GetEndTimestamp() - (*itr)->GetStartTimestamp(); + } + return duration; +} + } // namespace media } // namespace cobalt
diff --git a/src/cobalt/media/filters/source_buffer_stream.h b/src/cobalt/media/filters/source_buffer_stream.h index 6fe9229..c473d4a 100644 --- a/src/cobalt/media/filters/source_buffer_stream.h +++ b/src/cobalt/media/filters/source_buffer_stream.h
@@ -471,6 +471,10 @@ // appropriately and returns true. Otherwise returns false. bool SetPendingBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); + // Returns the accumulated duration of all ranges. This is solely used by + // garbage collection. + base::TimeDelta GetBufferedDurationForGarbageCollection() const; + // Used to report log messages that can help the web developer figure out what // is wrong with the content. scoped_refptr<MediaLog> media_log_;
diff --git a/src/cobalt/media/formats/mp4/mp4_stream_parser.cc b/src/cobalt/media/formats/mp4/mp4_stream_parser.cc index d8074e9..dd13d30 100644 --- a/src/cobalt/media/formats/mp4/mp4_stream_parser.cc +++ b/src/cobalt/media/formats/mp4/mp4_stream_parser.cc
@@ -618,6 +618,10 @@ buffer_allocator_, &frame_buf[0], frame_buf.size(), runs_->is_keyframe(), buffer_type, runs_->track_id()); + if (!stream_buf) { + return false; + } + if (decrypt_config) stream_buf->set_decrypt_config(decrypt_config.Pass()); stream_buf->set_duration(runs_->duration());
diff --git a/src/cobalt/media/formats/mpeg/mpeg_audio_stream_parser_base.cc b/src/cobalt/media/formats/mpeg/mpeg_audio_stream_parser_base.cc index 31d415a..602b166 100644 --- a/src/cobalt/media/formats/mpeg/mpeg_audio_stream_parser_base.cc +++ b/src/cobalt/media/formats/mpeg/mpeg_audio_stream_parser_base.cc
@@ -233,6 +233,9 @@ scoped_refptr<StreamParserBuffer> buffer = StreamParserBuffer::CopyFrom(buffer_allocator_, data, frame_size, true, DemuxerStream::AUDIO, kMpegAudioTrackId); + if (!buffer) { + return -1; + } buffer->set_timestamp(timestamp_helper_->GetTimestamp()); buffer->set_duration(timestamp_helper_->GetFrameDuration(sample_count)); buffers->push_back(buffer);
diff --git a/src/cobalt/media/formats/webm/webm_cluster_parser.cc b/src/cobalt/media/formats/webm/webm_cluster_parser.cc index a8fac84..48a4850 100644 --- a/src/cobalt/media/formats/webm/webm_cluster_parser.cc +++ b/src/cobalt/media/formats/webm/webm_cluster_parser.cc
@@ -512,7 +512,10 @@ buffer = StreamParserBuffer::CopyFrom( buffer_allocator_, data + data_offset, size - data_offset, additional, additional_size, is_keyframe, buffer_type, track_num); - + if (!buffer) { + MEDIA_LOG(ERROR, media_log_) << "Failed to allocate StreamParserBuffer"; + return false; + } if (decrypt_config) buffer->set_decrypt_config(decrypt_config.Pass()); } else { std::string id, settings, content; @@ -529,6 +532,10 @@ buffer_allocator_, reinterpret_cast<const uint8_t*>(content.data()), content.length(), &side_data[0], side_data.size(), true, buffer_type, track_num); + if (!buffer) { + MEDIA_LOG(ERROR, media_log_) << "Failed to allocate StreamParserBuffer"; + return false; + } } buffer->set_timestamp(timestamp);
diff --git a/src/cobalt/renderer/pipeline.cc b/src/cobalt/renderer/pipeline.cc index 187e684..b2c7967 100644 --- a/src/cobalt/renderer/pipeline.cc +++ b/src/cobalt/renderer/pipeline.cc
@@ -84,9 +84,6 @@ last_did_rasterize_(false), last_animations_expired_(true), last_stat_tracked_animations_expired_(true), - rasterize_periodic_timer_("Renderer.Rasterize.Duration", - kRasterizePeriodicTimerEntriesPerUpdate, - false /*enable_entry_list_c_val*/), rasterize_animations_timer_("Renderer.Rasterize.Animations", kRasterizeAnimationsTimerMaxEntries, true /*enable_entry_list_c_val*/), @@ -310,14 +307,6 @@ bool animations_active = !are_stat_tracked_animations_expired && did_rasterize; - // The rasterization is only timed with the periodic timer when the render - // tree has changed. This ensures that the frames being timed are consistent - // between platforms that submit unchanged trees and those that don't. - if (did_rasterize) { - rasterize_periodic_timer_.Start(start_time); - rasterize_periodic_timer_.Stop(end_time); - } - if (last_animations_active || animations_active) { // The rasterization is only timed with the animations timer when there are // animations to track. This applies when animations were active during
diff --git a/src/cobalt/renderer/pipeline.h b/src/cobalt/renderer/pipeline.h index a9abff7..571f274 100644 --- a/src/cobalt/renderer/pipeline.h +++ b/src/cobalt/renderer/pipeline.h
@@ -209,13 +209,9 @@ bool last_did_rasterize_; // Timer tracking the amount of time spent in - // |RasterizeSubmissionToRenderTarget| when the render tree has changed. - // The tracking is flushed when the max count is hit. - base::CValCollectionTimerStats<base::CValPublic> rasterize_periodic_timer_; - // Timer tracking the amount of time spent in // |RasterizeSubmissionToRenderTarget| while animations are active. The // tracking is flushed when the animations expire. - base::CValCollectionTimerStats<base::CValDebug> rasterize_animations_timer_; + base::CValCollectionTimerStats<base::CValPublic> rasterize_animations_timer_; // Accumulates render tree rasterization interval times but does not flush // them until the maximum number of samples is gathered. @@ -229,16 +225,16 @@ rasterize_animations_interval_timer_; // The total number of new render trees that have been rasterized. - base::CVal<int> new_render_tree_rasterize_count_; + base::CVal<int, base::CValPublic> new_render_tree_rasterize_count_; // The last time that a newly encountered render tree was first rasterized. - base::CVal<int64> new_render_tree_rasterize_time_; + base::CVal<int64, base::CValPublic> new_render_tree_rasterize_time_; // Whether or not animations are currently playing. - base::CVal<bool> has_active_animations_c_val_; + base::CVal<bool, base::CValPublic> has_active_animations_c_val_; // The most recent time animations started playing. - base::CVal<int64> animations_start_time_; + base::CVal<int64, base::CValPublic> animations_start_time_; // The most recent time animations ended playing. - base::CVal<int64> animations_end_time_; + base::CVal<int64, base::CValPublic> animations_end_time_; #if defined(ENABLE_DEBUG_CONSOLE) // Dumps the current render tree to the console.
diff --git a/src/cobalt/renderer/rasterizer/blitter/cached_software_rasterizer.cc b/src/cobalt/renderer/rasterizer/blitter/cached_software_rasterizer.cc index 1c5e2d4..2dd5667 100644 --- a/src/cobalt/renderer/rasterizer/blitter/cached_software_rasterizer.cc +++ b/src/cobalt/renderer/rasterizer/blitter/cached_software_rasterizer.cc
@@ -234,6 +234,7 @@ // This surface may have already been in the cache if it was in there // with a different scale. In that case, replace the old one. cache_memory_usage_ -= found->second.GetEstimatedMemoryUsage(); + SbBlitterDestroySurface(found->second.surface); surface_map_.erase(found); }
diff --git a/src/media/base/pipeline_impl.cc b/src/media/base/pipeline_impl.cc index aff759d..cf2bef0 100644 --- a/src/media/base/pipeline_impl.cc +++ b/src/media/base/pipeline_impl.cc
@@ -745,6 +745,25 @@ const BufferingStateCB& buffering_state_cb, const base::Closure& duration_change_cb) { DCHECK(message_loop_->BelongsToCurrentThread()); + + // Suspend() can be called from a thread other than the WebModule thread. In + // such case it is possible that Stop() is called before Start() and |state_| + // will be set to |kStopping| or |kStopped|. + if (state_ == kStopping || state_ == kStopped) { + return; + } + + // Check for individual state so we have more clue when one of them is hit. + CHECK_NE(kInitDemuxer, state_) << "state shouldn't be kInitDemuxer"; + CHECK_NE(kInitAudioRenderer, state_) + << "state shouldn't be kInitAudioRenderer"; + CHECK_NE(kInitVideoRenderer, state_) + << "state shouldn't be kInitVideoRenderer"; + CHECK_NE(kInitPrerolling, state_) << "state shouldn't be kInitPrerolling"; + CHECK_NE(kSeeking, state_) << "state shouldn't be kSeeking"; + CHECK_NE(kStarting, state_) << "state shouldn't be kStarting"; + CHECK_NE(kStarted, state_) << "state shouldn't be kStarted"; + CHECK_EQ(kCreated, state_) << "Media pipeline cannot be started more than once";
diff --git a/src/starboard/linux/x64x11/clang/3.3/download_clang.sh b/src/starboard/linux/x64x11/clang/3.3/download_clang.sh index f552ae8..54dded5 100755 --- a/src/starboard/linux/x64x11/clang/3.3/download_clang.sh +++ b/src/starboard/linux/x64x11/clang/3.3/download_clang.sh
@@ -37,7 +37,7 @@ cd llvm # Specify a bootstrap compiler that is known to be available. - CC=clang-3.6 CXX=clang++-3.6 \ + CC=clang CXX=clang++ \ ./configure --enable-optimized --disable-doxygen --prefix=${PWD}/bin make -j"$(nproc)" cd ${toolchain_path}
diff --git a/src/starboard/linux/x64x11/gcc/4.4/compiler_flags.gypi b/src/starboard/linux/x64x11/gcc/4.4/compiler_flags.gypi index 9fc908e..6f7d411 100644 --- a/src/starboard/linux/x64x11/gcc/4.4/compiler_flags.gypi +++ b/src/starboard/linux/x64x11/gcc/4.4/compiler_flags.gypi
@@ -47,6 +47,9 @@ '-O2', ], 'common_compiler_flags': [ + # Add the target specific include path that is not compatible with gcc + # 4.4 default search locations. + '-I/usr/include/x86_64-linux-gnu', # Default visibility to hidden, to enable dead stripping. '-fvisibility=hidden', # protobuf uses hash_map.
diff --git a/src/starboard/linux/x64x11/gcc/4.4/download_gcc.sh b/src/starboard/linux/x64x11/gcc/4.4/download_gcc.sh new file mode 100755 index 0000000..8bac360 --- /dev/null +++ b/src/starboard/linux/x64x11/gcc/4.4/download_gcc.sh
@@ -0,0 +1,139 @@ +#!/bin/bash +# Copyright 2018 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This script downloads and compiles gcc version 4.4.7 + +set -e +unset GOMA_DIR +export GOMA_DIR + +toolchain_name="gcc" +version="4.4.7" +toolchain_folder="x86_64-linux-gnu-${toolchain_name}-${version}" + +binary_path="gcc/bin/g++" +build_duration="about 10 minutes" + +cd $(dirname $0) +source ../../toolchain_paths.sh +cd ${toolchain_path} + +( + texinfo_install_folder=${toolchain_path}/texinfo + if [ ! -f ${texinfo_install_folder}/bin/info ]; then + # Download and compile texinfo + texinfo_version="texinfo-4.13" + texinfo_tar_file=${texinfo_version}a.tar.gz + wget -c https://ftp.gnu.org/gnu/texinfo/${texinfo_tar_file} + + checksum_invalid=$(sha256sum ${texinfo_tar_file} | grep -q -c 1303e91a1c752b69a32666a407e9fbdd6e936def4b09bc7de30f416301530d68) + if [ $checksum_invalid ]; then echo "Invalid checksum"; exit 1 ; fi + rm -rf texinfo ${texinfo_version} + tar -xzf ${texinfo_tar_file} + cd ${texinfo_version}/ + ./configure --prefix=${texinfo_install_folder} + make -j$(nproc) && make install + cd ${toolchain_path} + fi + export PATH=${texinfo_install_folder}/bin:${PATH} + + if [ ! -e gmp/lib/libgmp.a ]; then + gmp_version="gmp-4.3.2" + gmp_tar_file=${gmp_version}.tar.bz2 + wget -c https://ftp.gnu.org/gnu/gmp/${gmp_tar_file} + + checksum_invalid=$(sha256sum ${gmp_tar_file} | grep -q -c 936162c0312886c21581002b79932829aa048cfaf9937c6265aeaa14f1cd1775) + if [ $checksum_invalid ]; then echo "Invalid checksum" ; exit 1 ; fi + + rm -rf gmp ${gmp_version} + tar -xjf ${gmp_tar_file} + cd ${gmp_version} + ./configure --disable-shared --enable-static --prefix=${PWD}/../gmp + make -j$(nproc) && make install + cd ${toolchain_path} + fi + + if [ ! -e mpfr/lib/libmpfr.a ]; then + mpfr_version="mpfr-2.4.2" + mpfr_tar_file=${mpfr_version}.tar.xz + wget -c https://ftp.gnu.org/gnu/mpfr/${mpfr_version}.tar.xz + + checksum_invalid=$(sha256sum ${mpfr_tar_file} | grep -q -c d7271bbfbc9ddf387d3919df8318cd7192c67b232919bfa1cb3202d07843da1b) + if [ $checksum_invalid ]; then echo "Invalid checksum" ; exit 1 ; fi + + rm -rf mpfr ${mpfr_version} + tar -xJf ${mpfr_version}.tar.xz + cd ${mpfr_version} + ./configure --disable-shared --enable-static --with-gmp=../gmp --prefix=${PWD}/../mpfr + make -j$(nproc) && make install + cd ${toolchain_path} + fi + + # Download gcc + if [ ! -e gcc-${version}/README ]; then + file="gcc-${version}.tar.bz2" + wget -c https://ftp.gnu.org/gnu/gcc/gcc-${version}/${file} + wget -c https://ftp.gnu.org/gnu/gcc/gcc-${version}/${file}.sig + wget -c https://ftp.gnu.org/gnu/gnu-keyring.gpg + signature_invalid=`gpg --verify --no-default-keyring --keyring ./gnu-keyring.gpg ${file}.sig` + if [ $signature_invalid ]; then echo "Invalid signature" ; exit 1 ; fi + + checksum_invalid=$(sha256sum ${file} | grep -q -c 5ff75116b8f763fa0fb5621af80fc6fb3ea0f1b1a57520874982f03f26cd607f) + if [ $checksum_invalid ]; then echo "Invalid checksum" ; exit 1 ; fi + + rm -rf gcc-${version} + tar -xjf ${file} + cd gcc-${version} + if [ -f ./contrib/download_prerequisites ]; then + ./contrib/download_prerequisites + fi + + # Replace 'struct siginfo' with 'siginfo_t' in linux-unwind.h (compilation fix). + sed -i 's:struct siginfo:siginfo_t:g' ${toolchain_path}/gcc-${version}/gcc/config/i386/linux-unwind.h + + cd ${toolchain_path} + fi + + # Create clean build folder for gcc + rm -rf gcc gcc-${version}-build + mkdir gcc-${version}-build + cd gcc-${version}-build + + export LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:/usr/lib32:${toolchain_path}/gmp/lib:${toolchain_path}/mpfr/lib + export LD_LIBRARY_PATH=$LIBRARY_PATH + echo LIBRARY_PATH = $LIBRARY_PATH + + export C_INCLUDE_PATH=/usr/include/x86_64-linux-gnu + export CPLUS_INCLUDE_PATH=/usr/include/x86_64-linux-gnu + export TARGET_SYSTEM_ROOT=/usr/include/x86_64-linux-gnu + + export CC="gcc -fgnu89-inline" + export CXX="g++ -fgnu89-inline" + + ${toolchain_path}/gcc-${version}/configure \ + --prefix=${toolchain_path}/gcc \ + --disable-multilib \ + --enable-languages=c,c++ \ + --with-gmp=${toolchain_path}/gmp \ + --with-mpfr=${toolchain_path}/mpfr \ + --with-mpfr-lib=${toolchain_path}/mpfr/lib + + make -j$(nproc) && make install + cd ${toolchain_path} + + ls -l ${toolchain_binary} + ${toolchain_binary} --version +) >${logfile} 2>&1 +
diff --git a/src/starboard/linux/x64x11/gcc/4.4/gyp_configuration.py b/src/starboard/linux/x64x11/gcc/4.4/gyp_configuration.py index 3d6e006..dbb14af 100644 --- a/src/starboard/linux/x64x11/gcc/4.4/gyp_configuration.py +++ b/src/starboard/linux/x64x11/gcc/4.4/gyp_configuration.py
@@ -15,6 +15,7 @@ import logging import os +import subprocess import sys # Import the shared Linux platform configuration. @@ -25,6 +26,7 @@ 'shared'))) # pylint: disable=import-self,g-import-not-at-top import gyp_configuration as shared_configuration +import gyp_utils class PlatformConfig(shared_configuration.PlatformConfig): @@ -34,16 +36,28 @@ super(PlatformConfig, self).__init__( platform, asan_enabled_by_default, goma_supports_compiler=False) + # Run the script that ensures gcc 4.4.7 is installed. + script_path = os.path.dirname(os.path.realpath(__file__)) + subprocess.call( + os.path.join(script_path, 'download_gcc.sh'), cwd=script_path) + def GetVariables(self, configuration): variables = super(PlatformConfig, self).GetVariables(configuration) - variables.update({'clang': 0,}) + variables.update({ + 'clang': 0, + }) return variables def GetEnvironmentVariables(self): env_variables = super(PlatformConfig, self).GetEnvironmentVariables() + toolchain_bin_dir = os.path.join(gyp_utils.GetToolchainsDir(), + 'x86_64-linux-gnu-gcc-4.4.7', 'gcc', 'bin') env_variables.update({ - 'CC': 'gcc-4.4', - 'CXX': 'g++-4.4', + 'CC': + os.path.join(toolchain_bin_dir, 'gcc'), + 'CXX': + 'LIBRARY_PATH=/usr/lib/x86_64-linux-gnu ' + + os.path.join(toolchain_bin_dir, 'g++'), }) return env_variables
diff --git a/src/starboard/nplb/socket_resolve_test.cc b/src/starboard/nplb/socket_resolve_test.cc index ebca117..bf96ac3 100644 --- a/src/starboard/nplb/socket_resolve_test.cc +++ b/src/starboard/nplb/socket_resolve_test.cc
@@ -37,7 +37,7 @@ const void* kNull = NULL; // A random host name to use to test DNS resolution. -const char* kTestHostName = "www.yahoo.com"; +const char kTestHostName[] = "www.example.com"; #define LOG_ADDRESS(i) "In returned address #" << (i)
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/strutil.cc b/src/third_party/protobuf/src/google/protobuf/stubs/strutil.cc index 296694c..8f5ff59 100644 --- a/src/third_party/protobuf/src/google/protobuf/stubs/strutil.cc +++ b/src/third_party/protobuf/src/google/protobuf/stubs/strutil.cc
@@ -29,12 +29,39 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // from google3/strings/strutil.cc -#include "starboard/client_porting/poem/stdlib_poem.h" -#include "starboard/client_porting/poem/stdio_poem.h" -#include "starboard/client_porting/poem/string_poem.h" #ifndef STARBOARD + #include <stdio.h> + +// We need to be able to build this library using the host toolchain for some +// platforms, and Starboard is not available there. So we define these +// "reverse poems" to move past this issue for host builds. For why we don't +// just use poems, see the comment in the #else clause. +#define SbMemoryCopy memcpy +#define SbMemoryMove memmove +#define SbStringGetLength strlen +#define SbStringCopyUnsafe strcpy +#define PoemFindCharacterInString strchr +#define SbStringFormatF snprintf +#define SbStringFormatUnsafeF sprintf +#define SbStringParseUnsignedInteger strtoul +#define SbStringParseSignedInteger strtol +#define SbStringParseDouble strtod + +#else // STARBOARD + +// We avoid using poems here because a subsequent #include of math.h may +// result, on some platforms, of the indirect inclusion of stdlib.h, which +// will then conflict with our poem includes. +#define POEM_NO_EMULATION +// For access to PoemFindCharacterInString() as a replacement for strchr(). +#include "starboard/client_porting/poem/string_poem.h" +#undef POEM_NO_EMULATION + +#include "starboard/memory.h" +#include "starboard/string.h" + #endif // STARBOARD #include <errno.h> @@ -276,7 +303,7 @@ string* result) { GOOGLE_CHECK(result != NULL); result->clear(); - int delim_length = strlen(delim); + int delim_length = SbStringGetLength(delim); // Precompute resulting length so we can reserve() memory in one shot. int length = 0; @@ -515,7 +542,7 @@ (last_hex_escape && isxdigit(*src)))) { if (dest_len - used < 4) // need space for 4 letter escape return -1; - sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"), + SbStringFormatUnsafeF(dest + used, (use_hex ? "\\x%02x" : "\\%03o"), static_cast<uint8>(*src)); is_hex_escape = use_hex; used += 4; @@ -643,7 +670,7 @@ int32 strto32_adaptor(const char *nptr, char **endptr, int base) { const int saved_errno = errno; errno = 0; - const long result = strtol(nptr, endptr, base); + const long result = SbStringParseSignedInteger(nptr, endptr, base); if (errno == ERANGE && result == LONG_MIN) { return kint32min; } else if (errno == ERANGE && result == LONG_MAX) { @@ -663,7 +690,7 @@ uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) { const int saved_errno = errno; errno = 0; - const unsigned long result = strtoul(nptr, endptr, base); + const unsigned long result = SbStringParseUnsignedInteger(nptr, endptr, base); if (errno == ERANGE && result == ULONG_MAX) { return kuint32max; } else if (errno == 0 && result > kuint32max) { @@ -1225,7 +1252,7 @@ void DelocalizeRadix(char* buffer) { // Fast check: if the buffer has a normal decimal point, assume no // translation is needed. - if (strchr(buffer, '.') != NULL) return; + if (PoemFindCharacterInString(buffer, '.') != NULL) return; // Find the first unknown character. while (IsValidFloatChar(*buffer)) ++buffer; @@ -1245,7 +1272,7 @@ // extra bytes. char* target = buffer; do { ++buffer; } while (!IsValidFloatChar(*buffer) && *buffer != '\0'); - memmove(target, buffer, strlen(buffer) + 1); + SbMemoryMove(target, buffer, SbStringGetLength(buffer) + 1); } } @@ -1257,20 +1284,20 @@ GOOGLE_COMPILE_ASSERT(DBL_DIG < 20, DBL_DIG_is_too_big); if (value == numeric_limits<double>::infinity()) { - strcpy(buffer, "inf"); + SbStringCopyUnsafe(buffer, "inf"); return buffer; } else if (value == -numeric_limits<double>::infinity()) { - strcpy(buffer, "-inf"); + SbStringCopyUnsafe(buffer, "-inf"); return buffer; } else if (MathLimits<double>::IsNaN(value)) { - strcpy(buffer, "nan"); + SbStringCopyUnsafe(buffer, "nan"); return buffer; } int snprintf_result = - snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG, value); + SbStringFormatF(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG, value); - // The snprintf should never overflow because the buffer is significantly + // The SbStringFormatF should never overflow because the buffer is significantly // larger than the precision we asked for. GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize); @@ -1280,10 +1307,10 @@ // of a double. This long double may have extra bits that make it compare // unequal to "value" even though it would be exactly equal if it were // truncated to a double. - volatile double parsed_value = strtod(buffer, NULL); + volatile double parsed_value = SbStringParseDouble(buffer, NULL); if (parsed_value != value) { int snprintf_result = - snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG+2, value); + SbStringFormatF(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG+2, value); // Should never overflow; see above. GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize); @@ -1332,7 +1359,7 @@ char* endptr; errno = 0; // errno only gets set on errors #if defined(_WIN32) || defined (__hpux) || defined(STARBOARD) // has no strtof() - *value = strtod(str, &endptr); + *value = SbStringParseDouble(str, &endptr); #else *value = strtof(str, &endptr); #endif @@ -1341,7 +1368,7 @@ bool safe_strtod(const char* str, double* value) { char* endptr; - *value = strtod(str, &endptr); + *value = SbStringParseDouble(str, &endptr); if (endptr != str) { while (ascii_isspace(*endptr)) ++endptr; } @@ -1375,27 +1402,27 @@ GOOGLE_COMPILE_ASSERT(FLT_DIG < 10, FLT_DIG_is_too_big); if (value == numeric_limits<double>::infinity()) { - strcpy(buffer, "inf"); + SbStringCopyUnsafe(buffer, "inf"); return buffer; } else if (value == -numeric_limits<double>::infinity()) { - strcpy(buffer, "-inf"); + SbStringCopyUnsafe(buffer, "-inf"); return buffer; } else if (MathLimits<float>::IsNaN(value)) { - strcpy(buffer, "nan"); + SbStringCopyUnsafe(buffer, "nan"); return buffer; } int snprintf_result = - snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG, value); + SbStringFormatF(buffer, kFloatToBufferSize, "%.*g", FLT_DIG, value); - // The snprintf should never overflow because the buffer is significantly - // larger than the precision we asked for. + // The SbStringFormatF should never overflow because the buffer is + // significantly larger than the precision we asked for. GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize); float parsed_value; if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) { int snprintf_result = - snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG+2, value); + SbStringFormatF(buffer, kFloatToBufferSize, "%.*g", FLT_DIG+2, value); // Should never overflow; see above. GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize); @@ -1435,35 +1462,35 @@ // of a mix of raw C strings, C++ strings, and integer values. // ---------------------------------------------------------------------- -// Append is merely a version of memcpy that returns the address of the byte +// Append is merely a version of SbMemoryCopy that returns the address of the byte // after the area just overwritten. It comes in multiple flavors to minimize // call overhead. static char *Append1(char *out, const AlphaNum &x) { - memcpy(out, x.data(), x.size()); + SbMemoryCopy(out, x.data(), x.size()); return out + x.size(); } static char *Append2(char *out, const AlphaNum &x1, const AlphaNum &x2) { - memcpy(out, x1.data(), x1.size()); + SbMemoryCopy(out, x1.data(), x1.size()); out += x1.size(); - memcpy(out, x2.data(), x2.size()); + SbMemoryCopy(out, x2.data(), x2.size()); return out + x2.size(); } static char *Append4(char *out, const AlphaNum &x1, const AlphaNum &x2, const AlphaNum &x3, const AlphaNum &x4) { - memcpy(out, x1.data(), x1.size()); + SbMemoryCopy(out, x1.data(), x1.size()); out += x1.size(); - memcpy(out, x2.data(), x2.size()); + SbMemoryCopy(out, x2.data(), x2.size()); out += x2.size(); - memcpy(out, x3.data(), x3.size()); + SbMemoryCopy(out, x3.data(), x3.size()); out += x3.size(); - memcpy(out, x4.data(), x4.size()); + SbMemoryCopy(out, x4.data(), x4.size()); return out + x4.size(); } @@ -2269,7 +2296,7 @@ len = 4; } tmp = ghtonl(tmp); - memcpy(output, reinterpret_cast<const char*>(&tmp) + sizeof(tmp) - len, len); + SbMemoryCopy(output, reinterpret_cast<const char*>(&tmp) + sizeof(tmp) - len, len); return len; }