Import Cobalt 21.lts.5.304347
diff --git a/src/CONTRIBUTING.md b/src/CONTRIBUTING.md index 71f6b83..332d6ab 100644 --- a/src/CONTRIBUTING.md +++ b/src/CONTRIBUTING.md
@@ -53,7 +53,7 @@ 1. Run `git clang-format HEAD~` to apply default C++ formatting rules, followed by `git commit -a --amend` to squash any formatting changes into your commit. - 1. Run `git cl upload` to upload the review to + 1. Run `git push origin HEAD:refs/for/master` to upload the review to [Cobalt's Gerrit instance](https://cobalt-review.googlesource.com/). 1. Someone from the maintainers team will review the code, putting up comments on any things that need to change for submission. @@ -62,4 +62,3 @@ 1. If you do not need to make any more changes, a maintainer will integrate the change into our private repository, and it will get pushed out to the public repository after some time. -
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id index 87efaac..bd3b8b4 100644 --- a/src/cobalt/build/build.id +++ b/src/cobalt/build/build.id
@@ -1 +1 @@ -302899 \ No newline at end of file +304347 \ No newline at end of file
diff --git a/src/cobalt/build/save_build_id.py b/src/cobalt/build/save_build_id.py index 014e80d..fc81ab9 100755 --- a/src/cobalt/build/save_build_id.py +++ b/src/cobalt/build/save_build_id.py
@@ -63,7 +63,12 @@ return 0 if not options.build_id: - options.build_id = gyp_utils.GetBuildNumber() + build_id_server_url = os.environ.get('BUILD_ID_SERVER_URL') + if build_id_server_url: + options.build_id = gyp_utils.GetBuildNumber( + version_server=build_id_server_url) + else: + options.build_id = gyp_utils.GetBuildNumber() if not options.build_id: logging.error('Unable to retrieve build id.')
diff --git a/src/cobalt/media/base/sbplayer_pipeline.cc b/src/cobalt/media/base/sbplayer_pipeline.cc index 92979dd..a393489 100644 --- a/src/cobalt/media/base/sbplayer_pipeline.cc +++ b/src/cobalt/media/base/sbplayer_pipeline.cc
@@ -852,11 +852,15 @@ task_runner_, source_url, window_, this, set_bounds_helper_.get(), allow_resume_after_suspend_, *decode_to_texture_output_mode_, on_encrypted_media_init_data_encountered_cb_, video_frame_provider_)); - SetPlaybackRateTask(playback_rate_); - SetVolumeTask(volume_); + if (player_->IsValid()) { + SetPlaybackRateTask(playback_rate_); + SetVolumeTask(volume_); + } else { + player_.reset(); + } } - if (player_->IsValid()) { + if (player_ && player_->IsValid()) { base::Closure output_mode_change_cb; { base::AutoLock auto_lock(lock_); @@ -867,7 +871,8 @@ return; } - player_.reset(); + DLOG(ERROR) << "SbPlayerPipeline::CreateUrlPlayer failed: " + "player_->IsValid() is false."; CallSeekCB(DECODER_ERROR_NOT_SUPPORTED); } @@ -937,33 +942,35 @@ set_bounds_helper_.get(), allow_resume_after_suspend_, *decode_to_texture_output_mode_, video_frame_provider_, max_video_capabilities_)); - - if (!player_->IsValid()) { + if (player_->IsValid()) { + SetPlaybackRateTask(playback_rate_); + SetVolumeTask(volume_); + } else { player_.reset(); - DLOG(ERROR) << "SbPlayerPipeline::CreatePlayer failed: " - "player_->IsValid() is false."; - CallSeekCB(DECODER_ERROR_NOT_SUPPORTED); - return; } - - SetPlaybackRateTask(playback_rate_); - SetVolumeTask(volume_); } - base::Closure output_mode_change_cb; - { - base::AutoLock auto_lock(lock_); - DCHECK(!output_mode_change_cb_.is_null()); - output_mode_change_cb = std::move(output_mode_change_cb_); - } - output_mode_change_cb.Run(); + if (player_ && player_->IsValid()) { + base::Closure output_mode_change_cb; + { + base::AutoLock auto_lock(lock_); + DCHECK(!output_mode_change_cb_.is_null()); + output_mode_change_cb = std::move(output_mode_change_cb_); + } + output_mode_change_cb.Run(); - if (audio_stream_) { - UpdateDecoderConfig(audio_stream_); + if (audio_stream_) { + UpdateDecoderConfig(audio_stream_); + } + if (video_stream_) { + UpdateDecoderConfig(video_stream_); + } + return; } - if (video_stream_) { - UpdateDecoderConfig(video_stream_); - } + + DLOG(ERROR) << "SbPlayerPipeline::CreatePlayer failed: " + "player_->IsValid() is false."; + CallSeekCB(DECODER_ERROR_NOT_SUPPORTED); } void SbPlayerPipeline::OnDemuxerInitialized(PipelineStatus status) { @@ -1353,10 +1360,17 @@ if (player_) { player_->Resume(); if (!player_->IsValid()) { - player_.reset(); - DLOG(ERROR) << "SbPlayerPipeline::ResumeTask failed: " - "player_->IsValid() is false."; - CallSeekCB(DECODER_ERROR_NOT_SUPPORTED); + { + base::AutoLock auto_lock(lock_); + player_.reset(); + } + // TODO: Determine if CallSeekCB() may be used here, as |seek_cb_| may be + // available if the app is suspended before a seek is completed. + if (!error_cb_.is_null()) { + ResetAndRunIfNotNull(&error_cb_, DECODER_ERROR_NOT_SUPPORTED, + "SbPlayerPipeline::ResumeTask failed: " + "player_->IsValid() is false."); + } return; } }
diff --git a/src/cobalt/media/formats/mp4/box_definitions.cc b/src/cobalt/media/formats/mp4/box_definitions.cc index 5d30892..2ff0303 100644 --- a/src/cobalt/media/formats/mp4/box_definitions.cc +++ b/src/cobalt/media/formats/mp4/box_definitions.cc
@@ -1308,7 +1308,8 @@ reader->ReadChild(&decode_time) && reader->MaybeReadChildren(&runs) && reader->MaybeReadChild(&auxiliary_offset) && reader->MaybeReadChild(&auxiliary_size) && - reader->MaybeReadChild(&sdtp)); + reader->MaybeReadChild(&sdtp) && + reader->MaybeReadChild(&sample_encryption)); // There could be multiple SampleGroupDescription and SampleToGroup boxes with // different grouping types. For common encryption, the relevant grouping type
diff --git a/src/cobalt/media/player/web_media_player_impl.cc b/src/cobalt/media/player/web_media_player_impl.cc index d5cfa6f..c8ae297 100644 --- a/src/cobalt/media/player/web_media_player_impl.cc +++ b/src/cobalt/media/player/web_media_player_impl.cc
@@ -231,7 +231,7 @@ UMA_HISTOGRAM_ENUMERATION("Media.URLScheme", URLScheme(url), kMaxURLScheme); DLOG(INFO) << "Start URL playback"; - // Handle any volume changes that occured before load(). + // Handle any volume changes that occurred before load(). SetVolume(GetClient()->Volume()); // TODO: Set networkState to WebMediaPlayer::kNetworkStateIdle on stop. @@ -251,7 +251,7 @@ DLOG(INFO) << "Start MEDIASOURCE playback"; - // Handle any volume changes that occured before load(). + // Handle any volume changes that occurred before load(). SetVolume(GetClient()->Volume()); SetNetworkState(WebMediaPlayer::kNetworkStateLoading); @@ -278,7 +278,7 @@ UMA_HISTOGRAM_ENUMERATION("Media.URLScheme", URLScheme(url), kMaxURLScheme); DLOG(INFO) << "Start PROGRESSIVE playback"; - // Handle any volume changes that occured before load(). + // Handle any volume changes that occurred before load(). SetVolume(GetClient()->Volume()); SetNetworkState(WebMediaPlayer::kNetworkStateLoading); @@ -307,9 +307,6 @@ TRACE_EVENT0("cobalt::media", "WebMediaPlayerImpl::Play"); DCHECK_EQ(main_loop_, base::MessageLoop::current()); -#if defined(__LB_ANDROID__) - audio_focus_bridge_.RequestAudioFocus(); -#endif // defined(__LB_ANDROID__) state_.paused = false; pipeline_->SetPlaybackRate(state_.playback_rate); @@ -319,9 +316,6 @@ void WebMediaPlayerImpl::Pause() { DCHECK_EQ(main_loop_, base::MessageLoop::current()); -#if defined(__LB_ANDROID__) - audio_focus_bridge_.AbandonAudioFocus(); -#endif // defined(__LB_ANDROID__) state_.paused = true; pipeline_->SetPlaybackRate(0.0f);
diff --git a/src/cobalt/media/player/web_media_player_impl.h b/src/cobalt/media/player/web_media_player_impl.h index a1a51be..9aa48c1 100644 --- a/src/cobalt/media/player/web_media_player_impl.h +++ b/src/cobalt/media/player/web_media_player_impl.h
@@ -313,10 +313,6 @@ std::unique_ptr<Demuxer> progressive_demuxer_; std::unique_ptr<ChunkDemuxer> chunk_demuxer_; -#if defined(__LB_ANDROID__) - AudioFocusBridge audio_focus_bridge_; -#endif // defined(__LB_ANDROID__) - // Suppresses calls to OnPipelineError() after destruction / shutdown has been // started; prevents us from spuriously logging errors that are transient or // unimportant.
diff --git a/src/cobalt/renderer/egl_and_gles.h b/src/cobalt/renderer/egl_and_gles.h index 3dac4b2..6666f1b 100644 --- a/src/cobalt/renderer/egl_and_gles.h +++ b/src/cobalt/renderer/egl_and_gles.h
@@ -50,6 +50,7 @@ #define GL_DCHECK_MAYBE_LOG(x) #endif // defined(COBALT_EGL_AND_GLES_LOGGING) +#if SB_DCHECK_ENABLED #define EGL_DCHECK(x) \ do { \ EGL_DCHECK_MAYBE_LOG(x); \ @@ -64,6 +65,10 @@ SB_DCHECK(COBALT_GL_ERRNO == GL_NO_ERROR) \ << #x << " exited with code: " << COBALT_GL_ERRNO; \ } while (false) +#else +#define EGL_DCHECK(x) +#define GL_DCHECK(x) +#endif // SB_DCHECK_ENABLED #if SB_API_VERSION >= 11 namespace cobalt {
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_threshold_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_threshold_2.glsl index 1380682..1be401c 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_threshold_2.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_threshold_2.glsl
@@ -14,7 +14,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_thresholds.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_thresholds.glsl index 63ff1ed..11db997 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_thresholds.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_thresholds.glsl
@@ -19,7 +19,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_threshold_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_threshold_2.glsl index 9c5c1f3..e7447a2 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_threshold_2.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_threshold_2.glsl
@@ -14,7 +14,7 @@ varying mediump float vinCoverage_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds.glsl index cbcba0c..7bf9ef3 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds.glsl
@@ -19,7 +19,7 @@ varying highp float vcoverage_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_2.glsl index 083f5e4..e6a6613 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_2.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_2.glsl
@@ -14,7 +14,7 @@ varying highp float vcoverage_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_3.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_3.glsl index e737a75..a5049c7 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_3.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_3.glsl
@@ -21,7 +21,7 @@ varying mediump float vinCoverage_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_decal_scaletranslate_texdom_texturew_threshold.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_decal_scaletranslate_texdom_texturew_threshold.glsl index d3a03a4..e338bcf 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_decal_scaletranslate_texdom_texturew_threshold.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_decal_scaletranslate_texdom_texturew_threshold.glsl
@@ -18,7 +18,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold.glsl index 5f2b1d3..667a564 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold.glsl
@@ -15,7 +15,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_2.glsl index 084c066..35a3010 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_2.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_2.glsl
@@ -15,7 +15,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_3.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_3.glsl index cb27f80..1f47fae 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_3.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_3.glsl
@@ -15,7 +15,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds.glsl index 1ba24f6..b7223a3 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds.glsl
@@ -18,7 +18,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds_2.glsl index da56a36..ba5cadd 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds_2.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds_2.glsl
@@ -20,7 +20,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold.glsl index e2ec055..8bcc27a 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold.glsl
@@ -16,7 +16,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_2.glsl index fe3a8ae..2ac7fcc 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_2.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_2.glsl
@@ -16,7 +16,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_3.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_3.glsl index f1bbe9d..1cb8137 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_3.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_3.glsl
@@ -16,7 +16,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_thresholds.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_thresholds.glsl index b073544..ba8e732 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_thresholds.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_thresholds.glsl
@@ -19,7 +19,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_threshold.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_threshold.glsl index 3657419..2cec90c 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_threshold.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_threshold.glsl
@@ -13,7 +13,7 @@ varying mediump vec4 vcolor_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds.glsl index 6e1c100..7685597 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds.glsl
@@ -18,7 +18,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_2.glsl index e055c58..a1f1060 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_2.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_2.glsl
@@ -18,7 +18,7 @@ varying mediump vec4 vcolor_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_coverage_texture.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_coverage_texture.glsl index 224674d..07a5ac3 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_coverage_texture.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_coverage_texture.glsl
@@ -10,7 +10,7 @@ varying highp float vcoverage_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_quad_texture.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_quad_texture.glsl index 1ea6bd8..3c26f70 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_quad_texture.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_quad_texture.glsl
@@ -11,7 +11,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_quad_texture_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_quad_texture_2.glsl index d8c1e31..298ccc0 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_quad_texture_2.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_quad_texture_2.glsl
@@ -11,7 +11,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_texindex_texturew.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_texindex_texturew.glsl index 4e004af..92cba89 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_texindex_texturew.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_border_color_texindex_texturew.glsl
@@ -12,7 +12,7 @@ varying highp vec2 vTransformedCoords_0_Stage0; mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) { mediump vec4 _sample1099_c0_c0; - mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06; + mediump float t = vTransformedCoords_0_Stage0.x + 9.999999747378752e-06; _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0); return _sample1099_c0_c0; }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_edges_texindex_texturew_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_edges_texindex_texturew_2.glsl index e7cd090..fda3d24 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_edges_texindex_texturew_2.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_edges_texindex_texturew_2.glsl
@@ -21,9 +21,9 @@ { texColor = texture2D(uTextureSampler_0_Stage0, uv).wwww; } - mediump float distance = 7.96875 * (texColor.x - 0.50196081399917603); + mediump float distance = 7.96875 * (texColor.x - 0.501960813999176); mediump float afwidth; - afwidth = abs(0.64999997615814209 * -dFdy(vIntTextureCoords_Stage0.y)); + afwidth = abs(0.6499999761581421 * -dFdy(vIntTextureCoords_Stage0.y)); mediump float val = smoothstep(-afwidth, afwidth, distance); outputCoverage_Stage0 = vec4(val); }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse.glsl index ee26f8b..8b55db4 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse.glsl
@@ -14,7 +14,7 @@ highp float test = dot(offset, offset) - 1.0; highp vec2 grad = (2.0 * offset) * (vEllipseOffsets_Stage0.z * vEllipseRadii_Stage0.xy); highp float grad_dot = dot(grad, grad); - grad_dot = max(grad_dot, 6.1036000261083245e-05); + grad_dot = max(grad_dot, 6.103600026108325e-05); highp float invlen = vEllipseOffsets_Stage0.z * inversesqrt(grad_dot); highp float edgeAlpha = clamp(0.5 - test * invlen, 0.0, 1.0); outputCoverage_Stage0 = vec4(edgeAlpha);
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse_2.glsl index 0cb3d54..dd2801e 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse_2.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse_2.glsl
@@ -18,7 +18,7 @@ highp vec2 grad = vec2(vEllipseOffsets0_Stage0.x * duvdx.x + vEllipseOffsets0_Stage0.y * duvdx.y, vEllipseOffsets0_Stage0.x * duvdy.x + vEllipseOffsets0_Stage0.y * duvdy.y); grad *= vEllipseOffsets0_Stage0.z; highp float grad_dot = 4.0 * dot(grad, grad); - grad_dot = max(grad_dot, 6.1036000261083245e-05); + grad_dot = max(grad_dot, 6.103600026108325e-05); highp float invlen = inversesqrt(grad_dot); invlen *= vEllipseOffsets0_Stage0.z; highp float edgeAlpha = clamp(0.5 - test * invlen, 0.0, 1.0); @@ -29,7 +29,7 @@ grad = vec2(vEllipseOffsets1_Stage0.x * duvdx.x + vEllipseOffsets1_Stage0.y * duvdx.y, vEllipseOffsets1_Stage0.x * duvdy.x + vEllipseOffsets1_Stage0.y * duvdy.y); grad *= vEllipseOffsets0_Stage0.z; grad_dot = 4.0 * dot(grad, grad); - grad_dot = max(grad_dot, 6.1036000261083245e-05); + grad_dot = max(grad_dot, 6.103600026108325e-05); invlen = inversesqrt(grad_dot); invlen *= vEllipseOffsets0_Stage0.z; edgeAlpha *= clamp(0.5 + test * invlen, 0.0, 1.0);
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse_3.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse_3.glsl index 6148054..ff7654e 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse_3.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse_3.glsl
@@ -18,7 +18,7 @@ highp vec2 grad = vec2(vEllipseOffsets0_Stage0.x * duvdx.x + vEllipseOffsets0_Stage0.y * duvdx.y, vEllipseOffsets0_Stage0.x * duvdy.x + vEllipseOffsets0_Stage0.y * duvdy.y); grad *= vEllipseOffsets0_Stage0.z; highp float grad_dot = 4.0 * dot(grad, grad); - grad_dot = max(grad_dot, 6.1036000261083245e-05); + grad_dot = max(grad_dot, 6.103600026108325e-05); highp float invlen = inversesqrt(grad_dot); invlen *= vEllipseOffsets0_Stage0.z; highp float edgeAlpha = clamp(0.5 - test * invlen, 0.0, 1.0);
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse_scale_texture.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse_scale_texture.glsl index 0b4a811..4676e51 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse_scale_texture.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_ellipse_scale_texture.glsl
@@ -27,7 +27,7 @@ highp float implicit = dot(Z, d) - 1.0; highp float grad_dot = 4.0 * dot(Z, Z); { - grad_dot = max(grad_dot, 6.1036000261083245e-05); + grad_dot = max(grad_dot, 6.103600026108325e-05); } highp float approx_dist = implicit * inversesqrt(grad_dot); {
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew.glsl index 53a0a74..32a6af2 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew.glsl
@@ -18,9 +18,9 @@ { texColor = texture2D(uTextureSampler_0_Stage0, uv).wwww; } - mediump float distance = 7.96875 * (texColor.x - 0.50196081399917603); + mediump float distance = 7.96875 * (texColor.x - 0.501960813999176); mediump float afwidth; - afwidth = abs(0.64999997615814209 * -dFdy(vIntTextureCoords_Stage0.y)); + afwidth = abs(0.6499999761581421 * -dFdy(vIntTextureCoords_Stage0.y)); mediump float val = smoothstep(-afwidth, afwidth, distance); outputCoverage_Stage0 = vec4(val); }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_2.glsl index 1b61907..7c4db08 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_2.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_2.glsl
@@ -18,9 +18,9 @@ { texColor = texture2D(uTextureSampler_0_Stage0, uv).wwww; } - mediump float distance = 7.96875 * (texColor.x - 0.50196081399917603); + mediump float distance = 7.96875 * (texColor.x - 0.501960813999176); mediump float afwidth; - afwidth = abs(0.64999997615814209 * -dFdy(vIntTextureCoords_Stage0.y)); + afwidth = abs(0.6499999761581421 * -dFdy(vIntTextureCoords_Stage0.y)); mediump float val = smoothstep(-afwidth, afwidth, distance); outputCoverage_Stage0 = vec4(val); }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_3.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_3.glsl index f4db076..421494c 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_3.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_3.glsl
@@ -18,19 +18,19 @@ { texColor = texture2D(uTextureSampler_0_Stage0, uv).wwww; } - mediump float distance = 7.96875 * (texColor.x - 0.50196081399917603); + mediump float distance = 7.96875 * (texColor.x - 0.501960813999176); mediump float afwidth; mediump vec2 dist_grad = vec2(dFdx(distance), -dFdy(distance)); mediump float dg_len2 = dot(dist_grad, dist_grad); - if (dg_len2 < 9.9999997473787516e-05) { - dist_grad = vec2(0.70709997415542603, 0.70709997415542603); + if (dg_len2 < 9.999999747378752e-05) { + dist_grad = vec2(0.707099974155426, 0.707099974155426); } else { dist_grad = dist_grad * inversesqrt(dg_len2); } mediump vec2 Jdx = dFdx(vIntTextureCoords_Stage0); mediump vec2 Jdy = -dFdy(vIntTextureCoords_Stage0); mediump vec2 grad = vec2(dist_grad.x * Jdx.x + dist_grad.y * Jdy.x, dist_grad.x * Jdx.y + dist_grad.y * Jdy.y); - afwidth = 0.64999997615814209 * length(grad); + afwidth = 0.6499999761581421 * length(grad); mediump float val = smoothstep(-afwidth, afwidth, distance); outputCoverage_Stage0 = vec4(val); }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_4.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_4.glsl index 20eef11..663553b 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_4.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_4.glsl
@@ -18,10 +18,10 @@ { texColor = texture2D(uTextureSampler_0_Stage0, uv).wwww; } - mediump float distance = 7.96875 * (texColor.x - 0.50196081399917603); + mediump float distance = 7.96875 * (texColor.x - 0.501960813999176); mediump float afwidth; mediump float st_grad_len = length(-dFdy(vIntTextureCoords_Stage0)); - afwidth = abs(0.64999997615814209 * st_grad_len); + afwidth = abs(0.6499999761581421 * st_grad_len); mediump float val = smoothstep(-afwidth, afwidth, distance); outputCoverage_Stage0 = vec4(val); }
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_5.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_5.glsl index ac92c03..80cd4a3 100644 --- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_5.glsl +++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_color_texindex_texturew_5.glsl
@@ -18,10 +18,10 @@ { texColor = texture2D(uTextureSampler_0_Stage0, uv).wwww; } - mediump float distance = 7.96875 * (texColor.x - 0.50196081399917603); + mediump float distance = 7.96875 * (texColor.x - 0.501960813999176); mediump float afwidth; mediump float st_grad_len = length(-dFdy(vIntTextureCoords_Stage0)); - afwidth = abs(0.64999997615814209 * st_grad_len); + afwidth = abs(0.6499999761581421 * st_grad_len); mediump float val = smoothstep(-afwidth, afwidth, distance); outputCoverage_Stage0 = vec4(val); }
diff --git a/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc b/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc index ac3cb80..3c20715 100644 --- a/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc +++ b/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc
@@ -20,6 +20,7 @@ #include <string> #include <vector> +#include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "cobalt/extension/graphics.h" #include "cobalt/math/size.h" @@ -364,28 +365,31 @@ graphics_extension->GetMapToMeshColorAdjustments(&color_adjustment)) { // Setup vectors for the color adjustments. Ensure they use dot for decimal // point regardless of locale. - std::stringstream buffer; - buffer.imbue(std::locale::classic()); - buffer << " vec4 scale0 = vec4(" << color_adjustment.rgba0_scale[0] << "," - << color_adjustment.rgba0_scale[1] << "," - << color_adjustment.rgba0_scale[2] << "," - << color_adjustment.rgba0_scale[3] << ");"; - buffer << " vec4 scale1 = vec4(" << color_adjustment.rgba1_scale[0] << "," - << color_adjustment.rgba1_scale[1] << "," - << color_adjustment.rgba1_scale[2] << "," - << color_adjustment.rgba1_scale[3] << ");"; - buffer << " vec4 scale2 = vec4(" << color_adjustment.rgba2_scale[0] << "," - << color_adjustment.rgba2_scale[1] << "," - << color_adjustment.rgba2_scale[2] << "," - << color_adjustment.rgba2_scale[3] << ");"; - buffer << " vec4 scale3 = vec4(" << color_adjustment.rgba3_scale[0] << "," - << color_adjustment.rgba3_scale[1] << "," - << color_adjustment.rgba3_scale[2] << "," - << color_adjustment.rgba3_scale[3] << ");"; + std::string buffer; + buffer = " vec4 scale0 = vec4(" + + base::NumberToString(color_adjustment.rgba0_scale[0]) + "," + + base::NumberToString(color_adjustment.rgba0_scale[1]) + "," + + base::NumberToString(color_adjustment.rgba0_scale[2]) + "," + + base::NumberToString(color_adjustment.rgba0_scale[3]) + ");" + + " vec4 scale1 = vec4(" + + base::NumberToString(color_adjustment.rgba1_scale[0]) + "," + + base::NumberToString(color_adjustment.rgba1_scale[1]) + "," + + base::NumberToString(color_adjustment.rgba1_scale[2]) + "," + + base::NumberToString(color_adjustment.rgba1_scale[3]) + ");" + + " vec4 scale2 = vec4(" + + base::NumberToString(color_adjustment.rgba2_scale[0]) + "," + + base::NumberToString(color_adjustment.rgba2_scale[1]) + "," + + base::NumberToString(color_adjustment.rgba2_scale[2]) + "," + + base::NumberToString(color_adjustment.rgba2_scale[3]) + ");" + + " vec4 scale3 = vec4(" + + base::NumberToString(color_adjustment.rgba3_scale[0]) + "," + + base::NumberToString(color_adjustment.rgba3_scale[1]) + "," + + base::NumberToString(color_adjustment.rgba3_scale[2]) + "," + + base::NumberToString(color_adjustment.rgba3_scale[3]) + ");"; blit_fragment_shader_source += " vec4 color2 = color * color;" " vec4 color3 = color2 * color;" + - buffer.str() + + buffer + " color = scale0 + scale1*color + scale2*color2 + scale3*color3;" " gl_FragColor = clamp(color, vec4(0.0), vec4(1.0));" "}";
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/skia.gyp b/src/cobalt/renderer/rasterizer/skia/skia/skia.gyp index dfefca6..5fe1b23 100644 --- a/src/cobalt/renderer/rasterizer/skia/skia/skia.gyp +++ b/src/cobalt/renderer/rasterizer/skia/skia/skia.gyp
@@ -28,6 +28,7 @@ 'target_name': 'skia_library', 'type': 'static_library', 'dependencies': [ + '<(DEPTH)/base/base.gyp:base', 'skia_library_no_asan', ], 'includes': [ @@ -65,7 +66,6 @@ 'target_name': 'filter_fuzz_stub', 'type': 'executable', 'dependencies': [ - '<(DEPTH)/base/base.gyp:base', 'skia', ], 'sources': [
diff --git a/src/cobalt/site/docs/contributors/index.md b/src/cobalt/site/docs/contributors/index.md index ea93cc6..77811fa 100644 --- a/src/cobalt/site/docs/contributors/index.md +++ b/src/cobalt/site/docs/contributors/index.md
@@ -52,7 +52,7 @@ * Ensure you or your company have signed the appropriate CLA as discussed in the [Before You Contribute](#before-you-contribute) section above. * Rebase your changes down into a single git commit. -* Run `git cl upload` to upload the review to +* Run `git push origin HEAD:refs/for/master` to upload the review to [Cobalt's Gerrit instance](https://cobalt-review.googlesource.com/). * Someone from the maintainers team reviews the code, adding comments on any things that need to change before the code can be submitted.
diff --git a/src/cobalt/updater/network_fetcher.cc b/src/cobalt/updater/network_fetcher.cc index fb7ea98..1dfbc7c 100644 --- a/src/cobalt/updater/network_fetcher.cc +++ b/src/cobalt/updater/network_fetcher.cc
@@ -129,6 +129,13 @@ url_fetcher_->Start(); } +void NetworkFetcher::CancelDownloadToFile() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + SB_LOG(INFO) << "Canceling DownloadToFile"; + url_fetcher_.reset(); +} + void NetworkFetcher::OnURLFetchResponseStarted(const net::URLFetcher* source) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); std::move(response_started_callback_)
diff --git a/src/cobalt/updater/network_fetcher.h b/src/cobalt/updater/network_fetcher.h index 1ff2675..17b8909 100644 --- a/src/cobalt/updater/network_fetcher.h +++ b/src/cobalt/updater/network_fetcher.h
@@ -69,6 +69,7 @@ ProgressCallback progress_callback, DownloadToFileCompleteCallback download_to_file_complete_callback) override; + void CancelDownloadToFile() override; // net::URLFetcherDelegate interface. void OnURLFetchResponseStarted(const net::URLFetcher* source) override;
diff --git a/src/cobalt/updater/updater_module.cc b/src/cobalt/updater/updater_module.cc index 8f5663f..3941cb6 100644 --- a/src/cobalt/updater/updater_module.cc +++ b/src/cobalt/updater/updater_module.cc
@@ -174,6 +174,7 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); update_client_->RemoveObserver(updater_observer_.get()); updater_observer_.reset(); + update_client_->Stop(); update_client_ = nullptr; if (updater_configurator_ != nullptr) {
diff --git a/src/cobalt/version.h b/src/cobalt/version.h index 9e20fe2..e014a72 100644 --- a/src/cobalt/version.h +++ b/src/cobalt/version.h
@@ -35,6 +35,6 @@ // release is cut. //. -#define COBALT_VERSION "21.lts.4" +#define COBALT_VERSION "21.lts.5" #endif // COBALT_VERSION_H_
diff --git a/src/cobalt/webdriver/protocol/moveto.cc b/src/cobalt/webdriver/protocol/moveto.cc index a8a10f9..d9eb35e 100644 --- a/src/cobalt/webdriver/protocol/moveto.cc +++ b/src/cobalt/webdriver/protocol/moveto.cc
@@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "cobalt/webdriver/protocol/moveto.h" + #include <memory> #include <string> - -#include "cobalt/webdriver/protocol/moveto.h" +#include <utility> namespace cobalt { namespace webdriver { @@ -43,7 +44,7 @@ } base::Optional<Moveto> Moveto::FromValue(const base::Value* value) { - const base::DictionaryValue* dictionary_value; + const base::DictionaryValue* dictionary_value = nullptr; if (!value->GetAsDictionary(&dictionary_value)) { return base::nullopt; } @@ -53,6 +54,12 @@ if (dictionary_value->GetString(kElementKey, &element_id) && !element_id.empty()) { element = ElementId(element_id); + } else { + const base::Value* element_value = + value->FindKeyOfType(kElementKey, base::Value::Type::DICTIONARY); + if (element_value) { + element = ElementId::FromValue(element_value); + } } int xoffset_value = 0;
diff --git a/src/cobalt/webdriver/testdata/simple_test.py b/src/cobalt/webdriver/testdata/simple_test.py index d2cea99..bf532b0 100755 --- a/src/cobalt/webdriver/testdata/simple_test.py +++ b/src/cobalt/webdriver/testdata/simple_test.py
@@ -29,6 +29,37 @@ POST = 'POST' DELETE = 'DELETE' +# WebDriver Response Status Codes: +# https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#Response-Status-Codes + +RESPONSE_STATUS_CODES = { + 0: 'Success', + 6: 'No Such Driver', + 7: 'No Such Element', + 8: 'No Such Frame', + 9: 'Unknown Command', + 10: 'Stale Element Reference', + 11: 'Element Not Visible', + 12: 'Invalid Element State', + 13: 'Unknown Error', + 15: 'Element Is Not Selectable', + 17: 'JavaScript Error', + 19: 'XPath Lookup Error', + 21: 'Timeout', + 23: 'No Such Window', + 24: 'Invalid Cookie Domain', + 25: 'Unable To Set Cookie', + 26: 'Unexpected Alert Open', + 27: 'No Alert Open Error', + 28: 'Script Timeout', + 29: 'Invalid Element Coordinates', + 30: 'IME Not Available', + 31: 'IME Engine Activation Failed', + 32: 'Invalid Selector', + 33: 'Session Not Created Exception', + 34: 'Move Target Out Of Bounds' +} + def Request(request_type, path='', parameters=None): """Perform a WebDriver JSON Wire Protocol Request. @@ -54,8 +85,11 @@ if request.status_code == 200: return result else: - print '*** Error %d: %s' % (request.status_code, result['value']['message'] - if isinstance(result, dict) else result) + print('*** Error %d %s: \"%s\"' % + (request.status_code, RESPONSE_STATUS_CODES[result['status']] + if isinstance(result, dict) else 'unknown', + result['value']['message'] if isinstance(result, dict) else result)) + print('*** Error %d: %s' % (request.status_code, result)) return None @@ -82,8 +116,9 @@ request_type, path=None, parameters=None): - return SessionRequest(session_id, request_type, 'element/%s/%s' % - (element_id[u'ELEMENT'], path), parameters) + return SessionRequest(session_id, request_type, + 'element/%s/%s' % (element_id[u'ELEMENT'], path), + parameters) def GetSessionID(): @@ -129,6 +164,20 @@ f.close() +def GetElementScreenShot(session_id, element_id, filename): + """Retrieve a Screenshot. + + Args: + session_id: Value for ':sessionId' for the request + filename: The filename to write the PNG screenshot to + """ + request = ElementRequest(session_id, element_id, GET, 'screenshot') + if request: + with open(filename, 'w') as f: + f.write(binascii.a2b_base64(request['value'])) + f.close() + + def GetActiveElement(session_id): return SessionRequest(session_id, POST, 'element/active')['value'] @@ -171,32 +220,97 @@ def ElementFind(session_id, using, value): - return SessionRequest(session_id, POST, 'element', - {u'using': using, - u'value': value})['value'] + result = SessionRequest(session_id, POST, 'element', { + u'using': using, + u'value': value + }) + return None if result is None else result['value'] def MouseTest(): # Do a simple test that hovers the mouse to the right from the active # element, then clicks on the element of class 'trending'. session_id = GetSessionID() - active_element = GetActiveElement(session_id) - print 'active_element : %s' % active_element + try: + active_element = GetActiveElement(session_id) + print('active_element : %s' % active_element) - for xoffset in range(0, 1900, 20): - print 'Moveto: %s' % Moveto(session_id, active_element, xoffset, 200) - time.sleep(0.05) + for xoffset in range(0, 1900, 20): + print('Moveto: %s' % Moveto(session_id, active_element, xoffset, 200)) + time.sleep(0.05) - trending_element = ElementFind(session_id, 'class name', 'trending') - print 'trending_element : %s' % trending_element + selected_element = ElementFind(session_id, 'class name', + 'ytlr-tile-renderer--focused') + print('selected_element : %s' % selected_element) - print 'ElementClick: %s' % ElementClick(session_id, trending_element, 0) + print('ElementClick: %s' % ElementClick(session_id, selected_element, 0)) + + except KeyboardInterrupt: + print('Bye') DeleteSession(session_id) +def ElementScreenShotTest(): + # Do a simple test that hovers the mouse to the right from the active + # element, then clicks on the element of class 'trending'. + session_id = GetSessionID() + try: + selected_element = ElementFind(session_id, 'class name', + 'ytlr-tile-renderer--focused') + print('Selected List element : %s' % selected_element) + + # Write screenshots for the selected element, until interrupted. + while True: + selected_element = ElementFind(session_id, 'class name', + 'ytlr-tile-renderer--focused') + print('Selected List element : %s' % selected_element) + if selected_element is not None: + print('GetElementScreenShot: %s' % GetElementScreenShot( + session_id, selected_element, + 'element-' + selected_element['ELEMENT'] + '.png')) + + except KeyboardInterrupt: + print('Bye') + + DeleteSession(session_id) + + +def ElementUniqueTest(): + # Do a simple test that keeps running as long as the element IDs stay the + # same. + session_id = GetSessionID() + try: + initial_active_element = GetActiveElement(session_id) + print('initial active_element : %s' % initial_active_element) + + initial_selected_element = ElementFind(session_id, 'class name', + 'ytlr-tile-renderer--focused') + print('Selected List element : %s' % initial_selected_element) + while True: + active_element = GetActiveElement(session_id) + print('active_element : %s' % active_element) + + if initial_active_element != active_element: + break + + selected_element = ElementFind(session_id, 'class name', + 'ytlr-tile-renderer--focused') + print('Selected List element : %s' % selected_element) + + if initial_selected_element != selected_element: + break + + time.sleep(1) + + except KeyboardInterrupt: + print('Bye') + + def main(): MouseTest() + ElementScreenShotTest() + # ElementUniqueTest() if __name__ == '__main__':
diff --git a/src/cobalt/webdriver/window_driver.cc b/src/cobalt/webdriver/window_driver.cc index 483b6d2..1cb4432 100644 --- a/src/cobalt/webdriver/window_driver.cc +++ b/src/cobalt/webdriver/window_driver.cc
@@ -399,6 +399,14 @@ protocol::ElementId WindowDriver::ElementToId( const scoped_refptr<dom::Element>& element) { DCHECK_EQ(base::MessageLoop::current()->task_runner(), window_task_runner_); + for (auto i : element_drivers_) { + // Note: The element_task_runner_ is the same as the window_task_runner_. + auto weak_element = i.second->GetWeakElement(); + if (element == weak_element) { + return i.second->element_id(); + } + } + return CreateNewElementDriver(base::AsWeakPtr(element.get())); }
diff --git a/src/components/update_client/component.cc b/src/components/update_client/component.cc index 3e23074..21a74f0 100644 --- a/src/components/update_client/component.cc +++ b/src/components/update_client/component.cc
@@ -300,6 +300,13 @@ base::BindOnce(&Component::ChangeState, base::Unretained(this))); } +#if defined(STARBOARD) +void Component::Cancel() { + DCHECK(thread_checker_.CalledOnValidThread()); + state_->Cancel(); +} +#endif + void Component::ChangeState(std::unique_ptr<State> next_state) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -532,6 +539,14 @@ DoHandle(); } +#if defined(STARBOARD) +void Component::State::Cancel() { + DCHECK(thread_checker_.CalledOnValidThread()); + // Further work may be needed to ensure cancelation during any state results + // in a clear result and no memory leaks. +} +#endif + void Component::State::TransitionState(std::unique_ptr<State> next_state) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(next_state); @@ -726,6 +741,13 @@ DCHECK(thread_checker_.CalledOnValidThread()); } +#if defined(STARBOARD) +void Component::StateDownloadingDiff::Cancel() { + DCHECK(thread_checker_.CalledOnValidThread()); + crx_downloader_->CancelDownload(); +} +#endif + void Component::StateDownloadingDiff::DoHandle() { DCHECK(thread_checker_.CalledOnValidThread()); @@ -800,6 +822,13 @@ DCHECK(thread_checker_.CalledOnValidThread()); } +#if defined(STARBOARD) +void Component::StateDownloading::Cancel() { + DCHECK(thread_checker_.CalledOnValidThread()); + crx_downloader_->CancelDownload(); +} +#endif + void Component::StateDownloading::DoHandle() { DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/src/components/update_client/component.h b/src/components/update_client/component.h index 0f9b973..229e80e 100644 --- a/src/components/update_client/component.h +++ b/src/components/update_client/component.h
@@ -55,6 +55,12 @@ // to the next component state before |callback_handle_complete_| is invoked. void Handle(CallbackHandleComplete callback_handle_complete); +#if defined(STARBOARD) + // Stops update progress for the component and may clean resources used in its + // current state. + void Cancel(); +#endif + CrxUpdateItem GetCrxUpdateItem() const; // Sets the uninstall state for this component. @@ -156,6 +162,11 @@ // by the outer component, after the current state is fully handled. void Handle(CallbackNextState callback); +#if defined(STARBOARD) + // Stops update progress and may clean resources used in the current state. + virtual void Cancel(); +#endif + ComponentState state() const { return state_; } protected: @@ -247,6 +258,9 @@ public: explicit StateDownloadingDiff(Component* component); ~StateDownloadingDiff() override; +#if defined(STARBOARD) + void Cancel() override; +#endif private: // State overrides. @@ -270,6 +284,9 @@ public: explicit StateDownloading(Component* component); ~StateDownloading() override; +#if defined(STARBOARD) + void Cancel() override; +#endif private: // State overrides.
diff --git a/src/components/update_client/crx_downloader.cc b/src/components/update_client/crx_downloader.cc index bac3857..1e347d6 100644 --- a/src/components/update_client/crx_downloader.cc +++ b/src/components/update_client/crx_downloader.cc
@@ -120,6 +120,12 @@ DoStartDownload(*current_url_); } +#if defined(STARBOARD) +void CrxDownloader::CancelDownload() { + DoCancelDownload(); +} +#endif + void CrxDownloader::OnDownloadComplete( bool is_handled, const Result& result,
diff --git a/src/components/update_client/crx_downloader.h b/src/components/update_client/crx_downloader.h index 3b46799..2db575a 100644 --- a/src/components/update_client/crx_downloader.h +++ b/src/components/update_client/crx_downloader.h
@@ -122,6 +122,10 @@ const std::string& expected_hash, DownloadCallback download_callback); +#if defined(STARBOARD) + void CancelDownload(); +#endif + const std::vector<DownloadMetrics> download_metrics() const; protected: @@ -151,6 +155,9 @@ private: virtual void DoStartDownload(const GURL& url) = 0; +#if defined(STARBOARD) + virtual void DoCancelDownload() = 0; +#endif void VerifyResponse(bool is_handled, Result result,
diff --git a/src/components/update_client/network.h b/src/components/update_client/network.h index daed162..dec108f 100644 --- a/src/components/update_client/network.h +++ b/src/components/update_client/network.h
@@ -63,6 +63,9 @@ ResponseStartedCallback response_started_callback, ProgressCallback progress_callback, DownloadToFileCompleteCallback download_to_file_complete_callback) = 0; +#if defined(STARBOARD) + virtual void CancelDownloadToFile() = 0; +#endif protected: NetworkFetcher() = default;
diff --git a/src/components/update_client/task_update.cc b/src/components/update_client/task_update.cc index ab445b5..0129e4c 100644 --- a/src/components/update_client/task_update.cc +++ b/src/components/update_client/task_update.cc
@@ -36,13 +36,25 @@ return; } +#if defined(STARBOARD) + update_engine_->Update(is_foreground_, ids_, std::move(crx_data_callback_), + base::BindOnce(&TaskUpdate::TaskComplete, this), + cancelation_closure_); +#else update_engine_->Update(is_foreground_, ids_, std::move(crx_data_callback_), base::BindOnce(&TaskUpdate::TaskComplete, this)); +#endif } void TaskUpdate::Cancel() { DCHECK(thread_checker_.CalledOnValidThread()); +#if defined(STARBOARD) + if (cancelation_closure_) { // The engine's picked up the task. + std::move(cancelation_closure_).Run(); + } +#endif + TaskComplete(Error::UPDATE_CANCELED); }
diff --git a/src/components/update_client/task_update.h b/src/components/update_client/task_update.h index 4df796b..74c0a6a 100644 --- a/src/components/update_client/task_update.h +++ b/src/components/update_client/task_update.h
@@ -57,6 +57,9 @@ const std::vector<std::string> ids_; UpdateClient::CrxDataCallback crx_data_callback_; Callback callback_; +#if defined(STARBOARD) + base::OnceClosure cancelation_closure_; +#endif DISALLOW_COPY_AND_ASSIGN(TaskUpdate); };
diff --git a/src/components/update_client/update_client.cc b/src/components/update_client/update_client.cc index 369c6d3..6ce65bf 100644 --- a/src/components/update_client/update_client.cc +++ b/src/components/update_client/update_client.cc
@@ -201,6 +201,16 @@ is_stopped_ = true; + // Cancel the pending tasks. These tasks are safe to cancel and delete since + // they have not picked up by the update engine, and not shared with any + // task runner yet. + while (!task_queue_.empty()) { + auto task = task_queue_.front(); + task_queue_.pop_front(); + task->Cancel(); + } + +#if !defined(STARBOARD) // In the current implementation it is sufficient to cancel the pending // tasks only. The tasks that are run by the update engine will stop // making progress naturally, as the main task runner stops running task @@ -210,15 +220,15 @@ // area, to cancel the running tasks by canceling the current action update. // This behavior would be expected, correct, and result in no resource leaks // in all cases, in shutdown or not. - // - // Cancel the pending tasks. These tasks are safe to cancel and delete since - // they have not picked up by the update engine, and not shared with any - // task runner yet. - while (!task_queue_.empty()) { - auto task = task_queue_.front(); - task_queue_.pop_front(); +#else + // For Cobalt it's not sufficient to just let the tasks already picked up by + // the update engine stop naturally, as this can result in resource leaks and + // crashes. These tasks are also canceled so that any necessary cleanup can be + // done. + for (auto task : tasks_) { task->Cancel(); } +#endif } void UpdateClientImpl::SendUninstallPing(const std::string& id,
diff --git a/src/components/update_client/update_engine.cc b/src/components/update_client/update_engine.cc index a6d6920..29c260b 100644 --- a/src/components/update_client/update_engine.cc +++ b/src/components/update_client/update_engine.cc
@@ -72,10 +72,19 @@ DCHECK(thread_checker_.CalledOnValidThread()); } +#if !defined(STARBOARD) void UpdateEngine::Update(bool is_foreground, const std::vector<std::string>& ids, UpdateClient::CrxDataCallback crx_data_callback, Callback callback) { +#else +void UpdateEngine::Update(bool is_foreground, + const std::vector<std::string>& ids, + UpdateClient::CrxDataCallback crx_data_callback, + Callback callback, + base::OnceClosure& cancelation_closure) { + +#endif DCHECK(thread_checker_.CalledOnValidThread()); if (ids.empty()) { @@ -100,6 +109,10 @@ config_, is_foreground, ids, std::move(crx_data_callback), notify_observers_callback_, std::move(callback), crx_downloader_factory_); DCHECK(!update_context->session_id.empty()); +#if defined(STARBOARD) + cancelation_closure = base::BindOnce(&UpdateEngine::Cancel, this, + update_context->session_id, ids); +#endif const auto result = update_contexts_.insert( std::make_pair(update_context->session_id, update_context)); @@ -405,6 +418,17 @@ now < throttle_updates_until_; } +#if defined(STARBOARD) +void UpdateEngine::Cancel(const std::string& update_context_session_id, + const std::vector<std::string>& crx_component_ids) { + const auto& context = update_contexts_.at(update_context_session_id); + for (const auto& crx_component_id : crx_component_ids) { + auto& component = context->components.at(crx_component_id); + component->Cancel(); + } +} +#endif + void UpdateEngine::SendUninstallPing(const std::string& id, const base::Version& version, int reason,
diff --git a/src/components/update_client/update_engine.h b/src/components/update_client/update_engine.h index 9601873..4384fa8 100644 --- a/src/components/update_client/update_engine.h +++ b/src/components/update_client/update_engine.h
@@ -56,10 +56,20 @@ // is not found. bool GetUpdateState(const std::string& id, CrxUpdateItem* update_state); +#if !defined(STARBOARD) void Update(bool is_foreground, const std::vector<std::string>& ids, UpdateClient::CrxDataCallback crx_data_callback, Callback update_callback); +#else + // |cancelation_closure| is populated with a closure that can be run to cancel + // the update requested by the caller. + void Update(bool is_foreground, + const std::vector<std::string>& ids, + UpdateClient::CrxDataCallback crx_data_callback, + Callback update_callback, + base::OnceClosure& cancelation_closure); +#endif void SendUninstallPing(const std::string& id, const base::Version& version, @@ -96,6 +106,14 @@ // occurs too soon. bool IsThrottled(bool is_foreground) const; +#if defined(STARBOARD) + // Cancels updates currently handled by the engine for each component + // identified by one of |crx_component_ids| for the update context identified + // by the |update_context_session_id|. + void Cancel(const std::string& update_context_session_id, + const std::vector<std::string>& crx_component_ids); +#endif + base::ThreadChecker thread_checker_; scoped_refptr<Configurator> config_; UpdateChecker::Factory update_checker_factory_;
diff --git a/src/components/update_client/url_fetcher_downloader.cc b/src/components/update_client/url_fetcher_downloader.cc index f94b010..f940e2e 100644 --- a/src/components/update_client/url_fetcher_downloader.cc +++ b/src/components/update_client/url_fetcher_downloader.cc
@@ -144,6 +144,13 @@ #endif } +#if defined(STARBOARD) +void UrlFetcherDownloader::DoCancelDownload() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + network_fetcher_->CancelDownloadToFile(); +} +#endif + void UrlFetcherDownloader::CreateDownloadDir() { base::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_url_fetcher_"), &download_dir_);
diff --git a/src/components/update_client/url_fetcher_downloader.h b/src/components/update_client/url_fetcher_downloader.h index fc32732..ea7f29d 100644 --- a/src/components/update_client/url_fetcher_downloader.h +++ b/src/components/update_client/url_fetcher_downloader.h
@@ -42,6 +42,9 @@ private: // Overrides for CrxDownloader. void DoStartDownload(const GURL& url) override; +#if defined(STARBOARD) + void DoCancelDownload() override; +#endif void CreateDownloadDir(); void StartURLFetch(const GURL& url);
diff --git a/src/docker/linux/base/build/Dockerfile b/src/docker/linux/base/build/Dockerfile index 545908d..8d60ad9 100644 --- a/src/docker/linux/base/build/Dockerfile +++ b/src/docker/linux/base/build/Dockerfile
@@ -2,10 +2,15 @@ FROM ${FROM_IMAGE:-cobalt-base} # === Get Nodejs pinned LTS version via NVM +ARG NVM_SHA256SUM="f068e17dacb88f73302790cc076956c7a0d459ce9b01df842ff3e75744f9e2fe /tmp/install.sh" +ARG NVM_URL="https://cobalt.googlesource.com/third_party/nvm/+/refs/tags/v0.35.3/install.sh?format=TEXT" ENV NVM_DIR /root/.nvm ENV NODE_VERSION 12.17.0 -RUN curl --silent -o- https://raw.githubusercontent.com/creationix/nvm/v0.35.3/install.sh | bash +RUN curl --silent -o- ${NVM_URL} \ + | base64 -d > /tmp/install.sh \ + && echo ${NVM_SHA256SUM} | sha256sum --check \ + && . /tmp/install.sh RUN . $NVM_DIR/nvm.sh \ && nvm install --lts \
diff --git a/src/requirements.txt b/src/requirements.txt index e9215ea..b666306 100644 --- a/src/requirements.txt +++ b/src/requirements.txt
@@ -2,3 +2,4 @@ pre-commit==2.6.0 pylint==2.6.0 yapf==0.30.0 +requests==2.25.1
diff --git a/src/starboard/android/apk/build.id b/src/starboard/android/apk/build.id deleted file mode 100644 index 772184d..0000000 --- a/src/starboard/android/apk/build.id +++ /dev/null
@@ -1 +0,0 @@ -302879 \ No newline at end of file
diff --git a/src/starboard/build/collect_deploy_content.gypi b/src/starboard/build/collect_deploy_content.gypi index 6bee14a..a9a5064 100644 --- a/src/starboard/build/collect_deploy_content.gypi +++ b/src/starboard/build/collect_deploy_content.gypi
@@ -46,6 +46,11 @@ 'collect_deploy_content_extra_args': [ '--use_absolute_symlinks' ], } }], + ['cobalt_docker_build == 1 and host_os == "win"', { + 'variables': { + 'collect_deploy_content_extra_args': [ '--copy_override' ], + } + }], ], 'actions': [{ 'action_name': 'collect_deploy_content',
diff --git a/src/starboard/build/collect_deploy_content.py b/src/starboard/build/collect_deploy_content.py index 8d3fffd..49bf9af 100644 --- a/src/starboard/build/collect_deploy_content.py +++ b/src/starboard/build/collect_deploy_content.py
@@ -17,6 +17,7 @@ import argparse import logging import os +import shutil import sys import _env # pylint: disable=unused-import @@ -39,6 +40,21 @@ port_symlink.Rmtree(path) +def _CopyTree(src_path, dst_path): + """ + Copy tree with a safeguard for windows long path (>260). + On Windows Python is facing long path limitation, for more details see + https://bugs.python.org/issue27730 + """ + if os.sep == r'\\': + prefix = r'\\\\?\\' + if prefix not in src_path: + src_path = prefix + src_path + if prefix not in dst_path: + dst_path = prefix + dst_path + shutil.copytree(src_path, dst_path) + + def main(argv): parser = argparse.ArgumentParser() parser.add_argument( @@ -59,6 +75,11 @@ metavar='subdirs', nargs='*', help='subdirectories within both the input and output directories') + parser.add_argument( + '--copy_override', + action='store_true', + help='Overrides the behavior of collect_deploy_content to copy files, ' + 'instead of symlinking them.') options = parser.parse_args(argv[1:]) if os.environ.get(_SHOULD_LOG_ENV_KEY, None) == '1': @@ -107,7 +128,9 @@ msg += ' path points to an unknown type' logging.error(msg) - if options.use_absolute_symlinks: + if options.copy_override: + _CopyTree(src_path, dst_path) + elif options.use_absolute_symlinks: port_symlink.MakeSymLink( target_path=os.path.abspath(src_path), link_path=os.path.abspath(dst_path))
diff --git a/src/starboard/common/log.h b/src/starboard/common/log.h index f1ec6b9..596dbc6 100644 --- a/src/starboard/common/log.h +++ b/src/starboard/common/log.h
@@ -168,8 +168,10 @@ #if SB_LOGGING_IS_OFFICIAL_BUILD || \ (defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)) #define SB_DCHECK(condition) SB_EAT_STREAM_PARAMETERS +#define SB_DCHECK_ENABLED 0 #else #define SB_DCHECK(condition) SB_CHECK(condition) +#define SB_DCHECK_ENABLED 1 #endif #define SB_DLOG(severity) SB_DLOG_IF(severity, SB_DLOG_IS_ON(severity)) @@ -224,8 +226,10 @@ #if SB_LOGGING_IS_OFFICIAL_BUILD #define SB_NOTIMPLEMENTED() #define SB_DCHECK(condition) +#define SB_DCHECK_ENABLED 0 #else #define SB_DCHECK(condition) SB_CHECK(condition) +#define SB_DCHECK_ENABLED 1 #define SB_NOTIMPLEMENTED() \ do { \ static int count = 0; \
diff --git a/src/starboard/linux/shared/gyp_configuration.py b/src/starboard/linux/shared/gyp_configuration.py index b8f0949..4e4a96c 100644 --- a/src/starboard/linux/shared/gyp_configuration.py +++ b/src/starboard/linux/shared/gyp_configuration.py
@@ -121,3 +121,10 @@ 'VideoDecoderTests/VideoDecoderTest.*Invalid*', ], } + # Conditionally disables tests that require ipv6 + if os.getenv('IPV6_AVAILABLE', 1) == '0': + __FILTERED_TESTS['nplb'] = [ + 'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDayDestination/1', + 'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDaySourceForDestination/1', + 'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDaySourceNotLoopback/1', + ]
diff --git a/src/starboard/nplb/nplb_evergreen_compat_tests/crashpad_config_test.cc b/src/starboard/nplb/nplb_evergreen_compat_tests/crashpad_config_test.cc new file mode 100644 index 0000000..ca4ee47 --- /dev/null +++ b/src/starboard/nplb/nplb_evergreen_compat_tests/crashpad_config_test.cc
@@ -0,0 +1,61 @@ +// 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 <string> +#include <vector> + +#include "cobalt/extension/crash_handler.h" +#include "starboard/nplb/nplb_evergreen_compat_tests/checks.h" +#include "starboard/system.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if SB_IS(EVERGREEN_COMPATIBLE) + +namespace starboard { +namespace nplb { +namespace nplb_evergreen_compat_tests { + +namespace { + +class CrashpadConfigTest : public ::testing::Test { + protected: + CrashpadConfigTest() {} + ~CrashpadConfigTest() {} +}; + +TEST_F(CrashpadConfigTest, VerifyUploadCert) { + std::vector<char> buffer(kSbFileMaxPath); + ASSERT_TRUE(SbSystemGetPath(kSbSystemPathContentDirectory, buffer.data(), + buffer.size())); + + std::string cert_location(buffer.data()); + cert_location.append(std::string(kSbFileSepString) + "app" + + kSbFileSepString + "cobalt" + kSbFileSepString + + "content" + kSbFileSepString + "ssl" + kSbFileSepString + + "certs"); + ASSERT_TRUE(SbFileExists(cert_location.c_str())); +} + +TEST_F(CrashpadConfigTest, VerifyCrashHandlerExtension) { + auto crash_handler_extension = + SbSystemGetExtension(kCobaltExtensionCrashHandlerName); + ASSERT_TRUE(crash_handler_extension != nullptr); +} + +} // namespace +} // namespace nplb_evergreen_compat_tests +} // namespace nplb +} // namespace starboard + +#endif // SB_IS(EVERGREEN_COMPATIBLE)
diff --git a/src/starboard/nplb/nplb_evergreen_compat_tests/nplb_evergreen_compat_tests.gyp b/src/starboard/nplb/nplb_evergreen_compat_tests/nplb_evergreen_compat_tests.gyp index 4e292f8..1f2b9a73 100644 --- a/src/starboard/nplb/nplb_evergreen_compat_tests/nplb_evergreen_compat_tests.gyp +++ b/src/starboard/nplb/nplb_evergreen_compat_tests/nplb_evergreen_compat_tests.gyp
@@ -19,6 +19,7 @@ 'type': '<(gtest_target_type)', 'sources': [ 'checks.h', + 'crashpad_config_test.cc', 'executable_memory_test.cc', 'fonts_test.cc', 'sabi_test.cc',
diff --git a/src/third_party/crashpad/handler/handler.gyp b/src/third_party/crashpad/handler/handler.gyp index effe9e1..1275a4d 100644 --- a/src/third_party/crashpad/handler/handler.gyp +++ b/src/third_party/crashpad/handler/handler.gyp
@@ -89,8 +89,21 @@ 'sources': [ 'main.cc', ], - 'conditions': [ + # Help platforms cross compiled on linux to reduce + # the memory footprint of crashpad_handler by eliminating + # unused code and unused shared libraries. + # The flags assume gcc/clang toolchain. + ['host_os=="linux"', { + 'cflags': [ + '-ffunction-sections', + '-fdata-sections', + ], + 'ldflags': [ + '-Wl,--as-needed', + '-Wl,-gc-sections', + ], + }], ['OS=="win"', { 'msvs_settings': { 'VCLinkerTool': {
diff --git a/src/third_party/freetype2/src/tools/Jamfile b/src/third_party/freetype2/src/tools/Jamfile new file mode 100644 index 0000000..475161e --- /dev/null +++ b/src/third_party/freetype2/src/tools/Jamfile
@@ -0,0 +1,5 @@ +# Jamfile for src/tools +# +SubDir FT2_TOP src tools ; + +Main apinames : apinames.c ;
diff --git a/src/third_party/freetype2/src/tools/afblue.pl b/src/third_party/freetype2/src/tools/afblue.pl new file mode 100644 index 0000000..bbc4f47 --- /dev/null +++ b/src/third_party/freetype2/src/tools/afblue.pl
@@ -0,0 +1,551 @@ +#! /usr/bin/perl -w +# -*- Perl -*- +# +# afblue.pl +# +# Process a blue zone character data file. +# +# Copyright (C) 2013-2020 by +# David Turner, Robert Wilhelm, and Werner Lemberg. +# +# This file is part of the FreeType project, and may only be used, +# modified, and distributed under the terms of the FreeType project +# license, LICENSE.TXT. By continuing to use, modify, or distribute +# this file you indicate that you have read the license and +# understand and accept it fully. + +use strict; +use warnings; +use English '-no_match_vars'; +use open ':std', ':encoding(UTF-8)'; + + +my $prog = $PROGRAM_NAME; +$prog =~ s| .* / ||x; # Remove path. + +die "usage: $prog datafile < infile > outfile\n" if $#ARGV != 0; + + +my $datafile = $ARGV[0]; + +my %diversions; # The extracted and massaged data from `datafile'. +my @else_stack; # Booleans to track else-clauses. +my @name_stack; # Stack of integers used for names of aux. variables. + +my $curr_enum; # Name of the current enumeration. +my $curr_array; # Name of the current array. +my $curr_max; # Name of the current maximum value. + +my $curr_enum_element; # Name of the current enumeration element. +my $curr_offset; # The offset relative to current aux. variable. +my $curr_elem_size; # The number of non-space characters in the current string or + # the number of elements in the current block. + +my $have_sections = 0; # Boolean; set if start of a section has been seen. +my $have_strings; # Boolean; set if current section contains strings. +my $have_blocks; # Boolean; set if current section contains blocks. + +my $have_enum_element; # Boolean; set if we have an enumeration element. +my $in_string; # Boolean; set if a string has been parsed. + +my $num_sections = 0; # Number of sections seen so far. + +my $last_aux; # Name of last auxiliary variable. + + +# Regular expressions. + +# [<ws>] <enum_name> <ws> <array_name> <ws> <max_name> [<ws>] ':' [<ws>] '\n' +my $section_re = qr/ ^ \s* (\S+) \s+ (\S+) \s+ (\S+) \s* : \s* $ /x; + +# [<ws>] <enum_element_name> [<ws>] '\n' +my $enum_element_re = qr/ ^ \s* ( [A-Za-z0-9_]+ ) \s* $ /x; + +# '#' <preprocessor directive> '\n' +my $preprocessor_re = qr/ ^ \# /x; + +# [<ws>] '/' '/' <comment> '\n' +my $comment_re = qr| ^ \s* // |x; + +# empty line +my $whitespace_only_re = qr/ ^ \s* $ /x; + +# [<ws>] '"' <string> '"' [<ws>] '\n' (<string> doesn't contain newlines) +my $string_re = qr/ ^ \s* + " ( (?> (?: (?> [^"\\]+ ) | \\. )* ) ) " + \s* $ /x; + +# [<ws>] '{' <block> '}' [<ws>] '\n' (<block> can contain newlines) +my $block_start_re = qr/ ^ \s* \{ /x; + +# We need the capturing group for `split' to make it return the separator +# tokens (i.e., the opening and closing brace) also. +my $brace_re = qr/ ( [{}] ) /x; + + +sub Warn +{ + my $message = shift; + warn "$datafile:$INPUT_LINE_NUMBER: warning: $message\n"; +} + + +sub Die +{ + my $message = shift; + die "$datafile:$INPUT_LINE_NUMBER: error: $message\n"; +} + + +my $warned_before = 0; + +sub warn_before +{ + Warn("data before first section gets ignored") unless $warned_before; + $warned_before = 1; +} + + +sub strip_newline +{ + chomp; + s/ \x0D $ //x; +} + + +sub end_curr_string +{ + # Append final null byte to string. + if ($have_strings) + { + push @{$diversions{$curr_array}}, " '\\0',\n" if $in_string; + + $curr_offset++; + $in_string = 0; + } +} + + +sub update_max_elem_size +{ + if ($curr_elem_size) + { + my $max = pop @{$diversions{$curr_max}}; + $max = $curr_elem_size if $curr_elem_size > $max; + push @{$diversions{$curr_max}}, $max; + } +} + + +sub convert_non_ascii_char +{ + # A UTF-8 character outside of the printable ASCII range, with possibly a + # leading backslash character. + my $s = shift; + + # Here we count characters, not bytes. + $curr_elem_size += length $s; + + utf8::encode($s); + $s = uc unpack 'H*', $s; + + $curr_offset += $s =~ s/\G(..)/'\\x$1', /sg; + + return $s; +} + + +sub convert_ascii_chars +{ + # A series of ASCII characters in the printable range. + my $s = shift; + + # We reduce multiple space characters to a single one. + $s =~ s/ +/ /g; + + # Count all non-space characters. Note that `()' applies a list context + # to the capture that is used to count the elements. + $curr_elem_size += () = $s =~ /[^ ]/g; + + $curr_offset += $s =~ s/\G(.)/'$1', /g; + + return $s; +} + + +sub convert_literal +{ + my $s = shift; + my $orig = $s; + + # ASCII printables and space + my $safe_re = '\x20-\x7E'; + # ASCII printables and space, no backslash + my $safe_no_backslash_re = '\x20-\x5B\x5D-\x7E'; + + $s =~ s{ + (?: \\? ( [^$safe_re] ) + | ( (?: [$safe_no_backslash_re] + | \\ [$safe_re] )+ ) ) + } + { + defined($1) ? convert_non_ascii_char($1) + : convert_ascii_chars($2) + }egx; + + # We assume that `$orig' doesn't contain `*/' + return $s . " /* $orig */"; +} + + +sub aux_name +{ + return "af_blue_" . $num_sections. "_" . join('_', @name_stack); +} + + +sub aux_name_next +{ + $name_stack[$#name_stack]++; + my $name = aux_name(); + $name_stack[$#name_stack]--; + + return $name; +} + + +sub enum_val_string +{ + # Build string that holds code to save the current offset in an + # enumeration element. + my $aux = shift; + + my $add = ($last_aux eq "af_blue_" . $num_sections . "_0" ) + ? "" + : "$last_aux + "; + + return " $aux = $add$curr_offset,\n"; +} + + + +# Process data file. + +open(DATA, $datafile) || die "$prog: can't open \`$datafile': $OS_ERROR\n"; + +while (<DATA>) +{ + strip_newline(); + + next if /$comment_re/; + next if /$whitespace_only_re/; + + if (/$section_re/) + { + Warn("previous section is empty") if ($have_sections + && !$have_strings + && !$have_blocks); + + end_curr_string(); + update_max_elem_size(); + + # Save captured groups from `section_re'. + $curr_enum = $1; + $curr_array = $2; + $curr_max = $3; + + $curr_enum_element = ""; + $curr_offset = 0; + + Warn("overwriting already defined enumeration \`$curr_enum'") + if exists($diversions{$curr_enum}); + Warn("overwriting already defined array \`$curr_array'") + if exists($diversions{$curr_array}); + Warn("overwriting already defined maximum value \`$curr_max'") + if exists($diversions{$curr_max}); + + $diversions{$curr_enum} = []; + $diversions{$curr_array} = []; + $diversions{$curr_max} = []; + + push @{$diversions{$curr_max}}, 0; + + @name_stack = (); + push @name_stack, 0; + + $have_sections = 1; + $have_strings = 0; + $have_blocks = 0; + + $have_enum_element = 0; + $in_string = 0; + + $num_sections++; + $curr_elem_size = 0; + + $last_aux = aux_name(); + + next; + } + + if (/$preprocessor_re/) + { + if ($have_sections) + { + # Having preprocessor conditionals complicates the computation of + # correct offset values. We have to introduce auxiliary enumeration + # elements with the name `af_blue_<s>_<n1>_<n2>_...' that store + # offsets to be used in conditional clauses. `<s>' is the number of + # sections seen so far, `<n1>' is the number of `#if' and `#endif' + # conditionals seen so far in the topmost level, `<n2>' the number of + # `#if' and `#endif' conditionals seen so far one level deeper, etc. + # As a consequence, uneven values are used within a clause, and even + # values after a clause, since the C standard doesn't allow the + # redefinition of an enumeration value. For example, the name + # `af_blue_5_1_6' is used to construct enumeration values in the fifth + # section after the third (second-level) if-clause within the first + # (top-level) if-clause. After the first top-level clause has + # finished, `af_blue_5_2' is used. The current offset is then + # relative to the value stored in the current auxiliary element. + + if (/ ^ \# \s* if /x) + { + push @else_stack, 0; + + $name_stack[$#name_stack]++; + + push @{$diversions{$curr_enum}}, enum_val_string(aux_name()); + $last_aux = aux_name(); + + push @name_stack, 0; + + $curr_offset = 0; + } + elsif (/ ^ \# \s* elif /x) + { + Die("unbalanced #elif") unless @else_stack; + + pop @name_stack; + + push @{$diversions{$curr_enum}}, enum_val_string(aux_name_next()); + $last_aux = aux_name(); + + push @name_stack, 0; + + $curr_offset = 0; + } + elsif (/ ^ \# \s* else /x) + { + my $prev_else = pop @else_stack; + Die("unbalanced #else") unless defined($prev_else); + Die("#else already seen") if $prev_else; + push @else_stack, 1; + + pop @name_stack; + + push @{$diversions{$curr_enum}}, enum_val_string(aux_name_next()); + $last_aux = aux_name(); + + push @name_stack, 0; + + $curr_offset = 0; + } + elsif (/ ^ (\# \s*) endif /x) + { + my $prev_else = pop @else_stack; + Die("unbalanced #endif") unless defined($prev_else); + + pop @name_stack; + + # If there is no else-clause for an if-clause, we add one. This is + # necessary to have correct offsets. + if (!$prev_else) + { + # Use amount of whitespace from `endif'. + push @{$diversions{$curr_enum}}, enum_val_string(aux_name_next()) + . $1 . "else\n"; + $last_aux = aux_name(); + + $curr_offset = 0; + } + + $name_stack[$#name_stack]++; + + push @{$diversions{$curr_enum}}, enum_val_string(aux_name()); + $last_aux = aux_name(); + + $curr_offset = 0; + } + + # Handle (probably continued) preprocessor lines. + CONTINUED_LOOP: + { + do + { + strip_newline(); + + push @{$diversions{$curr_enum}}, $ARG . "\n"; + push @{$diversions{$curr_array}}, $ARG . "\n"; + + last CONTINUED_LOOP unless / \\ $ /x; + + } while (<DATA>); + } + } + else + { + warn_before(); + } + + next; + } + + if (/$enum_element_re/) + { + end_curr_string(); + update_max_elem_size(); + + $curr_enum_element = $1; + $have_enum_element = 1; + $curr_elem_size = 0; + + next; + } + + if (/$string_re/) + { + if ($have_sections) + { + Die("strings and blocks can't be mixed in a section") if $have_blocks; + + # Save captured group from `string_re'. + my $string = $1; + + if ($have_enum_element) + { + push @{$diversions{$curr_enum}}, enum_val_string($curr_enum_element); + $have_enum_element = 0; + } + + $string = convert_literal($string); + + push @{$diversions{$curr_array}}, " $string\n"; + + $have_strings = 1; + $in_string = 1; + } + else + { + warn_before(); + } + + next; + } + + if (/$block_start_re/) + { + if ($have_sections) + { + Die("strings and blocks can't be mixed in a section") if $have_strings; + + my $depth = 0; + my $block = ""; + my $block_end = 0; + + # Count braces while getting the block. + BRACE_LOOP: + { + do + { + strip_newline(); + + foreach my $substring (split(/$brace_re/)) + { + if ($block_end) + { + Die("invalid data after last matching closing brace") + if $substring !~ /$whitespace_only_re/; + } + + $block .= $substring; + + if ($substring eq '{') + { + $depth++; + } + elsif ($substring eq '}') + { + $depth--; + + $block_end = 1 if $depth == 0; + } + } + + # If we are here, we have run out of substrings, so get next line + # or exit. + last BRACE_LOOP if $block_end; + + $block .= "\n"; + + } while (<DATA>); + } + + if ($have_enum_element) + { + push @{$diversions{$curr_enum}}, enum_val_string($curr_enum_element); + $have_enum_element = 0; + } + + push @{$diversions{$curr_array}}, $block . ",\n"; + + $curr_offset++; + $curr_elem_size++; + + $have_blocks = 1; + } + else + { + warn_before(); + } + + next; + } + + # Garbage. We weren't able to parse the data. + Die("syntax error"); +} + +# Finalize data. +end_curr_string(); +update_max_elem_size(); + + +# Filter stdin to stdout, replacing `@...@' templates. + +sub emit_diversion +{ + my $diversion_name = shift; + return (exists($diversions{$1})) ? "@{$diversions{$1}}" + : "@" . $diversion_name . "@"; +} + + +$LIST_SEPARATOR = ''; + +my $s1 = "This file has been generated by the Perl script \`$prog',"; +my $s1len = length $s1; +my $s2 = "using data from file \`$datafile'."; +my $s2len = length $s2; +my $slen = ($s1len > $s2len) ? $s1len : $s2len; + +print "/* " . $s1 . " " x ($slen - $s1len) . " */\n" + . "/* " . $s2 . " " x ($slen - $s2len) . " */\n" + . "\n"; + +while (<STDIN>) +{ + s/ @ ( [A-Za-z0-9_]+? ) @ / emit_diversion($1) /egx; + print; +} + +# EOF
diff --git a/src/third_party/freetype2/src/tools/apinames.c b/src/third_party/freetype2/src/tools/apinames.c new file mode 100644 index 0000000..aeecf88 --- /dev/null +++ b/src/third_party/freetype2/src/tools/apinames.c
@@ -0,0 +1,514 @@ +/* + * This little program is used to parse the FreeType headers and + * find the declaration of all public APIs. This is easy, because + * they all look like the following: + * + * FT_EXPORT( return_type ) + * function_name( function arguments ); + * + * You must pass the list of header files as arguments. Wildcards are + * accepted if you are using GCC for compilation (and probably by + * other compilers too). + * + * Author: FreeType team, 2005-2019 + * + * This code is explicitly placed into the public domain. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#define PROGRAM_NAME "apinames" +#define PROGRAM_VERSION "0.3" + +#define LINEBUFF_SIZE 1024 + + +typedef enum OutputFormat_ +{ + OUTPUT_LIST = 0, /* output the list of names, one per line */ + OUTPUT_WINDOWS_DEF, /* output a Windows .DEF file for Visual C++ or Mingw */ + OUTPUT_BORLAND_DEF, /* output a Windows .DEF file for Borland C++ */ + OUTPUT_WATCOM_LBC, /* output a Watcom Linker Command File */ + OUTPUT_NETWARE_IMP, /* output a NetWare ImportFile */ + OUTPUT_GNU_VERMAP /* output a version map for GNU or Solaris linker */ + +} OutputFormat; + + +static void +panic( const char* message ) +{ + fprintf( stderr, "PANIC: %s\n", message ); + exit(2); +} + + +typedef struct NameRec_ +{ + char* name; + unsigned int hash; + +} NameRec, *Name; + + +static Name the_names; +static int num_names; +static int max_names; + + +static void +names_add( const char* name, + const char* end ) +{ + unsigned int h; + int nn, len; + Name nm; + + + if ( end <= name ) + return; + + /* compute hash value */ + len = (int)( end - name ); + h = 0; + + for ( nn = 0; nn < len; nn++ ) + h = h * 33 + name[nn]; + + /* check for an pre-existing name */ + for ( nn = 0; nn < num_names; nn++ ) + { + nm = the_names + nn; + + if ( (int)nm->hash == h && + memcmp( name, nm->name, len ) == 0 && + nm->name[len] == 0 ) + return; + } + + /* add new name */ + if ( num_names >= max_names ) + { + max_names += ( max_names >> 1 ) + 4; + the_names = (NameRec*)realloc( the_names, + sizeof ( the_names[0] ) * max_names ); + if ( !the_names ) + panic( "not enough memory" ); + } + nm = &the_names[num_names++]; + + nm->hash = h; + nm->name = (char*)malloc( len + 1 ); + if ( !nm->name ) + panic( "not enough memory" ); + + memcpy( nm->name, name, len ); + nm->name[len] = 0; +} + + +static int +name_compare( const void* name1, + const void* name2 ) +{ + Name n1 = (Name)name1; + Name n2 = (Name)name2; + + return strcmp( n1->name, n2->name ); +} + + +static void +names_sort( void ) +{ + qsort( the_names, (size_t)num_names, + sizeof ( the_names[0] ), name_compare ); +} + + +static void +names_dump( FILE* out, + OutputFormat format, + const char* dll_name ) +{ + int nn; + + + switch ( format ) + { + case OUTPUT_WINDOWS_DEF: + if ( dll_name ) + fprintf( out, "LIBRARY %s\n", dll_name ); + + fprintf( out, "DESCRIPTION FreeType 2 DLL\n" ); + fprintf( out, "EXPORTS\n" ); + + for ( nn = 0; nn < num_names; nn++ ) + fprintf( out, " %s\n", the_names[nn].name ); + + break; + + case OUTPUT_BORLAND_DEF: + if ( dll_name ) + fprintf( out, "LIBRARY %s\n", dll_name ); + + fprintf( out, "DESCRIPTION FreeType 2 DLL\n" ); + fprintf( out, "EXPORTS\n" ); + + for ( nn = 0; nn < num_names; nn++ ) + fprintf( out, " _%s\n", the_names[nn].name ); + + break; + + case OUTPUT_WATCOM_LBC: + { + const char* dot; + char temp[512]; + + + if ( !dll_name ) + { + fprintf( stderr, + "you must provide a DLL name with the -d option!\n" ); + exit( 4 ); + } + + /* we must omit the `.dll' suffix from the library name */ + dot = strchr( dll_name, '.' ); + if ( dot ) + { + int len = dot - dll_name; + + + if ( len > (int)( sizeof ( temp ) - 1 ) ) + len = sizeof ( temp ) - 1; + + memcpy( temp, dll_name, len ); + temp[len] = 0; + + dll_name = (const char*)temp; + } + + for ( nn = 0; nn < num_names; nn++ ) + fprintf( out, "++_%s.%s.%s\n", + the_names[nn].name, dll_name, the_names[nn].name ); + } + + break; + + case OUTPUT_NETWARE_IMP: + if ( dll_name ) + fprintf( out, " (%s)\n", dll_name ); + + for ( nn = 0; nn < num_names - 1; nn++ ) + fprintf( out, " %s,\n", the_names[nn].name ); + fprintf( out, " %s\n", the_names[num_names - 1].name ); + + break; + + case OUTPUT_GNU_VERMAP: + fprintf( out, "{\n\tglobal:\n" ); + + for ( nn = 0; nn < num_names; nn++ ) + fprintf( out, "\t\t%s;\n", the_names[nn].name ); + + fprintf( out, "\tlocal:\n\t\t*;\n};\n" ); + + break; + + default: /* LIST */ + for ( nn = 0; nn < num_names; nn++ ) + fprintf( out, "%s\n", the_names[nn].name ); + + break; + } +} + + +/* states of the line parser */ + +typedef enum State_ +{ + STATE_START = 0, /* waiting for FT_EXPORT keyword and return type */ + STATE_TYPE /* type was read, waiting for function name */ + +} State; + + +static int +read_header_file( FILE* file, + int verbose ) +{ + static char buff[LINEBUFF_SIZE + 1]; + State state = STATE_START; + + + while ( !feof( file ) ) + { + char* p; + + + if ( !fgets( buff, LINEBUFF_SIZE, file ) ) + break; + + p = buff; + + /* skip leading whitespace */ + while ( *p && ( *p == ' ' || *p == '\\' ) ) + p++; + + /* skip empty lines */ + if ( *p == '\n' || *p == '\r' ) + continue; + + switch ( state ) + { + case STATE_START: + if ( memcmp( p, "FT_EXPORT(", 10 ) != 0 ) + break; + + p += 10; + for (;;) + { + if ( *p == 0 || *p == '\n' || *p == '\r' ) + goto NextLine; + + if ( *p == ')' ) + { + p++; + break; + } + + p++; + } + + state = STATE_TYPE; + + /* + * Sometimes, the name is just after `FT_EXPORT(...)', so skip + * whitespace and fall-through if we find an alphanumeric character. + */ + while ( *p == ' ' || *p == '\t' ) + p++; + + if ( !isalpha( *p ) ) + break; + + /* fall-through */ + + case STATE_TYPE: + { + char* name = p; + + + while ( isalnum( *p ) || *p == '_' ) + p++; + + if ( p > name ) + { + if ( verbose ) + fprintf( stderr, ">>> %.*s\n", (int)( p - name ), name ); + + names_add( name, p ); + } + + state = STATE_START; + } + + break; + + default: + ; + } + +NextLine: + ; + } /* end of while loop */ + + return 0; +} + + +static void +usage( void ) +{ + static const char* const format = + "%s %s: extract FreeType API names from header files\n" + "\n" + "This program extracts the list of public FreeType API functions.\n" + "It receives a list of header files as an argument and\n" + "generates a sorted list of unique identifiers in various formats.\n" + "\n" + "usage: %s header1 [options] [header2 ...]\n" + "\n" + "options: - parse the contents of stdin, ignore arguments\n" + " -v verbose mode, output sent to standard error\n" + " -oFILE write output to FILE instead of standard output\n" + " -dNAME indicate DLL file name, 'freetype.dll' by default\n" + " -w output .DEF file for Visual C++ and Mingw\n" + " -wB output .DEF file for Borland C++\n" + " -wW output Watcom Linker Response File\n" + " -wN output NetWare Import File\n" + " -wL output version map for GNU or Solaris linker\n" + "\n"; + + fprintf( stderr, + format, + PROGRAM_NAME, + PROGRAM_VERSION, + PROGRAM_NAME ); + + exit( 1 ); +} + + +int +main( int argc, + const char* const* argv ) +{ + int from_stdin = 0; + int verbose = 0; + OutputFormat format = OUTPUT_LIST; /* the default */ + FILE* out = stdout; + const char* library_name = NULL; + + + if ( argc < 2 ) + usage(); + + /* `-' used as a single argument means read source file from stdin */ + while ( argc > 1 && argv[1][0] == '-' ) + { + const char* arg = argv[1]; + + + switch ( arg[1] ) + { + case 'v': + verbose = 1; + + break; + + case 'o': + if ( arg[2] == 0 ) + { + if ( argc < 2 ) + usage(); + + arg = argv[2]; + argv++; + argc--; + } + else + arg += 2; + + out = fopen( arg, "wt" ); + if ( !out ) + { + fprintf( stderr, "could not open '%s' for writing\n", arg ); + exit( 3 ); + } + + break; + + case 'd': + if ( arg[2] == 0 ) + { + if ( argc < 2 ) + usage(); + + arg = argv[2]; + argv++; + argc--; + } + else + arg += 2; + + library_name = arg; + + break; + + case 'w': + format = OUTPUT_WINDOWS_DEF; + + switch ( arg[2] ) + { + case 'B': + format = OUTPUT_BORLAND_DEF; + break; + + case 'W': + format = OUTPUT_WATCOM_LBC; + break; + + case 'N': + format = OUTPUT_NETWARE_IMP; + break; + + case 'L': + format = OUTPUT_GNU_VERMAP; + break; + + case 0: + break; + + default: + usage(); + } + + break; + + case 0: + from_stdin = 1; + + break; + + default: + usage(); + } + + argc--; + argv++; + + } /* end of while loop */ + + if ( from_stdin ) + read_header_file( stdin, verbose ); + else + { + for ( --argc, argv++; argc > 0; argc--, argv++ ) + { + FILE* file = fopen( argv[0], "rb" ); + + + if ( !file ) + fprintf( stderr, "unable to open '%s'\n", argv[0] ); + else + { + if ( verbose ) + fprintf( stderr, "opening '%s'\n", argv[0] ); + + read_header_file( file, verbose ); + fclose( file ); + } + } + } + + if ( num_names == 0 ) + panic( "could not find exported functions\n" ); + + names_sort(); + names_dump( out, format, library_name ); + + if ( out != stdout ) + fclose( out ); + + return 0; +} + + +/* END */
diff --git a/src/third_party/freetype2/src/tools/ftrandom/Makefile b/src/third_party/freetype2/src/tools/ftrandom/Makefile new file mode 100644 index 0000000..24dc49c --- /dev/null +++ b/src/third_party/freetype2/src/tools/ftrandom/Makefile
@@ -0,0 +1,45 @@ +# TOP_DIR and OBJ_DIR should be set by the user to the right directories, +# if necessary. + +TOP_DIR ?= ../../.. +OBJ_DIR ?= $(TOP_DIR)/objs + + +# The setup below is for gcc on a Unix-like platform, +# where FreeType has been set up to create a static library +# (which is the default). + +VPATH = $(OBJ_DIR) \ + $(OBJ_DIR)/.libs + +SRC_DIR = $(TOP_DIR)/src/tools/ftrandom + +CC = gcc +WFLAGS = -Wmissing-prototypes \ + -Wunused \ + -Wimplicit \ + -Wreturn-type \ + -Wparentheses \ + -pedantic \ + -Wformat \ + -Wchar-subscripts \ + -Wsequence-point +CFLAGS = $(WFLAGS) \ + -g +INCLUDES = -I $(TOP_DIR)/include +LDFLAGS = +LIBS = -lm \ + -lz \ + -lpng \ + -lbz2 \ + -lharfbuzz + +all: $(OBJ_DIR)/ftrandom + +$(OBJ_DIR)/ftrandom.o: $(SRC_DIR)/ftrandom.c + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< + +$(OBJ_DIR)/ftrandom: $(OBJ_DIR)/ftrandom.o libfreetype.a + $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) + +# EOF
diff --git a/src/third_party/freetype2/src/tools/ftrandom/README b/src/third_party/freetype2/src/tools/ftrandom/README new file mode 100644 index 0000000..7c61086 --- /dev/null +++ b/src/third_party/freetype2/src/tools/ftrandom/README
@@ -0,0 +1,69 @@ +ftrandom +======== + +This program expects a set of directories containing good fonts, and a set +of extensions of fonts to be tested. It will randomly pick a font, copy it, +introduce an error and then test it. + +The FreeType tests are quite basic; for each erroneous font ftrandom + + . forks off a new tester, + . initializes the library, + . opens each font in the file, + . loads each glyph, + . optionally reviews the contours of the glyph, + . optionally rasterizes the glyph, and + . closes the face. + +If a tester takes longer than 20 seconds, ftrandom saves the erroneous font +and continues. If the tester exits normally or with an error, then the +superstructure removes the test font and continues. + + +Command line options +-------------------- + + --all Test every font in the directory(ies) no matter + what its extension. + --check-outlines Call `FT_Outline_Decompose' on each glyph. + --dir <dir> Append <dir> to the list of directories to search + for good fonts. No recursive search. + --error-count <cnt> Introduce <cnt> single-byte errors into the + erroneous fonts (default: 1). + --error-fraction <frac> Multiply the file size of the font by <frac> and + introduce that many errors into the erroneous + font file. <frac> should be in the range [0;1] + (default: 0.0). + --ext <ext> Add <ext> to the set of font types tested. + --help Print out this list of options. + --nohints Specify FT_LOAD_NO_HINTING when loading glyphs. + --rasterize Call `FT_Render_Glyph' as well as loading it. + --result <dir> This is the directory in which test files are + placed. + --test <file> Run a single test on a pre-generated testcase. + This is done in the current process so it can be + debugged more easily. + +The default font extensions tested by ftrandom are + + .ttf .otf .ttc .cid .pfb .pfa .bdf .pcf .pfr .fon .otb .cff + +The default font directory is controlled by the macro `GOOD_FONTS_DIR' in +the source code (and can be thus specified during compilation); its default +value is + + /usr/local/share/fonts + +The default result directory is `results' (in the current directory). + + +Compilation +----------- + +Two possible solutions. + +. Run ftrandom within a debugging tool like `valgrind' to catch various + memory issues. + +. Compile FreeType with sanitizer flags as provided by gcc or clang, for + example, then link it with ftrandom.
diff --git a/src/third_party/freetype2/src/tools/ftrandom/ftrandom.c b/src/third_party/freetype2/src/tools/ftrandom/ftrandom.c new file mode 100644 index 0000000..ab5cfc9 --- /dev/null +++ b/src/third_party/freetype2/src/tools/ftrandom/ftrandom.c
@@ -0,0 +1,720 @@ +/* Copyright (C) 2005, 2007, 2008, 2013 by George Williams */ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 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. + + * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/* modified by Werner Lemberg <wl@gnu.org> */ +/* This file is now part of the FreeType library */ + + +#define _XOPEN_SOURCE 500 /* for `kill', `strdup', `random', and `srandom' */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <unistd.h> +#include <dirent.h> +#include <signal.h> +#include <time.h> + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_OUTLINE_H + +#define true 1 +#define false 0 +#define forever for (;;) + + + static int check_outlines = false; + static int nohints = false; + static int rasterize = false; + static char* results_dir = "results"; + +#define GOOD_FONTS_DIR "/usr/local/share/fonts" + + static char* default_dir_list[] = + { + GOOD_FONTS_DIR, + NULL + }; + + static char* default_ext_list[] = + { + "ttf", + "otf", + "ttc", + "cid", + "pfb", + "pfa", + "bdf", + "pcf", + "pfr", + "fon", + "otb", + "cff", + NULL + }; + + static unsigned int error_count = 1; + static double error_fraction = 0.0; + + static FT_F26Dot6 font_size = 12 * 64; + + static struct fontlist + { + char* name; + long len; + unsigned int isbinary: 1; + unsigned int isascii: 1; + unsigned int ishex: 1; + + } *fontlist; + + static unsigned int fcnt; + + + static int + FT_MoveTo( const FT_Vector *to, + void *user ) + { + FT_UNUSED( to ); + FT_UNUSED( user ); + + return 0; + } + + + static int + FT_LineTo( const FT_Vector *to, + void *user ) + { + FT_UNUSED( to ); + FT_UNUSED( user ); + + return 0; + } + + + static int + FT_ConicTo( const FT_Vector *_cp, + const FT_Vector *to, + void *user ) + { + FT_UNUSED( _cp ); + FT_UNUSED( to ); + FT_UNUSED( user ); + + return 0; + } + + + static int + FT_CubicTo( const FT_Vector *cp1, + const FT_Vector *cp2, + const FT_Vector *to, + void *user ) + { + FT_UNUSED( cp1 ); + FT_UNUSED( cp2 ); + FT_UNUSED( to ); + FT_UNUSED( user ); + + return 0; + } + + + static FT_Outline_Funcs outlinefuncs = + { + FT_MoveTo, + FT_LineTo, + FT_ConicTo, + FT_CubicTo, + 0, 0 /* No shift, no delta */ + }; + + + static void + TestFace( FT_Face face ) + { + unsigned int gid; + int load_flags = FT_LOAD_DEFAULT; + + + if ( check_outlines && + FT_IS_SCALABLE( face ) ) + load_flags = FT_LOAD_NO_BITMAP; + + if ( nohints ) + load_flags |= FT_LOAD_NO_HINTING; + + FT_Set_Char_Size( face, 0, font_size, 72, 72 ); + + for ( gid = 0; gid < face->num_glyphs; gid++ ) + { + if ( check_outlines && + FT_IS_SCALABLE( face ) ) + { + if ( !FT_Load_Glyph( face, gid, load_flags ) ) + FT_Outline_Decompose( &face->glyph->outline, &outlinefuncs, NULL ); + } + else + FT_Load_Glyph( face, gid, load_flags ); + + if ( rasterize ) + FT_Render_Glyph( face->glyph, ft_render_mode_normal ); + } + + FT_Done_Face( face ); + } + + + static void + ExecuteTest( char* testfont ) + { + FT_Library context; + FT_Face face; + + + if ( FT_Init_FreeType( &context ) ) + { + fprintf( stderr, "Can't initialize FreeType.\n" ); + exit( 1 ); + } + + if ( FT_New_Face( context, testfont, 0, &face ) ) + { + /* The font is erroneous, so if this fails that's ok. */ + exit( 0 ); + } + + if ( face->num_faces == 1 ) + TestFace( face ); + else + { + long i, num; + + + num = face->num_faces; + FT_Done_Face( face ); + + for ( i = 0; i < num; i++ ) + { + if ( !FT_New_Face( context, testfont, i, &face ) ) + TestFace( face ); + } + } + + FT_Done_FreeType( context ); + + exit( 0 ); + } + + + static int + extmatch( char* filename, + char** extensions ) + { + int i; + char* pt; + + + if ( !extensions ) + return true; + + pt = strrchr( filename, '.' ); + if ( !pt ) + return false; + if ( pt < strrchr( filename, '/' ) ) + return false; + + for ( i = 0; extensions[i] != NULL; i++ ) + if ( strcasecmp( pt + 1, extensions[i] ) == 0 || + strcasecmp( pt, extensions[i] ) == 0 ) + return true; + + return false; + } + + + static void + figurefiletype( struct fontlist* item ) + { + FILE* foo; + + + item->isbinary = item->isascii = item->ishex = false; + + foo = fopen( item->name, "rb" ); + if ( foo ) + { + /* Try to guess the file type from the first few characters... */ + int ch1 = getc( foo ); + int ch2 = getc( foo ); + int ch3 = getc( foo ); + int ch4 = getc( foo ); + + + fclose( foo ); + + if ( ( ch1 == 0 && ch2 == 1 && ch3 == 0 && ch4 == 0 ) || + ( ch1 == 'O' && ch2 == 'T' && ch3 == 'T' && ch4 == 'O' ) || + ( ch1 == 't' && ch2 == 'r' && ch3 == 'u' && ch4 == 'e' ) || + ( ch1 == 't' && ch2 == 't' && ch3 == 'c' && ch4 == 'f' ) ) + { + /* ttf, otf, ttc files */ + item->isbinary = true; + } + else if ( ch1 == 0x80 && ch2 == '\01' ) + { + /* PFB header */ + item->isbinary = true; + } + else if ( ch1 == '%' && ch2 == '!' ) + { + /* Random PostScript */ + if ( strstr( item->name, ".pfa" ) || + strstr( item->name, ".PFA" ) ) + item->ishex = true; + else + item->isascii = true; + } + else if ( ch1 == 1 && ch2 == 0 && ch3 == 4 ) + { + /* Bare CFF */ + item->isbinary = true; + } + else if ( ch1 == 'S' && ch2 == 'T' && ch3 == 'A' && ch4 == 'R' ) + { + /* BDF */ + item->ishex = true; + } + else if ( ch1 == 'P' && ch2 == 'F' && ch3 == 'R' && ch4 == '0' ) + { + /* PFR */ + item->isbinary = true; + } + else if ( ( ch1 == '\1' && ch2 == 'f' && ch3 == 'c' && ch4 == 'p' ) || + ( ch1 == 'M' && ch2 == 'Z' ) ) + { + /* Windows FON */ + item->isbinary = true; + } + else + { + fprintf( stderr, + "Can't recognize file type of `%s', assuming binary\n", + item->name ); + item->isbinary = true; + } + } + else + { + fprintf( stderr, "Can't open `%s' for typing the file.\n", + item->name ); + item->isbinary = true; + } + } + + + static void + FindFonts( char** fontdirs, + char** extensions ) + { + int i; + unsigned int max; + char buffer[1025]; + struct stat statb; + + + max = 0; + fcnt = 0; + + for ( i = 0; fontdirs[i] != NULL; i++ ) + { + DIR* examples; + struct dirent* ent; + + + examples = opendir( fontdirs[i] ); + if ( !examples ) + { + fprintf( stderr, + "Can't open example font directory `%s'\n", + fontdirs[i] ); + exit( 1 ); + } + + while ( ( ent = readdir( examples ) ) != NULL ) + { + snprintf( buffer, sizeof ( buffer ), + "%s/%s", fontdirs[i], ent->d_name ); + if ( stat( buffer, &statb ) == -1 || S_ISDIR( statb.st_mode ) ) + continue; + if ( !extensions || extmatch( buffer, extensions ) ) + { + if ( fcnt >= max ) + { + max += 100; + fontlist = realloc( fontlist, max * sizeof ( struct fontlist ) ); + if ( !fontlist ) + { + fprintf( stderr, "Can't allocate memory\n" ); + exit( 1 ); + } + } + + fontlist[fcnt].name = strdup( buffer ); + fontlist[fcnt].len = statb.st_size; + + figurefiletype( &fontlist[fcnt] ); + fcnt++; + } + } + + closedir( examples ); + } + + if ( fcnt == 0 ) + { + fprintf( stderr, "Can't find matching font files.\n" ); + exit( 1 ); + } + + fontlist[fcnt].name = NULL; + } + + + static unsigned int + getErrorCnt( struct fontlist* item ) + { + if ( error_count == 0 && error_fraction == 0.0 ) + return 0; + + return error_count + (unsigned int)( error_fraction * item->len ); + } + + + static int + getRandom( int low, + int high ) + { + if ( low - high < 0x10000L ) + return low + ( ( random() >> 8 ) % ( high + 1 - low ) ); + + return low + ( random() % ( high + 1 - low ) ); + } + + + static int + copyfont( struct fontlist* item, + char* newfont ) + { + static char buffer[8096]; + FILE *good, *newf; + size_t len; + unsigned int i, err_cnt; + + + good = fopen( item->name, "r" ); + if ( !good ) + { + fprintf( stderr, "Can't open `%s'\n", item->name ); + return false; + } + + newf = fopen( newfont, "w+" ); + if ( !newf ) + { + fprintf( stderr, "Can't create temporary output file `%s'\n", + newfont ); + exit( 1 ); + } + + while ( ( len = fread( buffer, 1, sizeof ( buffer ), good ) ) > 0 ) + fwrite( buffer, 1, len, newf ); + + fclose( good ); + + err_cnt = getErrorCnt( item ); + for ( i = 0; i < err_cnt; i++ ) + { + fseek( newf, getRandom( 0, (int)( item->len - 1 ) ), SEEK_SET ); + + if ( item->isbinary ) + putc( getRandom( 0, 0xFF ), newf ); + else if ( item->isascii ) + putc( getRandom( 0x20, 0x7E ), newf ); + else + { + int hex = getRandom( 0, 15 ); + + + if ( hex < 10 ) + hex += '0'; + else + hex += 'A' - 10; + + putc( hex, newf ); + } + } + + if ( ferror( newf ) ) + { + fclose( newf ); + unlink( newfont ); + return false; + } + + fclose( newf ); + + return true; + } + + + static int child_pid; + + static void + abort_test( int sig ) + { + FT_UNUSED( sig ); + + /* If a time-out happens, then kill the child */ + kill( child_pid, SIGFPE ); + write( 2, "Timeout... ", 11 ); + } + + + static void + do_test( void ) + { + int i = getRandom( 0, (int)( fcnt - 1 ) ); + static int test_num = 0; + char buffer[1024]; + + + sprintf( buffer, "%s/test%d", results_dir, test_num++ ); + + if ( copyfont ( &fontlist[i], buffer ) ) + { + signal( SIGALRM, abort_test ); + /* Anything that takes more than 20 seconds */ + /* to parse and/or rasterize is an error. */ + alarm( 20 ); + if ( ( child_pid = fork() ) == 0 ) + ExecuteTest( buffer ); + else if ( child_pid != -1 ) + { + int status; + + + waitpid( child_pid, &status, 0 ); + alarm( 0 ); + if ( WIFSIGNALED ( status ) ) + printf( "Error found in file `%s'\n", buffer ); + else + unlink( buffer ); + } + else + { + fprintf( stderr, "Can't fork test case.\n" ); + exit( 1 ); + } + alarm( 0 ); + } + } + + + static void + usage( FILE* out, + char* name ) + { + char** d = default_dir_list; + char** e = default_ext_list; + + + fprintf( out, "%s [options] -- Generate random erroneous fonts\n" + " and attempt to parse them with FreeType.\n\n", name ); + + fprintf( out, " --all All non-directory files are assumed to be fonts.\n" ); + fprintf( out, " --check-outlines Make sure we can parse the outlines of each glyph.\n" ); + fprintf( out, " --dir <path> Append <path> to list of font search directories\n" + " (no recursive search).\n" ); + fprintf( out, " --error-count <cnt> Introduce <cnt> single byte errors into each font\n" + " (default: 1)\n" ); + fprintf( out, " --error-fraction <frac> Introduce <frac>*filesize single byte errors\n" + " into each font (default: 0.0).\n" ); + fprintf( out, " --ext <ext> Add <ext> to list of extensions indicating fonts.\n" ); + fprintf( out, " --help Print this.\n" ); + fprintf( out, " --nohints Turn off hinting.\n" ); + fprintf( out, " --rasterize Attempt to rasterize each glyph.\n" ); + fprintf( out, " --results <path> Place the created test fonts into <path>\n" + " (default: `results')\n" ); + fprintf( out, " --size <float> Use the given font size for the tests.\n" ); + fprintf( out, " --test <file> Run a single test on an already existing file.\n" ); + fprintf( out, "\n" ); + + fprintf( out, "Default font extensions:\n" ); + fprintf( out, " " ); + while ( *e ) + fprintf( out, " .%s", *e++ ); + fprintf( out, "\n" ); + + fprintf( out, "Default font directories:\n" ); + fprintf( out, " " ); + while ( *d ) + fprintf( out, " %s", *d++ ); + fprintf( out, "\n" ); + } + + + int + main( int argc, + char** argv ) + { + char **dirs, **exts; + int dcnt = 0, ecnt = 0, rset = false, allexts = false; + int i; + time_t now; + char* testfile = NULL; + + + dirs = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) ); + exts = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) ); + + for ( i = 1; i < argc; i++ ) + { + char* pt = argv[i]; + char* end; + + + if ( pt[0] == '-' && pt[1] == '-' ) + pt++; + + if ( strcmp( pt, "-all" ) == 0 ) + allexts = true; + else if ( strcmp( pt, "-check-outlines" ) == 0 ) + check_outlines = true; + else if ( strcmp( pt, "-dir" ) == 0 ) + dirs[dcnt++] = argv[++i]; + else if ( strcmp( pt, "-error-count" ) == 0 ) + { + if ( !rset ) + error_fraction = 0.0; + rset = true; + error_count = (unsigned int)strtoul( argv[++i], &end, 10 ); + if ( *end != '\0' ) + { + fprintf( stderr, "Bad value for error-count: %s\n", argv[i] ); + exit( 1 ); + } + } + else if ( strcmp( pt, "-error-fraction" ) == 0 ) + { + if ( !rset ) + error_count = 0; + rset = true; + error_fraction = strtod( argv[++i], &end ); + if ( *end != '\0' ) + { + fprintf( stderr, "Bad value for error-fraction: %s\n", argv[i] ); + exit( 1 ); + } + if ( error_fraction < 0.0 || error_fraction > 1.0 ) + { + fprintf( stderr, "error-fraction must be in the range [0;1]\n" ); + exit( 1 ); + } + } + else if ( strcmp( pt, "-ext" ) == 0 ) + exts[ecnt++] = argv[++i]; + else if ( strcmp( pt, "-help" ) == 0 ) + { + usage( stdout, argv[0] ); + exit( 0 ); + } + else if ( strcmp( pt, "-nohints" ) == 0 ) + nohints = true; + else if ( strcmp( pt, "-rasterize" ) == 0 ) + rasterize = true; + else if ( strcmp( pt, "-results" ) == 0 ) + results_dir = argv[++i]; + else if ( strcmp( pt, "-size" ) == 0 ) + { + font_size = (FT_F26Dot6)( strtod( argv[++i], &end ) * 64 ); + if ( *end != '\0' || font_size < 64 ) + { + fprintf( stderr, "Bad value for size: %s\n", argv[i] ); + exit( 1 ); + } + } + else if ( strcmp( pt, "-test" ) == 0 ) + testfile = argv[++i]; + else + { + usage( stderr, argv[0] ); + exit( 1 ); + } + } + + if ( allexts ) + { + free( exts ); + exts = NULL; + } + else if ( ecnt == 0 ) + { + free( exts ); + exts = default_ext_list; + } + + if ( dcnt == 0 ) + { + free( dirs ); + dirs = default_dir_list; + } + + if ( testfile ) + ExecuteTest( testfile ); /* This should never return */ + + time( &now ); + srandom( (unsigned int)now ); + + FindFonts( dirs, exts ); + mkdir( results_dir, 0755 ); + + forever + do_test(); + + return 0; + } + + +/* EOF */
diff --git a/src/third_party/freetype2/src/tools/no-copyright b/src/third_party/freetype2/src/tools/no-copyright new file mode 100644 index 0000000..d639aa4 --- /dev/null +++ b/src/third_party/freetype2/src/tools/no-copyright
@@ -0,0 +1,65 @@ +# Files that don't get a copyright, or which are taken from elsewhere. +# +# All lines in this file are patterns, including the comment lines; this +# means that e.g. `FTL.TXT' matches all files that have this string in +# the file name (including the path relative to the current directory, +# always starting with `./'). +# +# Don't put empty lines into this file! +# +.gitignore +# +builds/unix/pkg.m4 +# +docs/FTL.TXT +docs/GPLv2.TXT +# +include/freetype/internal/fthash.h +# +src/base/fthash.c +src/base/md5.c +src/base/md5.h +# +src/bdf/bdf.c +src/bdf/bdf.h +src/bdf/bdfdrivr.c +src/bdf/bdfdrivr.h +src/bdf/bdferror.h +src/bdf/bdflib.c +src/bdf/module.mk +src/bdf/README +src/bdf/rules.mk +# +src/pcf/module.mk +src/pcf/pcf.c +src/pcf/pcf.h +src/pcf/pcfdrivr.c +src/pcf/pcfdrivr.h +src/pcf/pcferror.h +src/pcf/pcfread.c +src/pcf/pcfread.h +src/pcf/pcfutil.c +src/pcf/pcfutil.h +src/pcf/README +src/pcf/rules.mk +# +src/gzip/adler32.c +src/gzip/infblock.c +src/gzip/infblock.h +src/gzip/infcodes.c +src/gzip/infcodes.h +src/gzip/inffixed.h +src/gzip/inflate.c +src/gzip/inftrees.c +src/gzip/inftrees.h +src/gzip/infutil.c +src/gzip/infutil.h +src/gzip/zconf.h +src/gzip/zlib.h +src/gzip/zutil.c +src/gzip/zutil.h +# +src/tools/apinames.c +src/tools/ftrandom/ftrandom.c +# +# EOF
diff --git a/src/third_party/freetype2/src/tools/test_afm.c b/src/third_party/freetype2/src/tools/test_afm.c new file mode 100644 index 0000000..8de619b --- /dev/null +++ b/src/third_party/freetype2/src/tools/test_afm.c
@@ -0,0 +1,157 @@ +/* + * gcc -DFT2_BUILD_LIBRARY -I../../include -o test_afm test_afm.c \ + * -L../../objs/.libs -lfreetype -lz -static + */ +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + void dump_fontinfo( AFM_FontInfo fi ) + { + FT_UInt i; + + + printf( "This AFM is for %sCID font.\n\n", + ( fi->IsCIDFont ) ? "" : "non-" ); + + printf( "FontBBox: %.2f %.2f %.2f %.2f\n", fi->FontBBox.xMin / 65536., + fi->FontBBox.yMin / 65536., + fi->FontBBox.xMax / 65536., + fi->FontBBox.yMax / 65536. ); + printf( "Ascender: %.2f\n", fi->Ascender / 65536. ); + printf( "Descender: %.2f\n\n", fi->Descender / 65536. ); + + if ( fi->NumTrackKern ) + printf( "There are %d sets of track kernings:\n", + fi->NumTrackKern ); + else + printf( "There is no track kerning.\n" ); + + for ( i = 0; i < fi->NumTrackKern; i++ ) + { + AFM_TrackKern tk = fi->TrackKerns + i; + + + printf( "\t%2d: %5.2f %5.2f %5.2f %5.2f\n", tk->degree, + tk->min_ptsize / 65536., + tk->min_kern / 65536., + tk->max_ptsize / 65536., + tk->max_kern / 65536. ); + } + + printf( "\n" ); + + if ( fi->NumKernPair ) + printf( "There are %d kerning pairs:\n", + fi->NumKernPair ); + else + printf( "There is no kerning pair.\n" ); + + for ( i = 0; i < fi->NumKernPair; i++ ) + { + AFM_KernPair kp = fi->KernPairs + i; + + + printf( "\t%3d + %3d => (%4d, %4d)\n", kp->index1, + kp->index2, + kp->x, + kp->y ); + } + + } + + int + dummy_get_index( const char* name, + FT_Offset len, + void* user_data ) + { + if ( len ) + return name[0]; + else + return 0; + } + + FT_Error + parse_afm( FT_Library library, + FT_Stream stream, + AFM_FontInfo fi ) + { + PSAux_Service psaux; + AFM_ParserRec parser; + FT_Error error = FT_Err_Ok; + + + psaux = (PSAux_Service)FT_Get_Module_Interface( library, "psaux" ); + if ( !psaux || !psaux->afm_parser_funcs ) + return -1; + + error = FT_Stream_EnterFrame( stream, stream->size ); + if ( error ) + return error; + + error = psaux->afm_parser_funcs->init( &parser, + library->memory, + stream->cursor, + stream->limit ); + if ( error ) + return error; + + parser.FontInfo = fi; + parser.get_index = dummy_get_index; + + error = psaux->afm_parser_funcs->parse( &parser ); + + psaux->afm_parser_funcs->done( &parser ); + + return error; + } + + + int main( int argc, + char** argv ) + { + FT_Library library; + FT_StreamRec stream; + FT_Error error = FT_Err_Ok; + AFM_FontInfoRec fi; + + + if ( argc < 2 ) + return FT_ERR( Invalid_Argument ); + + error = FT_Init_FreeType( &library ); + if ( error ) + return error; + + FT_ZERO( &stream ); + error = FT_Stream_Open( &stream, argv[1] ); + if ( error ) + goto Exit; + stream.memory = library->memory; + + FT_ZERO( &fi ); + error = parse_afm( library, &stream, &fi ); + + if ( !error ) + { + FT_Memory memory = library->memory; + + + dump_fontinfo( &fi ); + + if ( fi.KernPairs ) + FT_FREE( fi.KernPairs ); + if ( fi.TrackKerns ) + FT_FREE( fi.TrackKerns ); + } + else + printf( "parse error\n" ); + + FT_Stream_Close( &stream ); + + Exit: + FT_Done_FreeType( library ); + + return error; + }
diff --git a/src/third_party/freetype2/src/tools/test_bbox.c b/src/third_party/freetype2/src/tools/test_bbox.c new file mode 100644 index 0000000..64b82c3 --- /dev/null +++ b/src/third_party/freetype2/src/tools/test_bbox.c
@@ -0,0 +1,188 @@ +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_BBOX_H + + +#include <time.h> /* for clock() */ + +/* SunOS 4.1.* does not define CLOCKS_PER_SEC, so include <sys/param.h> */ +/* to get the HZ macro which is the equivalent. */ +#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4) +#include <sys/param.h> +#define CLOCKS_PER_SEC HZ +#endif + + static long + get_time( void ) + { + return clock() * 10000L / CLOCKS_PER_SEC; + } + + + + + /* test bbox computations */ + +#define XSCALE 65536 +#define XX(x) ((FT_Pos)(x*XSCALE)) +#define XVEC(x,y) { XX(x), XX(y) } +#define XVAL(x) ((x)/(1.0*XSCALE)) + + /* dummy outline #1 */ + static FT_Vector dummy_vec_1[4] = + { +#if 1 + XVEC( 408.9111, 535.3164 ), + XVEC( 455.8887, 634.396 ), + XVEC( -37.8765, 786.2207 ), + XVEC( 164.6074, 535.3164 ) +#else + { (FT_Int32)0x0198E93DL , (FT_Int32)0x021750FFL }, /* 408.9111, 535.3164 */ + { (FT_Int32)0x01C7E312L , (FT_Int32)0x027A6560L }, /* 455.8887, 634.3960 */ + { (FT_Int32)0xFFDA1F9EL , (FT_Int32)0x0312387FL }, /* -37.8765, 786.2207 */ + { (FT_Int32)0x00A49B7EL , (FT_Int32)0x021750FFL } /* 164.6074, 535.3164 */ +#endif + }; + + static char dummy_tag_1[4] = + { + FT_CURVE_TAG_ON, + FT_CURVE_TAG_CUBIC, + FT_CURVE_TAG_CUBIC, + FT_CURVE_TAG_ON + }; + + static short dummy_contour_1[1] = + { + 3 + }; + + static FT_Outline dummy_outline_1 = + { + 1, + 4, + dummy_vec_1, + dummy_tag_1, + dummy_contour_1, + 0 + }; + + + /* dummy outline #2 */ + static FT_Vector dummy_vec_2[4] = + { + XVEC( 100.0, 100.0 ), + XVEC( 100.0, 200.0 ), + XVEC( 200.0, 200.0 ), + XVEC( 200.0, 133.0 ) + }; + + static FT_Outline dummy_outline_2 = + { + 1, + 4, + dummy_vec_2, + dummy_tag_1, + dummy_contour_1, + 0 + }; + + + /* dummy outline #3 with bbox of [0 100 128 128] precisely */ + static FT_Vector dummy_vec_3[4] = + { + XVEC( 100.0, 127.0 ), + XVEC( 200.0, 127.0 ), + XVEC( 0.0, 136.0 ), + XVEC( 0.0, 100.0 ) + }; + + static FT_Outline dummy_outline_3 = + { + 1, + 4, + dummy_vec_3, + dummy_tag_1, + dummy_contour_1, + 0 + }; + + + static void + dump_outline( FT_Outline* outline ) + { + FT_BBox bbox; + + /* compute and display cbox */ + FT_Outline_Get_CBox( outline, &bbox ); + printf( "cbox = [%.2f %.2f %.2f %.2f]\n", + XVAL( bbox.xMin ), + XVAL( bbox.yMin ), + XVAL( bbox.xMax ), + XVAL( bbox.yMax ) ); + + /* compute and display bbox */ + FT_Outline_Get_BBox( outline, &bbox ); + printf( "bbox = [%.2f %.2f %.2f %.2f]\n", + XVAL( bbox.xMin ), + XVAL( bbox.yMin ), + XVAL( bbox.xMax ), + XVAL( bbox.yMax ) ); + } + + + + static void + profile_outline( FT_Outline* outline, + long repeat ) + { + FT_BBox bbox; + long count; + long time0; + + time0 = get_time(); + for ( count = repeat; count > 0; count-- ) + FT_Outline_Get_CBox( outline, &bbox ); + + time0 = get_time() - time0; + printf( "time = %6.3f cbox = [%8.4f %8.4f %8.4f %8.4f]\n", + ((double)time0/10000.0), + XVAL( bbox.xMin ), + XVAL( bbox.yMin ), + XVAL( bbox.xMax ), + XVAL( bbox.yMax ) ); + printf( "cbox_hex = [%08X %08X %08X %08X]\n", + bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax ); + + + time0 = get_time(); + for ( count = repeat; count > 0; count-- ) + FT_Outline_Get_BBox( outline, &bbox ); + + time0 = get_time() - time0; + printf( "time = %6.3f bbox = [%8.4f %8.4f %8.4f %8.4f]\n", + ((double)time0/10000.0), + XVAL( bbox.xMin ), + XVAL( bbox.yMin ), + XVAL( bbox.xMax ), + XVAL( bbox.yMax ) ); + printf( "bbox_hex = [%08X %08X %08X %08X]\n", + bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax ); + } + +#define REPEAT 1000000L + + int main( int argc, char** argv ) + { + printf( "outline #1\n" ); + profile_outline( &dummy_outline_1, REPEAT ); + + printf( "outline #2\n" ); + profile_outline( &dummy_outline_2, REPEAT ); + + printf( "outline #3\n" ); + profile_outline( &dummy_outline_3, REPEAT ); + + return 0; + } +
diff --git a/src/third_party/freetype2/src/tools/test_trig.c b/src/third_party/freetype2/src/tools/test_trig.c new file mode 100644 index 0000000..99ac1cf --- /dev/null +++ b/src/third_party/freetype2/src/tools/test_trig.c
@@ -0,0 +1,258 @@ +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TRIGONOMETRY_H + +#include <math.h> +#include <stdio.h> + +#define PI 3.14159265358979323846 +#define SPI (PI/FT_ANGLE_PI) + +/* the precision in 16.16 fixed-point checks. Expect between 2 and 5 */ +/* noise LSB bits during operations, due to rounding errors.. */ +#define THRESHOLD 64 + + static error = 0; + + static void + test_cos( void ) + { + int i; + + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L ) + { + FT_Fixed f1, f2; + double d2; + + + f1 = FT_Cos(i); + d2 = cos( i*SPI ); + f2 = (FT_Fixed)(d2*65536.0); + + if ( abs( f2-f1 ) > THRESHOLD ) + { + error = 1; + printf( "FT_Cos[%3d] = %.7f cos[%3d] = %.7f\n", + (i >> 16), f1/65536.0, (i >> 16), d2 ); + } + } + } + + + static void + test_sin( void ) + { + int i; + + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L ) + { + FT_Fixed f1, f2; + double d2; + + + f1 = FT_Sin(i); + d2 = sin( i*SPI ); + f2 = (FT_Fixed)(d2*65536.0); + + if ( abs( f2-f1 ) > THRESHOLD ) + { + error = 1; + printf( "FT_Sin[%3d] = %.7f sin[%3d] = %.7f\n", + (i >> 16), f1/65536.0, (i >> 16), d2 ); + } + } + } + + + static void + test_tan( void ) + { + int i; + + + for ( i = 0; i < FT_ANGLE_PI2 - 0x2000000L; i += 0x10000L ) + { + FT_Fixed f1, f2; + double d2; + + + f1 = FT_Tan(i); + d2 = tan( i*SPI ); + f2 = (FT_Fixed)(d2*65536.0); + + if ( abs( f2-f1 ) > THRESHOLD ) + { + error = 1; + printf( "FT_Tan[%3d] = %.7f tan[%3d] = %.7f\n", + (i >> 16), f1/65536.0, (i >> 16), d2 ); + } + } + } + + + static void + test_atan2( void ) + { + int i; + + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L ) + { + FT_Fixed c2, s2; + double l, a, c1, s1; + int j; + + + l = 5.0; + a = i*SPI; + + c1 = l * cos(a); + s1 = l * sin(a); + + c2 = (FT_Fixed)(c1*65536.0); + s2 = (FT_Fixed)(s1*65536.0); + + j = FT_Atan2( c2, s2 ); + if ( j < 0 ) + j += FT_ANGLE_2PI; + + if ( abs( i - j ) > 1 ) + { + printf( "FT_Atan2( %.7f, %.7f ) = %.5f, atan = %.5f\n", + c2/65536.0, s2/65536.0, j/65536.0, i/65536.0 ); + } + } + } + + + static void + test_unit( void ) + { + int i; + + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L ) + { + FT_Vector v; + double a, c1, s1; + FT_Fixed c2, s2; + + + FT_Vector_Unit( &v, i ); + a = ( i*SPI ); + c1 = cos(a); + s1 = sin(a); + c2 = (FT_Fixed)(c1*65536.0); + s2 = (FT_Fixed)(s1*65536.0); + + if ( abs( v.x-c2 ) > THRESHOLD || + abs( v.y-s2 ) > THRESHOLD ) + { + error = 1; + printf( "FT_Vector_Unit[%3d] = ( %.7f, %.7f ) vec = ( %.7f, %.7f )\n", + (i >> 16), + v.x/65536.0, v.y/65536.0, + c1, s1 ); + } + } + } + + + static void + test_length( void ) + { + int i; + + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L ) + { + FT_Vector v; + FT_Fixed l, l2; + + + l = (FT_Fixed)(500.0*65536.0); + v.x = (FT_Fixed)( l * cos( i*SPI ) ); + v.y = (FT_Fixed)( l * sin( i*SPI ) ); + l2 = FT_Vector_Length( &v ); + + if ( abs( l2-l ) > THRESHOLD ) + { + error = 1; + printf( "FT_Length( %.7f, %.7f ) = %.5f, length = %.5f\n", + v.x/65536.0, v.y/65536.0, l2/65536.0, l/65536.0 ); + } + } + } + + + static void + test_rotate( void ) + { + int rotate; + + + for ( rotate = 0; rotate < FT_ANGLE_2PI; rotate += 0x10000L ) + { + double ra, cra, sra; + int i; + + + ra = rotate*SPI; + cra = cos( ra ); + sra = sin( ra ); + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000L ) + { + FT_Fixed c2, s2, c4, s4; + FT_Vector v; + double l, a, c1, s1, c3, s3; + + + l = 500.0; + a = i*SPI; + + c1 = l * cos(a); + s1 = l * sin(a); + + v.x = c2 = (FT_Fixed)(c1*65536.0); + v.y = s2 = (FT_Fixed)(s1*65536.0); + + FT_Vector_Rotate( &v, rotate ); + + c3 = c1 * cra - s1 * sra; + s3 = c1 * sra + s1 * cra; + + c4 = (FT_Fixed)(c3*65536.0); + s4 = (FT_Fixed)(s3*65536.0); + + if ( abs( c4 - v.x ) > THRESHOLD || + abs( s4 - v.y ) > THRESHOLD ) + { + error = 1; + printf( "FT_Rotate( (%.7f,%.7f), %.5f ) = ( %.7f, %.7f ), rot = ( %.7f, %.7f )\n", + c1, s1, ra, + c2/65536.0, s2/65536.0, + c4/65536.0, s4/65536.0 ); + } + } + } + } + + + int main( void ) + { + test_cos(); + test_sin(); + test_tan(); + test_atan2(); + test_unit(); + test_length(); + test_rotate(); + + if (!error) + printf( "trigonometry test ok !\n" ); + + return !error; + }
diff --git a/src/third_party/freetype2/src/tools/update-copyright b/src/third_party/freetype2/src/tools/update-copyright new file mode 100755 index 0000000..4a8bf9b --- /dev/null +++ b/src/third_party/freetype2/src/tools/update-copyright
@@ -0,0 +1,14 @@ +#!/bin/sh + +# Run the `update-copyright-year' script on all files in the git repository, +# taking care of exceptions stored in file `no-copyright'. + +topdir=`git rev-parse --show-toplevel` +toolsdir=$topdir/src/tools + +git ls-files --full-name $topdir \ +| sed 's|^|../../|' \ +| grep -vFf $toolsdir/no-copyright \ +| xargs $toolsdir/update-copyright-year + +# EOF
diff --git a/src/third_party/freetype2/src/tools/update-copyright-year b/src/third_party/freetype2/src/tools/update-copyright-year new file mode 100755 index 0000000..c659bba --- /dev/null +++ b/src/third_party/freetype2/src/tools/update-copyright-year
@@ -0,0 +1,138 @@ +eval '(exit $?0)' && eval 'exec perl -wS -i "$0" ${1+"$@"}' + & eval 'exec perl -wS -i "$0" $argv:q' + if 0; + +# Copyright (C) 2015-2020 by +# Werner Lemberg. +# +# This file is part of the FreeType project, and may only be used, modified, +# and distributed under the terms of the FreeType project license, +# LICENSE.TXT. By continuing to use, modify, or distribute this file you +# indicate that you have read the license and understand and accept it +# fully. + +# [Note: This script is expected to be called by the shell, which in turn +# calls perl automatically. The nifty start-up code above is based on +# gnulib's `update-copyright' script; it is a more portable replacement for +# the shebang, using the first `perl' program in the shell's path instead.] + +# Usage: +# +# update-copyright-year file1 [file2 ...] + + +# This script handles copyright entries like +# +# Copyright 2000 by +# foobar +# +# or +# +# /* Copyright 2000, 2001, 2004-2007 by */ +# /* foobar */ +# +# and replaces them uniformly with +# +# Copyright 2000-2015 +# foobar +# +# and +# +# /* Copyright 2000-2015 by */ +# /* foobar */ +# +# (assuming that the current year is 2015). As can be seen, the line length +# is retained if there is non-whitespace after the word `by' on the same +# line. + +use strict; + + +my (undef, undef, undef, + undef, undef, $year, + undef, undef, undef) = localtime(time); +$year += 1900; + +my $replaced = 0; + + +# Loop over all input files; option `-i' (issued at the very beginning of +# this script) makes perl edit them in-place. +while (<>) +{ + # Only handle the first copyright notice in a file. + if (!$replaced) + { + # First try: Search multiple copyright years. + s { + (?<begin>.*) + Copyright + (?<space1>(\ + + | \ +\(C\)\ +)) + (?<first>[12][0-9][0-9][0-9]) + (?<middle>.+) + (?<last>[12][0-9][0-9][0-9]) + (?<space2>\ +) + by + (?<space3>\ *) + (?<end>.*) + } + { + # Fill line to the same length (if appropriate); we skip the middle + # part but insert `(C)', three spaces, and `-'. + my $space = length($+{space1}) - 1 + + length($+{middle}) - 1 + + length($+{space2}) - 1 + + length($+{space3}) + - (length("(C)") + 1); + + print "$+{begin}"; + print "Copyright\ (C)\ $+{first}-$year\ by"; + print ' ' x $space if length($+{end}); + print "$+{end}\n"; + $replaced = 1; + }ex + || + # Second try: Search a single copyright year. + s { + (?<begin>.*) + Copyright + (?<space1>(\ + + | \ +\(C\)\ +)) + (?<first>[12][0-9][0-9][0-9]) + (?<space2>\ +) + by + (?<space3>\ *) + (?<end>.*) + } + { + # Fill line to the same length (if appropriate); we insert three + # spaces, a `-', and the current year. + my $space = length($+{space1}) - 1 + + length($+{space2}) - 1 + + length($+{space3}) + - (length($year) + 1); + + print "$+{begin}"; + print "Copyright\ (C)\ $+{first}-$year\ by"; + # If $space is negative this inserts nothing. + print ' ' x $space if length($+{end}); + print "$+{end}\n"; + $replaced = 1; + }ex + || + # Otherwise print line unaltered. + print; + } + else + { + print; + } +} +continue +{ + # Reset $replaced before processing the next file. + $replaced = 0 if eof; +} + +# EOF
diff --git a/src/third_party/inspector_protocol/crdtp/json_platform.cc b/src/third_party/inspector_protocol/crdtp/json_platform.cc index 59c8deb..21e26ce 100644 --- a/src/third_party/inspector_protocol/crdtp/json_platform.cc +++ b/src/third_party/inspector_protocol/crdtp/json_platform.cc
@@ -16,6 +16,9 @@ namespace json { namespace platform { bool StrToD(const char* str, double* result) { +#if SB_IS(EVERGREEN) +#error "The std::locale::classic() is not supported for Evergreen. Please use base::StringToDouble()." +#endif std::istringstream is(str); is.imbue(std::locale::classic()); is >> *result; @@ -23,6 +26,9 @@ } std::string DToStr(double value) { +#if SB_IS(EVERGREEN) +#error "The std::locale::classic() is not supported for Evergreen. Please use base::NumberToString()." +#endif std::stringstream ss; ss.imbue(std::locale::classic()); ss << value;
diff --git a/src/third_party/libevent/evdns.c b/src/third_party/libevent/evdns.c index 05fe594..d72fdaa 100644 --- a/src/third_party/libevent/evdns.c +++ b/src/third_party/libevent/evdns.c
@@ -783,7 +783,6 @@ for(;;) { u8 label_len; - if (j >= length) return -1; GET8(label_len); if (!label_len) break; if (label_len & 0xc0) { @@ -804,6 +803,7 @@ *cp++ = '.'; } if (cp + label_len >= end) return -1; + if (j + label_len > length) return -1; memcpy(cp, packet + j, label_len); cp += label_len; j += label_len;
diff --git a/src/third_party/libxml/src/entities.c b/src/third_party/libxml/src/entities.c index ea54cc3..4b41fe9 100644 --- a/src/third_party/libxml/src/entities.c +++ b/src/third_party/libxml/src/entities.c
@@ -667,11 +667,25 @@ } else { /* * We assume we have UTF-8 input. + * It must match either: + * 110xxxxx 10xxxxxx + * 1110xxxx 10xxxxxx 10xxxxxx + * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * That is: + * cur[0] is 11xxxxxx + * cur[1] is 10xxxxxx + * cur[2] is 10xxxxxx if cur[0] is 111xxxxx + * cur[3] is 10xxxxxx if cur[0] is 1111xxxx + * cur[0] is not 11111xxx */ char buf[11], *ptr; int val = 0, l = 1; - if (*cur < 0xC0) { + if (((cur[0] & 0xC0) != 0xC0) || + ((cur[1] & 0xC0) != 0x80) || + (((cur[0] & 0xE0) == 0xE0) && ((cur[2] & 0xC0) != 0x80)) || + (((cur[0] & 0xF0) == 0xF0) && ((cur[3] & 0xC0) != 0x80)) || + (((cur[0] & 0xF8) == 0xF8))) { xmlEntitiesErr(XML_CHECK_NOT_UTF8, "xmlEncodeEntities: input not UTF-8"); if (doc != NULL)
diff --git a/src/third_party/skia/src/sksl/SkSLString.cpp b/src/third_party/skia/src/sksl/SkSLString.cpp index 433744a..c8124da 100644 --- a/src/third_party/skia/src/sksl/SkSLString.cpp +++ b/src/third_party/skia/src/sksl/SkSLString.cpp
@@ -15,6 +15,8 @@ #include <sstream> #include <string> +#include "base/strings/string_number_conversions.h" + #if defined(STARBOARD) #include "starboard/client_porting/poem/stdio_leaks_poem.h" #include "starboard/client_porting/poem/stdlib_poem.h" @@ -229,6 +231,24 @@ } String to_string(double value) { +#if defined(STARBOARD) + std::string s = base::NumberToString(value); + bool needsDotZero = true; + for (int i = s.size() - 1; i >= 0; --i) { + char c = s[i]; + if (c == '.' || c == 'e') { + needsDotZero = false; + break; + } + } + if (needsDotZero) { + s += ".0"; + } + if (s.size() > 0 && s[0] == '.') { + s = "0" + s; + } + return String(s.c_str()); +#else std::stringstream buffer; buffer.imbue(std::locale::classic()); buffer.precision(17); @@ -246,6 +266,7 @@ buffer << ".0"; } return String(buffer.str().c_str()); +#endif } SKSL_INT stoi(const String& s) { @@ -258,6 +279,12 @@ } SKSL_FLOAT stod(const String& s) { +#if defined(STARBOARD) + double d; + bool res= base::StringToDouble(s.c_str(), &d); + SkASSERT(res); + return d; +#else double result; std::string str(s.c_str(), s.size()); std::stringstream buffer(str); @@ -265,6 +292,7 @@ buffer >> result; SkASSERT(!buffer.fail()); return result; +#endif } long stol(const String& s) {
diff --git a/src/tools/__init__.py b/src/tools/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/tools/__init__.py
diff --git a/src/tools/download_from_gcs.py b/src/tools/download_from_gcs.py index fc7c8ee..9c79dfb 100755 --- a/src/tools/download_from_gcs.py +++ b/src/tools/download_from_gcs.py
@@ -56,7 +56,13 @@ url = '{}/{}/{}'.format(_BASE_GCS_URL, bucket, sha1) context = create_default_context() - res = urllib.urlopen(url, context=context) if context else urllib.urlopen(url) + try: + res = urllib.urlopen(url, context=context) if context else urllib.urlopen(url) + except urllib.URLError: + from ssl import _create_unverified_context + context = _create_unverified_context() + res = urllib.urlopen(url, context=context) if context else urllib.urlopen(url) + if not res: logging.error('Could not reach %s', url) return None
diff --git a/src/tools/gyp/pylib/gyp/MSVSVersion.py b/src/tools/gyp/pylib/gyp/MSVSVersion.py index 0dacf85..cae2c88 100644 --- a/src/tools/gyp/pylib/gyp/MSVSVersion.py +++ b/src/tools/gyp/pylib/gyp/MSVSVersion.py
@@ -324,10 +324,13 @@ if not os.path.exists(path): path = r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE' path = _ConvertToCygpath(path) - full_path = os.path.join(path, 'devenv.exe') - if os.path.exists(full_path) and version in version_to_year: + devenv_path = os.path.join(path, 'devenv.exe') + devenv_ini_path = os.path.join(path, 'devenv.isolation.ini') + if (os.path.exists(devenv_path) or os.path.exists(devenv_ini_path)) and version in version_to_year: versions.append(_CreateVersion(version_to_year[version], os.path.join(path, '..', '..'))) + else: + print('_DetectVisualStudioVersion() did not find Visual Studio 2017 (v15.0)') continue # Old method of searching for which VS version is installed # We don't use the 2010-encouraged-way because we also want to get the
diff --git a/src/tools/gyp/pylib/gyp/msvs_emulation.py b/src/tools/gyp/pylib/gyp/msvs_emulation.py index 068ad1e..3951c19 100755 --- a/src/tools/gyp/pylib/gyp/msvs_emulation.py +++ b/src/tools/gyp/pylib/gyp/msvs_emulation.py
@@ -747,6 +747,7 @@ 'cell_.*', 'sn_.*', 'sce_.*', + 'is_docker', ) env = {} for line in output_of_set.splitlines():
diff --git a/src/tools/imagediff/image_diff.cc b/src/tools/imagediff/image_diff.cc deleted file mode 100644 index 19d5df9..0000000 --- a/src/tools/imagediff/image_diff.cc +++ /dev/null
@@ -1,382 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file input format is based loosely on -// Tools/DumpRenderTree/ImageDiff.m - -// The exact format of this tool's output to stdout is important, to match -// what the run-webkit-tests script expects. - -#include <algorithm> -#include <vector> -#include <string> -#include <iostream> - -#include "base/basictypes.h" -#include "base/command_line.h" -#include "base/file_path.h" -#include "base/file_util.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/process_util.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "ui/gfx/codec/png_codec.h" -#include "ui/gfx/size.h" - -#if defined(OS_WIN) -#include "windows.h" -#endif - -// Causes the app to remain open, waiting for pairs of filenames on stdin. -// The caller is then responsible for terminating this app. -static const char kOptionPollStdin[] = "use-stdin"; -static const char kOptionGenerateDiff[] = "diff"; - -// Return codes used by this utility. -static const int kStatusSame = 0; -static const int kStatusDifferent = 1; -static const int kStatusError = 2; - -// Color codes. -static const uint32 RGBA_RED = 0x000000ff; -static const uint32 RGBA_ALPHA = 0xff000000; - -class Image { - public: - Image() : w_(0), h_(0) { - } - - Image(const Image& image) - : w_(image.w_), - h_(image.h_), - data_(image.data_) { - } - - bool has_image() const { - return w_ > 0 && h_ > 0; - } - - int w() const { - return w_; - } - - int h() const { - return h_; - } - - const unsigned char* data() const { - return &data_.front(); - } - - // Creates the image from stdin with the given data length. On success, it - // will return true. On failure, no other methods should be accessed. - bool CreateFromStdin(size_t byte_length) { - if (byte_length == 0) - return false; - - scoped_array<unsigned char> source(new unsigned char[byte_length]); - if (fread(source.get(), 1, byte_length, stdin) != byte_length) - return false; - - if (!gfx::PNGCodec::Decode(source.get(), byte_length, - gfx::PNGCodec::FORMAT_RGBA, - &data_, &w_, &h_)) { - Clear(); - return false; - } - return true; - } - - // Creates the image from the given filename on disk, and returns true on - // success. - bool CreateFromFilename(const FilePath& path) { - FILE* f = file_util::OpenFile(path, "rb"); - if (!f) - return false; - - std::vector<unsigned char> compressed; - const int buf_size = 1024; - unsigned char buf[buf_size]; - size_t num_read = 0; - while ((num_read = fread(buf, 1, buf_size, f)) > 0) { - compressed.insert(compressed.end(), buf, buf + num_read); - } - - file_util::CloseFile(f); - - if (!gfx::PNGCodec::Decode(&compressed[0], compressed.size(), - gfx::PNGCodec::FORMAT_RGBA, &data_, &w_, &h_)) { - Clear(); - return false; - } - return true; - } - - void Clear() { - w_ = h_ = 0; - data_.clear(); - } - - // Returns the RGBA value of the pixel at the given location - uint32 pixel_at(int x, int y) const { - DCHECK(x >= 0 && x < w_); - DCHECK(y >= 0 && y < h_); - return *reinterpret_cast<const uint32*>(&(data_[(y * w_ + x) * 4])); - } - - void set_pixel_at(int x, int y, uint32 color) const { - DCHECK(x >= 0 && x < w_); - DCHECK(y >= 0 && y < h_); - void* addr = &const_cast<unsigned char*>(&data_.front())[(y * w_ + x) * 4]; - *reinterpret_cast<uint32*>(addr) = color; - } - - private: - // pixel dimensions of the image - int w_, h_; - - std::vector<unsigned char> data_; -}; - -float PercentageDifferent(const Image& baseline, const Image& actual) { - int w = std::min(baseline.w(), actual.w()); - int h = std::min(baseline.h(), actual.h()); - - // compute pixels different in the overlap - int pixels_different = 0; - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - if (baseline.pixel_at(x, y) != actual.pixel_at(x, y)) - pixels_different++; - } - } - - // count pixels that are a difference in size as also being different - int max_w = std::max(baseline.w(), actual.w()); - int max_h = std::max(baseline.h(), actual.h()); - - // ...pixels off the right side, but not including the lower right corner - pixels_different += (max_w - w) * h; - - // ...pixels along the bottom, including the lower right corner - pixels_different += (max_h - h) * max_w; - - // Like the WebKit ImageDiff tool, we define percentage different in terms - // of the size of the 'actual' bitmap. - float total_pixels = static_cast<float>(actual.w()) * - static_cast<float>(actual.h()); - if (total_pixels == 0) - return 100.0f; // when the bitmap is empty, they are 100% different - return static_cast<float>(pixels_different) / total_pixels * 100; -} - -void PrintHelp() { - fprintf(stderr, - "Usage:\n" - " image_diff <compare file> <reference file>\n" - " Compares two files on disk, returning 0 when they are the same\n" - " image_diff --use-stdin\n" - " Stays open reading pairs of filenames from stdin, comparing them,\n" - " and sending 0 to stdout when they are the same\n" - " image_diff --diff <compare file> <reference file> <output file>\n" - " Compares two files on disk, outputs an image that visualizes the" - " difference to <output file>\n"); - /* For unfinished webkit-like-mode (see below) - "\n" - " image_diff -s\n" - " Reads stream input from stdin, should be EXACTLY of the format\n" - " \"Content-length: <byte length> <data>Content-length: ...\n" - " it will take as many file pairs as given, and will compare them as\n" - " (cmp_file, reference_file) pairs\n"); - */ -} - -int CompareImages(const FilePath& file1, const FilePath& file2) { - Image actual_image; - Image baseline_image; - - if (!actual_image.CreateFromFilename(file1)) { - fprintf(stderr, "image_diff: Unable to open file \"%" PRFilePath "\"\n", - file1.value().c_str()); - return kStatusError; - } - if (!baseline_image.CreateFromFilename(file2)) { - fprintf(stderr, "image_diff: Unable to open file \"%" PRFilePath "\"\n", - file2.value().c_str()); - return kStatusError; - } - - float percent = PercentageDifferent(actual_image, baseline_image); - if (percent > 0.0) { - // failure: The WebKit version also writes the difference image to - // stdout, which seems excessive for our needs. - printf("diff: %01.2f%% failed\n", percent); - return kStatusDifferent; - } - - // success - printf("diff: %01.2f%% passed\n", percent); - return kStatusSame; - -/* Untested mode that acts like WebKit's image comparator. I wrote this but - decided it's too complicated. We may use it in the future if it looks useful - - char buffer[2048]; - while (fgets(buffer, sizeof(buffer), stdin)) { - - if (strncmp("Content-length: ", buffer, 16) == 0) { - char* context; - strtok_s(buffer, " ", &context); - int image_size = strtol(strtok_s(NULL, " ", &context), NULL, 10); - - bool success = false; - if (image_size > 0 && actual_image.has_image() == 0) { - if (!actual_image.CreateFromStdin(image_size)) { - fputs("Error, input image can't be decoded.\n", stderr); - return 1; - } - } else if (image_size > 0 && baseline_image.has_image() == 0) { - if (!baseline_image.CreateFromStdin(image_size)) { - fputs("Error, baseline image can't be decoded.\n", stderr); - return 1; - } - } else { - fputs("Error, image size must be specified.\n", stderr); - return 1; - } - } - - if (actual_image.has_image() && baseline_image.has_image()) { - float percent = PercentageDifferent(actual_image, baseline_image); - if (percent > 0.0) { - // failure: The WebKit version also writes the difference image to - // stdout, which seems excessive for our needs. - printf("diff: %01.2f%% failed\n", percent); - } else { - // success - printf("diff: %01.2f%% passed\n", percent); - } - actual_image.Clear(); - baseline_image.Clear(); - } - - fflush(stdout); - } -*/ -} - -bool CreateImageDiff(const Image& image1, const Image& image2, Image* out) { - int w = std::min(image1.w(), image2.w()); - int h = std::min(image1.h(), image2.h()); - *out = Image(image1); - bool same = (image1.w() == image2.w()) && (image1.h() == image2.h()); - - // TODO(estade): do something with the extra pixels if the image sizes - // are different. - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - uint32 base_pixel = image1.pixel_at(x, y); - if (base_pixel != image2.pixel_at(x, y)) { - // Set differing pixels red. - out->set_pixel_at(x, y, RGBA_RED | RGBA_ALPHA); - same = false; - } else { - // Set same pixels as faded. - uint32 alpha = base_pixel & RGBA_ALPHA; - uint32 new_pixel = base_pixel - ((alpha / 2) & RGBA_ALPHA); - out->set_pixel_at(x, y, new_pixel); - } - } - } - - return same; -} - -int DiffImages(const FilePath& file1, const FilePath& file2, - const FilePath& out_file) { - Image actual_image; - Image baseline_image; - - if (!actual_image.CreateFromFilename(file1)) { - fprintf(stderr, "image_diff: Unable to open file \"%" PRFilePath "\"\n", - file1.value().c_str()); - return kStatusError; - } - if (!baseline_image.CreateFromFilename(file2)) { - fprintf(stderr, "image_diff: Unable to open file \"%" PRFilePath "\"\n", - file2.value().c_str()); - return kStatusError; - } - - Image diff_image; - bool same = CreateImageDiff(baseline_image, actual_image, &diff_image); - if (same) - return kStatusSame; - - std::vector<unsigned char> png_encoding; - gfx::PNGCodec::Encode(diff_image.data(), gfx::PNGCodec::FORMAT_RGBA, - gfx::Size(diff_image.w(), diff_image.h()), - diff_image.w() * 4, false, - std::vector<gfx::PNGCodec::Comment>(), &png_encoding); - if (file_util::WriteFile(out_file, - reinterpret_cast<char*>(&png_encoding.front()), png_encoding.size()) < 0) - return kStatusError; - - return kStatusDifferent; -} - -// It isn't strictly correct to only support ASCII paths, but this -// program reads paths on stdin and the program that spawns it outputs -// paths as non-wide strings anyway. -FilePath FilePathFromASCII(const std::string& str) { -#if defined(OS_WIN) - return FilePath(ASCIIToWide(str)); -#else - return FilePath(str); -#endif -} - -int main(int argc, const char* argv[]) { - base::EnableTerminationOnHeapCorruption(); - CommandLine::Init(argc, argv); - const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); - if (parsed_command_line.HasSwitch(kOptionPollStdin)) { - // Watch stdin for filenames. - std::string stdin_buffer; - FilePath filename1; - while (std::getline(std::cin, stdin_buffer)) { - if (stdin_buffer.empty()) - continue; - - if (!filename1.empty()) { - // CompareImages writes results to stdout unless an error occurred. - FilePath filename2 = FilePathFromASCII(stdin_buffer); - if (CompareImages(filename1, filename2) == kStatusError) - printf("error\n"); - fflush(stdout); - filename1 = FilePath(); - } else { - // Save the first filename in another buffer and wait for the second - // filename to arrive via stdin. - filename1 = FilePathFromASCII(stdin_buffer); - } - } - return 0; - } - - const CommandLine::StringVector& args = parsed_command_line.GetArgs(); - if (parsed_command_line.HasSwitch(kOptionGenerateDiff)) { - if (args.size() == 3) { - return DiffImages(FilePath(args[0]), - FilePath(args[1]), - FilePath(args[2])); - } - } else if (args.size() == 2) { - return CompareImages(FilePath(args[0]), FilePath(args[1])); - } - - PrintHelp(); - return kStatusError; -}
diff --git a/src/tools/imagediff/image_diff.gyp b/src/tools/imagediff/image_diff.gyp deleted file mode 100644 index 6d4a620..0000000 --- a/src/tools/imagediff/image_diff.gyp +++ /dev/null
@@ -1,22 +0,0 @@ -# Copyright (c) 2009 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -{ - 'variables': { - 'chromium_code': 1, - }, - 'targets' : [ - { - 'target_name': 'image_diff', - 'type': 'executable', - 'dependencies': [ - '../../base/base.gyp:base', - '../../ui/ui.gyp:ui', - ], - 'sources': [ - 'image_diff.cc', - ], - }, - ], -}
diff --git a/src/v8/regress-1051017.js b/src/v8/regress-1051017.js new file mode 100644 index 0000000..142b563 --- /dev/null +++ b/src/v8/regress-1051017.js
@@ -0,0 +1,48 @@ +// Copyright 2020 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + + +function foo1() { + var x = -Infinity; + var i = 0; + for (; i < 1; i += x) { + if (i == -Infinity) x = +Infinity; + } + return i; +} + +%PrepareFunctionForOptimization(foo1); +assertEquals(NaN, foo1()); +assertEquals(NaN, foo1()); +%OptimizeFunctionOnNextCall(foo1); +assertEquals(NaN, foo1()); + + +function foo2() { + var i = -Infinity; + for (; i <= 42; i += Infinity) { } + return i; +} + +%PrepareFunctionForOptimization(foo2); +assertEquals(NaN, foo2()); +assertEquals(NaN, foo2()); +%OptimizeFunctionOnNextCall(foo2); +assertEquals(NaN, foo2()); + + +function foo3(b) { + var k = 0; + let str = b ? "42" : "0"; + for (var i = str; i < 1 && k++ < 1; i -= 0) { } + return i; +} + +%PrepareFunctionForOptimization(foo3); +assertEquals(0, foo3()); +assertEquals(0, foo3()); +%OptimizeFunctionOnNextCall(foo3); +assertEquals(0, foo3());
diff --git a/src/v8/src/compiler/js-create-lowering.cc b/src/v8/src/compiler/js-create-lowering.cc index 4e69db6..fe60eaa 100644 --- a/src/v8/src/compiler/js-create-lowering.cc +++ b/src/v8/src/compiler/js-create-lowering.cc
@@ -667,6 +667,9 @@ length_type.Max() <= kElementLoopUnrollLimit && length_type.Min() == length_type.Max()) { int capacity = static_cast<int>(length_type.Max()); + // Replace length with a constant in order to protect against a potential + // typer bug leading to length > capacity. + length = jsgraph()->Constant(capacity); return ReduceNewArray(node, length, capacity, *initial_map, elements_kind, allocation, slack_tracking_prediction); }
diff --git a/src/v8/src/compiler/typer.cc b/src/v8/src/compiler/typer.cc index ae1590a..956f0ec 100644 --- a/src/v8/src/compiler/typer.cc +++ b/src/v8/src/compiler/typer.cc
@@ -211,6 +211,9 @@ Type TypeConstant(Handle<Object> value); + bool InductionVariablePhiTypeIsPrefixedPoint( + InductionVariable* induction_var); + private: Typer* typer_; LoopVariableOptimizer* induction_vars_; @@ -251,7 +254,8 @@ using BinaryTyperFun = Type (*)(Type, Type, Typer* t); Type TypeUnaryOp(Node* node, UnaryTyperFun); - Type TypeBinaryOp(Node* node, BinaryTyperFun); + inline Type TypeBinaryOp(Node* node, BinaryTyperFun); + inline Type TypeBinaryOp(Type left, Type right, BinaryTyperFun); static Type BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t, BinaryTyperFun f); @@ -299,7 +303,21 @@ SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_METHOD) SIMPLIFIED_SPECULATIVE_BIGINT_BINOP_LIST(DECLARE_METHOD) #undef DECLARE_METHOD - +#define DECLARE_METHOD(Name) \ + inline Type Type##Name(Type left, Type right) { \ + return TypeBinaryOp(left, right, Name##Typer); \ + } + JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) +#undef DECLARE_METHOD +#define DECLARE_METHOD(Name) \ + inline Type Type##Name(Type left, Type right) { \ + return TypeBinaryOp(left, right, Name); \ + } + SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD) + SIMPLIFIED_BIGINT_BINOP_LIST(DECLARE_METHOD) + SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_METHOD) + SIMPLIFIED_SPECULATIVE_BIGINT_BINOP_LIST(DECLARE_METHOD) +#undef DECLARE_METHOD static Type ObjectIsArrayBufferView(Type, Typer*); static Type ObjectIsBigInt(Type, Typer*); static Type ObjectIsCallable(Type, Typer*); @@ -430,6 +448,14 @@ graph_reducer.ReduceGraph(); if (induction_vars != nullptr) { + // Validate the types computed by TypeInductionVariablePhi. + for (auto entry : induction_vars->induction_variables()) { + InductionVariable* induction_var = entry.second; + if (induction_var->phi()->opcode() == IrOpcode::kInductionVariablePhi) { + CHECK(visitor.InductionVariablePhiTypeIsPrefixedPoint(induction_var)); + } + } + induction_vars->ChangeToPhisAndInsertGuards(); } } @@ -466,6 +492,10 @@ Type Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) { Type left = Operand(node, 0); Type right = Operand(node, 1); + return TypeBinaryOp(left, right, f); +} + +Type Typer::Visitor::TypeBinaryOp(Type left, Type right, BinaryTyperFun f) { return left.IsNone() || right.IsNone() ? Type::None() : f(left, right, typer_); } @@ -843,15 +873,23 @@ Type initial_type = Operand(node, 0); Type increment_type = Operand(node, 2); - // We only handle integer induction variables (otherwise ranges - // do not apply and we cannot do anything). - if (!initial_type.Is(typer_->cache_->kInteger) || - !increment_type.Is(typer_->cache_->kInteger)) { - // Fallback to normal phi typing, but ensure monotonicity. - // (Unfortunately, without baking in the previous type, monotonicity might - // be violated because we might not yet have retyped the incrementing - // operation even though the increment's type might been already reflected - // in the induction variable phi.) + // Fallback to normal phi typing in a variety of cases: + // - when the induction variable is not initially of type Integer, because we + // want to work with ranges in the algorithm below. + // - when the increment is zero, because in that case normal phi typing will + // generally yield a more precise type. + // - when the induction variable can become NaN (through addition/subtraction + // of opposing infinities), because the code below can't handle that case. + if (initial_type.IsNone() || + increment_type.Is(typer_->cache_->kSingletonZero) || + !initial_type.Is(typer_->cache_->kInteger) || + !increment_type.Is(typer_->cache_->kInteger) || + increment_type.Min() == -V8_INFINITY || + increment_type.Max() == +V8_INFINITY) { + // Unfortunately, without baking in the previous type, monotonicity might be + // violated because we might not yet have retyped the incrementing operation + // even though the increment's type might been already reflected in the + // induction variable phi. Type type = NodeProperties::IsTyped(node) ? NodeProperties::GetType(node) : Type::None(); for (int i = 0; i < arity; ++i) { @@ -859,18 +897,10 @@ } return type; } - // If we do not have enough type information for the initial value or - // the increment, just return the initial value's type. - if (initial_type.IsNone() || - increment_type.Is(typer_->cache_->kSingletonZero)) { - return initial_type; - } - // Now process the bounds. auto res = induction_vars_->induction_variables().find(node->id()); - DCHECK(res != induction_vars_->induction_variables().end()); + DCHECK_NE(res, induction_vars_->induction_variables().end()); InductionVariable* induction_var = res->second; - InductionVariable::ArithmeticType arithmetic_type = induction_var->Type(); double min = -V8_INFINITY; @@ -882,13 +912,13 @@ increment_min = increment_type.Min(); increment_max = increment_type.Max(); } else { - DCHECK_EQ(InductionVariable::ArithmeticType::kSubtraction, arithmetic_type); + DCHECK_EQ(arithmetic_type, InductionVariable::ArithmeticType::kSubtraction); increment_min = -increment_type.Max(); increment_max = -increment_type.Min(); } if (increment_min >= 0) { - // increasing sequence + // Increasing sequence. min = initial_type.Min(); for (auto bound : induction_var->upper_bounds()) { Type bound_type = TypeOrNone(bound.bound); @@ -908,7 +938,7 @@ // The upper bound must be at least the initial value's upper bound. max = std::max(max, initial_type.Max()); } else if (increment_max <= 0) { - // decreasing sequence + // Decreasing sequence. max = initial_type.Max(); for (auto bound : induction_var->lower_bounds()) { Type bound_type = TypeOrNone(bound.bound); @@ -928,9 +958,11 @@ // The lower bound must be at most the initial value's lower bound. min = std::min(min, initial_type.Min()); } else { - // Shortcut: If the increment can be both positive and negative, - // the variable can go arbitrarily far, so just return integer. - return typer_->cache_->kInteger; + // If the increment can be both positive and negative, the variable can go + // arbitrarily far. Use the maximal range in that case. Note that this may + // be less precise than what ordinary typing would produce. + min = -V8_INFINITY; + max = +V8_INFINITY; } #ifndef V8_OS_STARBOARD if (FLAG_trace_turbo_loop) { @@ -945,9 +977,68 @@ << ")\n"; } #endif + return Type::Range(min, max, typer_->zone()); } +bool Typer::Visitor::InductionVariablePhiTypeIsPrefixedPoint( + InductionVariable* induction_var) { + Node* node = induction_var->phi(); + DCHECK_EQ(node->opcode(), IrOpcode::kInductionVariablePhi); + Type type = NodeProperties::GetType(node); + Type initial_type = Operand(node, 0); + Node* arith = node->InputAt(1); + Type increment_type = Operand(node, 2); + + // Intersect {type} with useful bounds. + for (auto bound : induction_var->upper_bounds()) { + Type bound_type = TypeOrNone(bound.bound); + if (!bound_type.Is(typer_->cache_->kInteger)) continue; + if (!bound_type.IsNone()) { + bound_type = Type::Range( + -V8_INFINITY, + bound_type.Max() - (bound.kind == InductionVariable::kStrict), + zone()); + } + type = Type::Intersect(type, bound_type, typer_->zone()); + } + for (auto bound : induction_var->lower_bounds()) { + Type bound_type = TypeOrNone(bound.bound); + if (!bound_type.Is(typer_->cache_->kInteger)) continue; + if (!bound_type.IsNone()) { + bound_type = Type::Range( + bound_type.Min() + (bound.kind == InductionVariable::kStrict), + +V8_INFINITY, typer_->zone()); + } + type = Type::Intersect(type, bound_type, typer_->zone()); + } + + // Apply ordinary typing to the "increment" operation. + // clang-format off + switch (arith->opcode()) { +#define CASE(x) \ + case IrOpcode::k##x: \ + type = Type##x(type, increment_type); \ + break; + CASE(JSAdd) + CASE(JSSubtract) + CASE(NumberAdd) + CASE(NumberSubtract) + CASE(SpeculativeNumberAdd) + CASE(SpeculativeNumberSubtract) + CASE(SpeculativeSafeIntegerAdd) + CASE(SpeculativeSafeIntegerSubtract) +#undef CASE + default: + UNREACHABLE(); + } + // clang-format on + + type = Type::Union(initial_type, type, typer_->zone()); + + return type.Is(NodeProperties::GetType(node)); +} + Type Typer::Visitor::TypeEffectPhi(Node* node) { UNREACHABLE(); } Type Typer::Visitor::TypeLoopExit(Node* node) { UNREACHABLE(); }