Update from https://crrev.com/304715
Includes patches to sky/viewer/cc/ and ui/compositor/ for the following:
cc: Toggle LCD text at raster time instead of record time.
https://codereview.chromium.org/684543006
https://crrev.com/304623
and
Make Keyframe use TimeTicks/TimeDelta to represent time instead of double.
https://codereview.chromium.org/719453007
https://crrev.com/304612
Review URL: https://codereview.chromium.org/737943002
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 959d462..2cce16c 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1108,6 +1108,13 @@
]
}
+# TODO(pasko): Remove this target when crbug.com/424562 is fixed.
+source_set("protect_file_posix") {
+ sources = [
+ "files/protect_file_posix.cc",
+ ]
+}
+
test("base_unittests") {
sources = [
"android/application_status_listener_unittest.cc",
diff --git a/base/base.gyp b/base/base.gyp
index ad4dd22..e31cf18 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -377,6 +377,18 @@
],
},
{
+ # TODO(pasko): Remove this target when crbug.com/424562 is fixed.
+ # GN: //base:protect_file_posix
+ 'target_name': 'protect_file_posix',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'base',
+ ],
+ 'sources': [
+ 'files/protect_file_posix.cc',
+ ],
+ },
+ {
'target_name': 'base_prefs_test_support',
'type': 'static_library',
'dependencies': [
diff --git a/base/files/file.cc b/base/files/file.cc
index ea8dbf2..a997074 100644
--- a/base/files/file.cc
+++ b/base/files/file.cc
@@ -5,6 +5,10 @@
#include "base/files/file.h"
#include "base/files/file_path.h"
+#if defined(OS_POSIX)
+#include "base/files/file_posix_hooks_internal.h"
+#endif
+
namespace base {
File::Info::Info()
@@ -38,6 +42,8 @@
async_(false) {
#if defined(OS_POSIX)
DCHECK_GE(platform_file, -1);
+ if (IsValid())
+ ProtectFileDescriptor(platform_file);
#endif
}
@@ -52,6 +58,10 @@
error_details_(other.object->error_details()),
created_(other.object->created()),
async_(other.object->async_) {
+#if defined(OS_POSIX)
+ if (IsValid())
+ ProtectFileDescriptor(GetPlatformFile());
+#endif
}
File::~File() {
diff --git a/base/files/file_posix.cc b/base/files/file_posix.cc
index 3d229e4..245ea6a 100644
--- a/base/files/file_posix.cc
+++ b/base/files/file_posix.cc
@@ -10,6 +10,7 @@
#include <unistd.h>
#include "base/files/file_path.h"
+#include "base/files/file_posix_hooks_internal.h"
#include "base/logging.h"
#include "base/metrics/sparse_histogram.h"
#include "base/posix/eintr_wrapper.h"
@@ -166,6 +167,14 @@
Time::kNanosecondsPerMicrosecond);
}
+// Default implementations of Protect/Unprotect hooks defined as weak symbols
+// where possible.
+void ProtectFileDescriptor(int fd) {
+}
+
+void UnprotectFileDescriptor(int fd) {
+}
+
// NaCl doesn't implement system calls to open files directly.
#if !defined(OS_NACL)
// TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here?
@@ -252,6 +261,7 @@
async_ = ((flags & FLAG_ASYNC) == FLAG_ASYNC);
error_details_ = FILE_OK;
file_.reset(descriptor);
+ ProtectFileDescriptor(descriptor);
}
#endif // !defined(OS_NACL)
@@ -264,6 +274,8 @@
}
PlatformFile File::TakePlatformFile() {
+ if (IsValid())
+ UnprotectFileDescriptor(GetPlatformFile());
return file_.release();
}
@@ -272,6 +284,7 @@
return;
base::ThreadRestrictions::AssertIOAllowed();
+ UnprotectFileDescriptor(GetPlatformFile());
file_.reset();
}
@@ -527,8 +540,10 @@
}
void File::SetPlatformFile(PlatformFile file) {
- DCHECK(!file_.is_valid());
+ CHECK(!file_.is_valid());
file_.reset(file);
+ if (file_.is_valid())
+ ProtectFileDescriptor(GetPlatformFile());
}
} // namespace base
diff --git a/base/files/file_posix_hooks_internal.h b/base/files/file_posix_hooks_internal.h
new file mode 100644
index 0000000..1137b48
--- /dev/null
+++ b/base/files/file_posix_hooks_internal.h
@@ -0,0 +1,31 @@
+// Copyright 2014 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.
+
+#ifndef BASE_FILES_FILE_POSIX_HOOKS_INTERNAL_H_
+#define BASE_FILES_FILE_POSIX_HOOKS_INTERNAL_H_
+
+#include "base/base_export.h"
+
+namespace base {
+
+// Define empty hooks for blacklisting file descriptors used in base::File.
+// These functions should be declared 'weak', i.e. the functions declared in
+// a default way would have precedence over the weak ones at link time. This
+// works for both static and dynamic linking.
+// TODO(pasko): Remove these hooks when crbug.com/424562 is fixed.
+//
+// With compilers other than GCC/Clang define strong no-op symbols for
+// simplicity.
+#if defined(COMPILER_GCC)
+#define ATTRIBUTE_WEAK __attribute__ ((weak))
+#else
+#define ATTRIBUTE_WEAK
+#endif
+BASE_EXPORT void ProtectFileDescriptor(int fd) ATTRIBUTE_WEAK;
+BASE_EXPORT void UnprotectFileDescriptor(int fd) ATTRIBUTE_WEAK;
+#undef ATTRIBUTE_WEAK
+
+} // namespace base
+
+#endif // BASE_FILES_FILE_POSIX_HOOKS_INTERNAL_H_
diff --git a/base/files/protect_file_posix.cc b/base/files/protect_file_posix.cc
new file mode 100644
index 0000000..e4753c4
--- /dev/null
+++ b/base/files/protect_file_posix.cc
@@ -0,0 +1,106 @@
+// Copyright 2014 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.
+
+#include "base/containers/hash_tables.h"
+#include "base/files/file.h"
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+#include "base/synchronization/lock.h"
+
+// These hooks provided for base::File perform additional sanity checks when
+// files are closed. These extra checks are hard to understand and maintain,
+// hence they are temporary. TODO(pasko): Remove these extra checks as soon as
+// crbug.com/424562 is fixed.
+//
+// Background:
+// 1. The browser process crashes if a call to close() provided by the C
+// library (i.e. close(3)) fails. This is done for security purposes. See
+// base/files/scoped_file.cc. When a crash like this happens, there is not
+// enough context in the minidump to triage the problem.
+// 2. base::File provides a good abstraction to prevent closing incorrect
+// file descriptors or double-closing. Closing non-owned file descriptors
+// would more likely happen from outside base::File and base::ScopedFD.
+//
+// These hooks intercept base::File operations to 'protect' file handles /
+// descriptors from accidental close(3) by other portions of the code being
+// linked into the browser. Also, this file provides an interceptor for the
+// close(3) itself, and requires to be linked with cooperation of
+// --Wl,--wrap=close (i.e. linker wrapping).
+//
+// Wrapping close(3) on all libraries can lead to confusion, particularly for
+// the libraries that do not use ::base (I am also looking at you,
+// crazy_linker). Instead two hooks are added to base::File, which are
+// implemented as no-op by default. This file should be linked into the Chrome
+// native binary(-ies) for a whitelist of targets where "file descriptor
+// protection" is useful.
+
+// With compilers other than GCC/Clang the wrapper is trivial. This is to avoid
+// overexercising mechanisms for overriding weak symbols.
+#if !defined(COMPILER_GCC)
+extern "C" {
+
+int __real_close(int fd);
+
+BASE_EXPORT int __wrap_close(int fd) {
+ return __real_close(fd);
+}
+
+} // extern "C"
+
+#else // defined(COMPILER_GCC)
+
+namespace {
+
+// Protects the |g_protected_fd_set|.
+base::LazyInstance<base::Lock>::Leaky g_lock = LAZY_INSTANCE_INITIALIZER;
+
+// Holds the set of all 'protected' file descriptors.
+base::LazyInstance<base::hash_set<int> >::Leaky g_protected_fd_set =
+ LAZY_INSTANCE_INITIALIZER;
+
+bool IsFileDescriptorProtected(int fd) {
+ base::AutoLock lock(*g_lock.Pointer());
+ return g_protected_fd_set.Get().count(fd) != 0;
+}
+
+} // namespace
+
+namespace base {
+
+BASE_EXPORT void ProtectFileDescriptor(int fd) {
+ base::AutoLock lock(g_lock.Get());
+ CHECK(!g_protected_fd_set.Get().count(fd)) << "fd: " << fd;
+ g_protected_fd_set.Get().insert(fd);
+}
+
+BASE_EXPORT void UnprotectFileDescriptor(int fd) {
+ base::AutoLock lock(*g_lock.Pointer());
+ CHECK(g_protected_fd_set.Get().erase(fd)) << "fd: " << fd;
+}
+
+} // namespace base
+
+extern "C" {
+
+int __real_close(int fd);
+
+BASE_EXPORT int __wrap_close(int fd) {
+ // The crash happens here if a protected file descriptor was attempted to be
+ // closed without first being unprotected. Unprotection happens only in
+ // base::File. In other words this is an "early crash" as compared to the one
+ // happening in scoped_file.cc.
+ //
+ // Getting an earlier crash provides a more useful stack trace (minidump)
+ // allowing to debug deeper into the thread that freed the wrong resource.
+ CHECK(!IsFileDescriptorProtected(fd)) << "fd: " << fd;
+
+ // Crash by the same reason as in scoped_file.cc.
+ PCHECK(0 == IGNORE_EINTR(__real_close(fd)));
+ return 0;
+}
+
+} // extern "C"
+
+#endif // defined(COMPILER_GCC)
diff --git a/base/files/protect_file_posix.gypi b/base/files/protect_file_posix.gypi
new file mode 100644
index 0000000..017fd87
--- /dev/null
+++ b/base/files/protect_file_posix.gypi
@@ -0,0 +1,31 @@
+# Copyright 2014 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.
+
+# Provides sanity-checks and early crashes on some improper use of posix file
+# descriptors. See protect_file_posix.cc for details.
+#
+# Usage:
+# {
+# 'target_name': 'libsomething',
+# 'type': 'shared_library', // Do *not* use it for static libraries.
+# 'includes': [
+# 'base/files/protect_file_posix.gypi',
+# ],
+# ...
+# }
+{
+ 'conditions': [
+ # In the component build the interceptors have to be declared with
+ # non-hidden visibility, which is not desirable for the release build.
+ # Disable the extra checks for the component build for simplicity.
+ ['component != "shared_library"', {
+ 'ldflags': [
+ '-Wl,--wrap=close',
+ ],
+ 'dependencies': [
+ '<(DEPTH)/base/base.gyp:protect_file_posix',
+ ],
+ }],
+ ],
+}
diff --git a/base/process/process.h b/base/process/process.h
index 7019474..50ccf8d 100644
--- a/base/process/process.h
+++ b/base/process/process.h
@@ -48,6 +48,12 @@
// Returns an object for the current process.
static Process Current();
+ // Creates an object from a |handle| owned by someone else.
+ // Don't use this for new code. It is only intended to ease the migration to
+ // a strict ownership model.
+ // TODO(rvargas) crbug.com/417532: Remove this code.
+ static Process DeprecatedGetProcessFromHandle(ProcessHandle handle);
+
// Returns true if processes can be backgrounded.
static bool CanBackgroundProcesses();
diff --git a/base/process/process_posix.cc b/base/process/process_posix.cc
index ea8fd8c..270438e 100644
--- a/base/process/process_posix.cc
+++ b/base/process/process_posix.cc
@@ -37,6 +37,12 @@
return process.Pass();
}
+// static
+Process Process::DeprecatedGetProcessFromHandle(ProcessHandle handle) {
+ DCHECK_NE(handle, GetCurrentProcessHandle());
+ return Process(handle);
+}
+
#if !defined(OS_LINUX)
// static
bool Process::CanBackgroundProcesses() {
diff --git a/base/process/process_unittest.cc b/base/process/process_unittest.cc
index 66d6e63..a5ba834 100644
--- a/base/process/process_unittest.cc
+++ b/base/process/process_unittest.cc
@@ -92,6 +92,21 @@
ASSERT_TRUE(process2.IsValid());
}
+TEST_F(ProcessTest, DeprecatedGetProcessFromHandle) {
+ Process process1(SpawnChild("SimpleChildProcess"));
+ ASSERT_TRUE(process1.IsValid());
+
+ Process process2 = Process::DeprecatedGetProcessFromHandle(process1.Handle());
+ ASSERT_TRUE(process1.IsValid());
+ ASSERT_TRUE(process2.IsValid());
+ EXPECT_EQ(process1.pid(), process2.pid());
+ EXPECT_FALSE(process1.is_current());
+ EXPECT_FALSE(process2.is_current());
+
+ process1.Close();
+ ASSERT_TRUE(process2.IsValid());
+}
+
MULTIPROCESS_TEST_MAIN(SleepyChildProcess) {
PlatformThread::Sleep(TestTimeouts::action_max_timeout());
return 0;
diff --git a/base/process/process_win.cc b/base/process/process_win.cc
index 05041b2..3e0d79f 100644
--- a/base/process/process_win.cc
+++ b/base/process/process_win.cc
@@ -39,6 +39,18 @@
}
// static
+Process Process::DeprecatedGetProcessFromHandle(ProcessHandle handle) {
+ DCHECK_NE(handle, ::GetCurrentProcess());
+ ProcessHandle out_handle;
+ if (!::DuplicateHandle(GetCurrentProcess(), handle,
+ GetCurrentProcess(), &out_handle,
+ 0, FALSE, DUPLICATE_SAME_ACCESS)) {
+ return Process();
+ }
+ return Process(out_handle);
+}
+
+// static
bool Process::CanBackgroundProcesses() {
return true;
}
diff --git a/build/all.gyp b/build/all.gyp
index a11ee7a..c3443f9 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -56,7 +56,6 @@
'../mojo/public/mojo_public.gyp:mojo_system',
'../google_apis/google_apis.gyp:google_apis_unittests',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/base/ui_base_tests.gyp:ui_unittests',
'../ui/ios/ui_ios_tests.gyp:ui_ios_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
],
@@ -308,7 +307,6 @@
'../sql/sql.gyp:sql_unittests',
'../sync/sync.gyp:sync_unit_tests',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/base/ui_base_tests.gyp:ui_unittests',
'../ui/display/display.gyp:display_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
'../url/url.gyp:url_unittests',
@@ -825,7 +823,6 @@
'../tools/android/android_tools.gyp:memconsumer',
'../tools/android/findbugs_plugin/findbugs_plugin.gyp:findbugs_plugin_test',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/base/ui_base_tests.gyp:ui_unittests',
'../ui/events/events.gyp:events_unittests',
# Unit test bundles packaged as an apk.
'../android_webview/android_webview.gyp:android_webview_test_apk',
@@ -852,7 +849,6 @@
'../sync/sync.gyp:sync_unit_tests_apk',
'../tools/android/heap_profiler/heap_profiler.gyp:heap_profiler_unittests_apk',
'../ui/base/ui_base_tests.gyp:ui_base_unittests_apk',
- '../ui/base/ui_base_tests.gyp:ui_unittests_apk',
'../ui/events/events.gyp:events_unittests_apk',
'../ui/gfx/gfx_tests.gyp:gfx_unittests_apk',
],
@@ -860,7 +856,6 @@
['enable_webrtc==1 and "<(libpeer_target_type)"=="static_library"', {
'dependencies': [
'../components/devtools_bridge.gyp:devtools_bridge_tests_apk',
- '../components/devtools_bridge.gyp:devtools_bridge_tests2_apk',
],
}],
],
@@ -876,7 +871,6 @@
'../tools/android/android_tools.gyp:memconsumer',
# Unit test bundles packaged as an apk.
'../components/devtools_bridge.gyp:devtools_bridge_tests_apk',
- '../components/devtools_bridge.gyp:devtools_bridge_tests2_apk',
'../content/content_shell_and_tests.gyp:content_browsertests_apk',
],
}, # target_name: android_builder_chromium_webrtc
@@ -930,7 +924,6 @@
'../tools/perf/clear_system_cache/clear_system_cache.gyp:*',
'../tools/telemetry/telemetry.gyp:*',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/base/ui_base_tests.gyp:ui_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
'../url/url.gyp:url_unittests',
],
@@ -968,7 +961,6 @@
'../tools/perf/clear_system_cache/clear_system_cache.gyp:*',
'../tools/telemetry/telemetry.gyp:*',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/base/ui_base_tests.gyp:ui_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
'../url/url.gyp:url_unittests',
],
@@ -1017,7 +1009,6 @@
'../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests',
'../third_party/libphonenumber/libphonenumber.gyp:libphonenumber_unittests',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/base/ui_base_tests.gyp:ui_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
'../url/url.gyp:url_unittests',
],
@@ -1069,7 +1060,6 @@
'../tools/perf/clear_system_cache/clear_system_cache.gyp:*',
'../tools/telemetry/telemetry.gyp:*',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/base/ui_base_tests.gyp:ui_unittests',
'../ui/events/events.gyp:events_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
'../ui/views/views.gyp:views_unittests',
@@ -1215,7 +1205,6 @@
'../sync/sync.gyp:sync_unit_tests',
'../third_party/widevine/cdm/widevine_cdm.gyp:widevinecdmadapter',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/base/ui_base_tests.gyp:ui_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
'../ui/views/views.gyp:views_unittests',
'../url/url.gyp:url_unittests',
@@ -1258,7 +1247,6 @@
'../ui/app_list/app_list.gyp:*',
'../ui/aura/aura.gyp:*',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/base/ui_base_tests.gyp:ui_unittests',
'../ui/compositor/compositor.gyp:*',
'../ui/display/display.gyp:display_unittests',
'../ui/events/events.gyp:*',
diff --git a/build/android/findbugs_filter/findbugs_known_bugs.txt b/build/android/findbugs_filter/findbugs_known_bugs.txt
index 7be93ec..6ad2b3a 100644
--- a/build/android/findbugs_filter/findbugs_known_bugs.txt
+++ b/build/android/findbugs_filter/findbugs_known_bugs.txt
@@ -22,6 +22,4 @@
M M LI: Incorrect lazy initialization of static field org.chromium.chrome.browser.sync.ProfileSyncService.sSyncSetupManager in org.chromium.chrome.browser.sync.ProfileSyncService.get(Context) At ProfileSyncService.java
M V EI2: org.chromium.content_public.browser.LoadUrlParams.setPostData(byte[]) may expose internal representation by storing an externally mutable object into LoadUrlParams.mPostData At LoadUrlParams.java
M V EI: org.chromium.content_public.browser.LoadUrlParams.getPostData() may expose internal representation by returning LoadUrlParams.mPostData At LoadUrlParams.java
-M D NP: Read of unwritten public or protected field data in org.chromium.components.devtools_bridge.SessionDependencyFactory$DataChannelObserverAdapter.onMessage(DataChannel$Buffer) At SessionDependencyFactory.java
-M D NP: Read of unwritten public or protected field mandatory in org.chromium.components.devtools_bridge.SessionDependencyFactory.createPeerConnectionConstraints() At SessionDependencyFactory.java
M V EI2: org.chromium.net.ChromiumUrlRequest.setUploadData(String, byte[]) may expose internal representation by storing an externally mutable object into ChromiumUrlRequest.mUploadData At ChromiumUrlRequest.java
diff --git a/build/android/pylib/android_commands.py b/build/android/pylib/android_commands.py
index ea86e6d..6981afc 100644
--- a/build/android/pylib/android_commands.py
+++ b/build/android/pylib/android_commands.py
@@ -1927,7 +1927,8 @@
# to the device.
while True:
if t0 + timeout - time.time() < 0:
- raise pexpect.TIMEOUT('Unable to enable USB charging in time.')
+ raise pexpect.TIMEOUT('Unable to disable USB charging in time: %s' % (
+ self.GetBatteryInfo()))
self.RunShellCommand(disable_command)
if not self.IsDeviceCharging():
break
diff --git a/build/android/pylib/gtest/gtest_config.py b/build/android/pylib/gtest/gtest_config.py
index 3b51a42..e671e0a 100644
--- a/build/android/pylib/gtest/gtest_config.py
+++ b/build/android/pylib/gtest/gtest_config.py
@@ -32,7 +32,6 @@
'sql_unittests',
'sync_unit_tests',
'ui_base_unittests',
- 'ui_unittests',
'unit_tests',
'webkit_unit_tests',
]
diff --git a/build/android/pylib/gtest/setup.py b/build/android/pylib/gtest/setup.py
index 3206bda..e3df9c7 100644
--- a/build/android/pylib/gtest/setup.py
+++ b/build/android/pylib/gtest/setup.py
@@ -40,7 +40,6 @@
'net_unittests': 'net/net_unittests.isolate',
'sql_unittests': 'sql/sql_unittests.isolate',
'ui_base_unittests': 'ui/base/ui_base_tests.isolate',
- 'ui_unittests': 'ui/base/ui_base_tests.isolate',
'unit_tests': 'chrome/unit_tests.isolate',
'webkit_unit_tests':
'third_party/WebKit/Source/web/WebKitUnitTests.isolate',
diff --git a/build/android/pylib/instrumentation/test_jar.py b/build/android/pylib/instrumentation/test_jar.py
index a3d8849..7b97e59 100644
--- a/build/android/pylib/instrumentation/test_jar.py
+++ b/build/android/pylib/instrumentation/test_jar.py
@@ -140,7 +140,7 @@
key = filters[0]
value_list = filters[1].split(',')
for value in value_list:
- if key in annotations and value == annotations['key']:
+ if key in annotations and value == annotations[key]:
return True
elif annotation_filter in annotations:
return True
diff --git a/build/android/pylib/uiautomator/test_runner.py b/build/android/pylib/uiautomator/test_runner.py
index c7239b4..b47a236 100644
--- a/build/android/pylib/uiautomator/test_runner.py
+++ b/build/android/pylib/uiautomator/test_runner.py
@@ -64,7 +64,7 @@
self.device.ClearApplicationState(self._package)
if self.flags:
annotations = self.test_pkg.GetTestAnnotations(test)
- if ('FirstRunExperience' == annotations(test).get('Feature', None)):
+ if ('FirstRunExperience' == annotations.get('Feature', None)):
self.flags.RemoveFlags(['--disable-fre'])
else:
self.flags.AddFlags(['--disable-fre'])
diff --git a/build/common.gypi b/build/common.gypi
index 7fa5d83..0d7d385 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -787,7 +787,8 @@
'disable_ftp_support%': 1,
'enable_extensions%': 0,
'enable_google_now%': 0,
- 'cld_version%': 1,
+ 'cld_version%': 2,
+ 'cld2_table_size%': 0,
'enable_basic_printing%': 0,
'enable_print_preview%': 0,
'enable_session_service%': 0,
diff --git a/build/config/features.gni b/build/config/features.gni
index 575a89c..82247b9 100644
--- a/build/config/features.gni
+++ b/build/config/features.gni
@@ -47,7 +47,7 @@
# 0: Don't specify the version. This option is for the Finch testing.
# 1: Use only CLD1.
# 2: Use only CLD2.
-if (is_android || is_ios) {
+if (is_android) {
cld_version = 1
} else {
cld_version = 2
diff --git a/cc/animation/animation_curve.h b/cc/animation/animation_curve.h
index c03feb8..f4c697c 100644
--- a/cc/animation/animation_curve.h
+++ b/cc/animation/animation_curve.h
@@ -48,7 +48,7 @@
public:
~ColorAnimationCurve() override {}
- virtual SkColor GetValue(double t) const = 0;
+ virtual SkColor GetValue(base::TimeDelta t) const = 0;
// Partial Animation implementation.
CurveType Type() const override;
@@ -58,7 +58,7 @@
public:
~FloatAnimationCurve() override {}
- virtual float GetValue(double t) const = 0;
+ virtual float GetValue(base::TimeDelta t) const = 0;
// Partial Animation implementation.
CurveType Type() const override;
@@ -68,7 +68,7 @@
public:
~TransformAnimationCurve() override {}
- virtual gfx::Transform GetValue(double t) const = 0;
+ virtual gfx::Transform GetValue(base::TimeDelta t) const = 0;
// Sets |bounds| to be the bounding box for the region within which |box|
// will move during this animation. If this region cannot be computed,
@@ -98,7 +98,7 @@
public:
~FilterAnimationCurve() override {}
- virtual FilterOperations GetValue(double t) const = 0;
+ virtual FilterOperations GetValue(base::TimeDelta t) const = 0;
virtual bool HasFilterThatMovesPixels() const = 0;
// Partial Animation implementation.
diff --git a/cc/animation/keyframed_animation_curve.cc b/cc/animation/keyframed_animation_curve.cc
index a6dc8c5..9642329 100644
--- a/cc/animation/keyframed_animation_curve.cc
+++ b/cc/animation/keyframed_animation_curve.cc
@@ -5,6 +5,7 @@
#include <algorithm>
#include "cc/animation/keyframed_animation_curve.h"
+#include "cc/base/time_util.h"
#include "ui/gfx/animation/tween.h"
#include "ui/gfx/geometry/box_f.h"
@@ -30,16 +31,18 @@
}
template <typename KeyframeType>
-double TransformedAnimationTime(
+base::TimeDelta TransformedAnimationTime(
const ScopedPtrVector<KeyframeType>& keyframes,
const scoped_ptr<TimingFunction>& timing_function,
- double time) {
+ base::TimeDelta time) {
if (timing_function) {
- double start_time = keyframes.front()->Time();
- double duration = keyframes.back()->Time() - start_time;
- double progress = (time - start_time) / duration;
+ base::TimeDelta start_time = keyframes.front()->Time();
+ base::TimeDelta duration =
+ keyframes.back()->Time() - keyframes.front()->Time();
+ double progress = TimeUtil::Divide(time - start_time, duration);
- time = timing_function->GetValue(progress) * duration + start_time;
+ time = TimeUtil::Scale(duration, timing_function->GetValue(progress)) +
+ start_time;
}
return time;
@@ -47,7 +50,7 @@
template <typename KeyframeType>
size_t GetActiveKeyframe(const ScopedPtrVector<KeyframeType>& keyframes,
- double time) {
+ base::TimeDelta time) {
DCHECK_GE(keyframes.size(), 2ul);
size_t i = 0;
for (; i < keyframes.size() - 2; ++i) { // Last keyframe is never active.
@@ -61,10 +64,11 @@
template <typename KeyframeType>
double TransformedKeyframeProgress(
const ScopedPtrVector<KeyframeType>& keyframes,
- double time,
+ base::TimeDelta time,
size_t i) {
- double progress = (time - keyframes[i]->Time()) /
- (keyframes[i + 1]->Time() - keyframes[i]->Time());
+ double progress =
+ TimeUtil::Divide(time - keyframes[i]->Time(),
+ keyframes[i + 1]->Time() - keyframes[i]->Time());
if (keyframes[i]->timing_function()) {
progress = keyframes[i]->timing_function()->GetValue(progress);
@@ -75,29 +79,30 @@
} // namespace
-Keyframe::Keyframe(double time, scoped_ptr<TimingFunction> timing_function)
- : time_(time),
- timing_function_(timing_function.Pass()) {}
+Keyframe::Keyframe(base::TimeDelta time,
+ scoped_ptr<TimingFunction> timing_function)
+ : time_(time), timing_function_(timing_function.Pass()) {
+}
Keyframe::~Keyframe() {}
-double Keyframe::Time() const {
+base::TimeDelta Keyframe::Time() const {
return time_;
}
scoped_ptr<ColorKeyframe> ColorKeyframe::Create(
- double time,
+ base::TimeDelta time,
SkColor value,
scoped_ptr<TimingFunction> timing_function) {
return make_scoped_ptr(
new ColorKeyframe(time, value, timing_function.Pass()));
}
-ColorKeyframe::ColorKeyframe(double time,
+ColorKeyframe::ColorKeyframe(base::TimeDelta time,
SkColor value,
scoped_ptr<TimingFunction> timing_function)
- : Keyframe(time, timing_function.Pass()),
- value_(value) {}
+ : Keyframe(time, timing_function.Pass()), value_(value) {
+}
ColorKeyframe::~ColorKeyframe() {}
@@ -111,18 +116,18 @@
}
scoped_ptr<FloatKeyframe> FloatKeyframe::Create(
- double time,
+ base::TimeDelta time,
float value,
scoped_ptr<TimingFunction> timing_function) {
return make_scoped_ptr(
new FloatKeyframe(time, value, timing_function.Pass()));
}
-FloatKeyframe::FloatKeyframe(double time,
+FloatKeyframe::FloatKeyframe(base::TimeDelta time,
float value,
scoped_ptr<TimingFunction> timing_function)
- : Keyframe(time, timing_function.Pass()),
- value_(value) {}
+ : Keyframe(time, timing_function.Pass()), value_(value) {
+}
FloatKeyframe::~FloatKeyframe() {}
@@ -138,18 +143,18 @@
}
scoped_ptr<TransformKeyframe> TransformKeyframe::Create(
- double time,
+ base::TimeDelta time,
const TransformOperations& value,
scoped_ptr<TimingFunction> timing_function) {
return make_scoped_ptr(
new TransformKeyframe(time, value, timing_function.Pass()));
}
-TransformKeyframe::TransformKeyframe(double time,
+TransformKeyframe::TransformKeyframe(base::TimeDelta time,
const TransformOperations& value,
scoped_ptr<TimingFunction> timing_function)
- : Keyframe(time, timing_function.Pass()),
- value_(value) {}
+ : Keyframe(time, timing_function.Pass()), value_(value) {
+}
TransformKeyframe::~TransformKeyframe() {}
@@ -165,18 +170,18 @@
}
scoped_ptr<FilterKeyframe> FilterKeyframe::Create(
- double time,
+ base::TimeDelta time,
const FilterOperations& value,
scoped_ptr<TimingFunction> timing_function) {
return make_scoped_ptr(
new FilterKeyframe(time, value, timing_function.Pass()));
}
-FilterKeyframe::FilterKeyframe(double time,
+FilterKeyframe::FilterKeyframe(base::TimeDelta time,
const FilterOperations& value,
scoped_ptr<TimingFunction> timing_function)
- : Keyframe(time, timing_function.Pass()),
- value_(value) {}
+ : Keyframe(time, timing_function.Pass()), value_(value) {
+}
FilterKeyframe::~FilterKeyframe() {}
@@ -206,8 +211,7 @@
}
base::TimeDelta KeyframedColorAnimationCurve::Duration() const {
- return base::TimeDelta::FromSecondsD(keyframes_.back()->Time() -
- keyframes_.front()->Time());
+ return keyframes_.back()->Time() - keyframes_.front()->Time();
}
scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const {
@@ -222,7 +226,7 @@
return to_return.Pass();
}
-SkColor KeyframedColorAnimationCurve::GetValue(double t) const {
+SkColor KeyframedColorAnimationCurve::GetValue(base::TimeDelta t) const {
if (t <= keyframes_.front()->Time())
return keyframes_.front()->Value();
@@ -254,8 +258,7 @@
}
base::TimeDelta KeyframedFloatAnimationCurve::Duration() const {
- return base::TimeDelta::FromSecondsD(keyframes_.back()->Time() -
- keyframes_.front()->Time());
+ return keyframes_.back()->Time() - keyframes_.front()->Time();
}
scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const {
@@ -270,7 +273,7 @@
return to_return.Pass();
}
-float KeyframedFloatAnimationCurve::GetValue(double t) const {
+float KeyframedFloatAnimationCurve::GetValue(base::TimeDelta t) const {
if (t <= keyframes_.front()->Time())
return keyframes_.front()->Value();
@@ -300,8 +303,7 @@
}
base::TimeDelta KeyframedTransformAnimationCurve::Duration() const {
- return base::TimeDelta::FromSecondsD(keyframes_.back()->Time() -
- keyframes_.front()->Time());
+ return keyframes_.back()->Time() - keyframes_.front()->Time();
}
scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const {
@@ -316,7 +318,8 @@
return to_return.Pass();
}
-gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const {
+gfx::Transform KeyframedTransformAnimationCurve::GetValue(
+ base::TimeDelta t) const {
if (t <= keyframes_.front()->Time())
return keyframes_.front()->Value().Apply();
@@ -412,8 +415,7 @@
}
base::TimeDelta KeyframedFilterAnimationCurve::Duration() const {
- return base::TimeDelta::FromSecondsD(keyframes_.back()->Time() -
- keyframes_.front()->Time());
+ return keyframes_.back()->Time() - keyframes_.front()->Time();
}
scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const {
@@ -428,7 +430,8 @@
return to_return.Pass();
}
-FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const {
+FilterOperations KeyframedFilterAnimationCurve::GetValue(
+ base::TimeDelta t) const {
if (t <= keyframes_.front()->Time())
return keyframes_.front()->Value();
diff --git a/cc/animation/keyframed_animation_curve.h b/cc/animation/keyframed_animation_curve.h
index ff746fe..e68f4f8 100644
--- a/cc/animation/keyframed_animation_curve.h
+++ b/cc/animation/keyframed_animation_curve.h
@@ -16,17 +16,17 @@
class CC_EXPORT Keyframe {
public:
- double Time() const;
+ base::TimeDelta Time() const;
const TimingFunction* timing_function() const {
return timing_function_.get();
}
protected:
- Keyframe(double time, scoped_ptr<TimingFunction> timing_function);
+ Keyframe(base::TimeDelta time, scoped_ptr<TimingFunction> timing_function);
virtual ~Keyframe();
private:
- double time_;
+ base::TimeDelta time_;
scoped_ptr<TimingFunction> timing_function_;
DISALLOW_COPY_AND_ASSIGN(Keyframe);
@@ -35,7 +35,7 @@
class CC_EXPORT ColorKeyframe : public Keyframe {
public:
static scoped_ptr<ColorKeyframe> Create(
- double time,
+ base::TimeDelta time,
SkColor value,
scoped_ptr<TimingFunction> timing_function);
~ColorKeyframe() override;
@@ -45,7 +45,7 @@
scoped_ptr<ColorKeyframe> Clone() const;
private:
- ColorKeyframe(double time,
+ ColorKeyframe(base::TimeDelta time,
SkColor value,
scoped_ptr<TimingFunction> timing_function);
@@ -55,7 +55,7 @@
class CC_EXPORT FloatKeyframe : public Keyframe {
public:
static scoped_ptr<FloatKeyframe> Create(
- double time,
+ base::TimeDelta time,
float value,
scoped_ptr<TimingFunction> timing_function);
~FloatKeyframe() override;
@@ -65,7 +65,7 @@
scoped_ptr<FloatKeyframe> Clone() const;
private:
- FloatKeyframe(double time,
+ FloatKeyframe(base::TimeDelta time,
float value,
scoped_ptr<TimingFunction> timing_function);
@@ -75,7 +75,7 @@
class CC_EXPORT TransformKeyframe : public Keyframe {
public:
static scoped_ptr<TransformKeyframe> Create(
- double time,
+ base::TimeDelta time,
const TransformOperations& value,
scoped_ptr<TimingFunction> timing_function);
~TransformKeyframe() override;
@@ -85,10 +85,9 @@
scoped_ptr<TransformKeyframe> Clone() const;
private:
- TransformKeyframe(
- double time,
- const TransformOperations& value,
- scoped_ptr<TimingFunction> timing_function);
+ TransformKeyframe(base::TimeDelta time,
+ const TransformOperations& value,
+ scoped_ptr<TimingFunction> timing_function);
TransformOperations value_;
};
@@ -96,7 +95,7 @@
class CC_EXPORT FilterKeyframe : public Keyframe {
public:
static scoped_ptr<FilterKeyframe> Create(
- double time,
+ base::TimeDelta time,
const FilterOperations& value,
scoped_ptr<TimingFunction> timing_function);
~FilterKeyframe() override;
@@ -106,10 +105,9 @@
scoped_ptr<FilterKeyframe> Clone() const;
private:
- FilterKeyframe(
- double time,
- const FilterOperations& value,
- scoped_ptr<TimingFunction> timing_function);
+ FilterKeyframe(base::TimeDelta time,
+ const FilterOperations& value,
+ scoped_ptr<TimingFunction> timing_function);
FilterOperations value_;
};
@@ -131,7 +129,7 @@
scoped_ptr<AnimationCurve> Clone() const override;
// BackgrounColorAnimationCurve implementation
- SkColor GetValue(double t) const override;
+ SkColor GetValue(base::TimeDelta t) const override;
private:
KeyframedColorAnimationCurve();
@@ -161,7 +159,7 @@
scoped_ptr<AnimationCurve> Clone() const override;
// FloatAnimationCurve implementation
- float GetValue(double t) const override;
+ float GetValue(base::TimeDelta t) const override;
private:
KeyframedFloatAnimationCurve();
@@ -192,7 +190,7 @@
scoped_ptr<AnimationCurve> Clone() const override;
// TransformAnimationCurve implementation
- gfx::Transform GetValue(double t) const override;
+ gfx::Transform GetValue(base::TimeDelta t) const override;
bool AnimatedBoundsForBox(const gfx::BoxF& box,
gfx::BoxF* bounds) const override;
bool AffectsScale() const override;
@@ -229,7 +227,7 @@
scoped_ptr<AnimationCurve> Clone() const override;
// FilterAnimationCurve implementation
- FilterOperations GetValue(double t) const override;
+ FilterOperations GetValue(base::TimeDelta t) const override;
bool HasFilterThatMovesPixels() const override;
private:
diff --git a/cc/animation/keyframed_animation_curve_unittest.cc b/cc/animation/keyframed_animation_curve_unittest.cc
index 71fd521..314ce9d 100644
--- a/cc/animation/keyframed_animation_curve_unittest.cc
+++ b/cc/animation/keyframed_animation_curve_unittest.cc
@@ -29,13 +29,15 @@
SkColor color = SkColorSetARGB(255, 255, 255, 255);
scoped_ptr<KeyframedColorAnimationCurve> curve(
KeyframedColorAnimationCurve::Create());
- curve->AddKeyframe(ColorKeyframe::Create(0.0, color, nullptr));
+ curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta(), color, nullptr));
- EXPECT_SKCOLOR_EQ(color, curve->GetValue(-1.f));
- EXPECT_SKCOLOR_EQ(color, curve->GetValue(0.f));
- EXPECT_SKCOLOR_EQ(color, curve->GetValue(0.5f));
- EXPECT_SKCOLOR_EQ(color, curve->GetValue(1.f));
- EXPECT_SKCOLOR_EQ(color, curve->GetValue(2.f));
+ EXPECT_SKCOLOR_EQ(color,
+ curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ EXPECT_SKCOLOR_EQ(color, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ EXPECT_SKCOLOR_EQ(color,
+ curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ EXPECT_SKCOLOR_EQ(color, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ EXPECT_SKCOLOR_EQ(color, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
}
// Tests that a color animation with two keyframes works as expected.
@@ -45,14 +47,21 @@
SkColor color_midpoint = gfx::Tween::ColorValueBetween(0.5, color_a, color_b);
scoped_ptr<KeyframedColorAnimationCurve> curve(
KeyframedColorAnimationCurve::Create());
- curve->AddKeyframe(ColorKeyframe::Create(0.0, color_a, nullptr));
- curve->AddKeyframe(ColorKeyframe::Create(1.0, color_b, nullptr));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr));
+ curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
+ color_b, nullptr));
- EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(-1.f));
- EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(0.f));
- EXPECT_SKCOLOR_EQ(color_midpoint, curve->GetValue(0.5f));
- EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(1.f));
- EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(2.f));
+ EXPECT_SKCOLOR_EQ(color_a,
+ curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ EXPECT_SKCOLOR_EQ(color_a,
+ curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ EXPECT_SKCOLOR_EQ(color_midpoint,
+ curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ EXPECT_SKCOLOR_EQ(color_b,
+ curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ EXPECT_SKCOLOR_EQ(color_b,
+ curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
}
// Tests that a color animation with three keyframes works as expected.
@@ -66,17 +75,27 @@
gfx::Tween::ColorValueBetween(0.5, color_b, color_c);
scoped_ptr<KeyframedColorAnimationCurve> curve(
KeyframedColorAnimationCurve::Create());
- curve->AddKeyframe(ColorKeyframe::Create(0.0, color_a, nullptr));
- curve->AddKeyframe(ColorKeyframe::Create(1.0, color_b, nullptr));
- curve->AddKeyframe(ColorKeyframe::Create(2.0, color_c, nullptr));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr));
+ curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
+ color_b, nullptr));
+ curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(2.0),
+ color_c, nullptr));
- EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(-1.f));
- EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(0.f));
- EXPECT_SKCOLOR_EQ(color_midpoint1, curve->GetValue(0.5f));
- EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(1.f));
- EXPECT_SKCOLOR_EQ(color_midpoint2, curve->GetValue(1.5f));
- EXPECT_SKCOLOR_EQ(color_c, curve->GetValue(2.f));
- EXPECT_SKCOLOR_EQ(color_c, curve->GetValue(3.f));
+ EXPECT_SKCOLOR_EQ(color_a,
+ curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ EXPECT_SKCOLOR_EQ(color_a,
+ curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ EXPECT_SKCOLOR_EQ(color_midpoint1,
+ curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ EXPECT_SKCOLOR_EQ(color_b,
+ curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ EXPECT_SKCOLOR_EQ(color_midpoint2,
+ curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
+ EXPECT_SKCOLOR_EQ(color_c,
+ curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
+ EXPECT_SKCOLOR_EQ(color_c,
+ curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
}
// Tests that a colro animation with multiple keys at a given time works sanely.
@@ -86,87 +105,103 @@
scoped_ptr<KeyframedColorAnimationCurve> curve(
KeyframedColorAnimationCurve::Create());
- curve->AddKeyframe(ColorKeyframe::Create(0.0, color_a, nullptr));
- curve->AddKeyframe(ColorKeyframe::Create(1.0, color_a, nullptr));
- curve->AddKeyframe(ColorKeyframe::Create(1.0, color_b, nullptr));
- curve->AddKeyframe(ColorKeyframe::Create(2.0, color_b, nullptr));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr));
+ curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
+ color_a, nullptr));
+ curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
+ color_b, nullptr));
+ curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(2.0),
+ color_b, nullptr));
- EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(-1.f));
- EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(0.f));
- EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(0.5f));
+ EXPECT_SKCOLOR_EQ(color_a,
+ curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ EXPECT_SKCOLOR_EQ(color_a,
+ curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ EXPECT_SKCOLOR_EQ(color_a,
+ curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
- SkColor value = curve->GetValue(1.0f);
+ SkColor value = curve->GetValue(base::TimeDelta::FromSecondsD(1.0f));
EXPECT_EQ(255u, SkColorGetA(value));
int red_value = SkColorGetR(value);
EXPECT_LE(64, red_value);
EXPECT_GE(192, red_value);
- EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(1.5f));
- EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(2.f));
- EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(3.f));
+ EXPECT_SKCOLOR_EQ(color_b,
+ curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
+ EXPECT_SKCOLOR_EQ(color_b,
+ curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
+ EXPECT_SKCOLOR_EQ(color_b,
+ curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
}
// Tests that a float animation with one keyframe works as expected.
TEST(KeyframedAnimationCurveTest, OneFloatKeyframe) {
scoped_ptr<KeyframedFloatAnimationCurve> curve(
KeyframedFloatAnimationCurve::Create());
- curve->AddKeyframe(FloatKeyframe::Create(0.0, 2.f, nullptr));
- EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f));
- EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f));
- EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.5f));
- EXPECT_FLOAT_EQ(2.f, curve->GetValue(1.f));
- EXPECT_FLOAT_EQ(2.f, curve->GetValue(2.f));
+ curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
}
// Tests that a float animation with two keyframes works as expected.
TEST(KeyframedAnimationCurveTest, TwoFloatKeyframe) {
scoped_ptr<KeyframedFloatAnimationCurve> curve(
KeyframedFloatAnimationCurve::Create());
- curve->AddKeyframe(FloatKeyframe::Create(0.0, 2.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(1.0, 4.f, nullptr));
- EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f));
- EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f));
- EXPECT_FLOAT_EQ(3.f, curve->GetValue(0.5f));
- EXPECT_FLOAT_EQ(4.f, curve->GetValue(1.f));
- EXPECT_FLOAT_EQ(4.f, curve->GetValue(2.f));
+ curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 4.f, nullptr));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
}
// Tests that a float animation with three keyframes works as expected.
TEST(KeyframedAnimationCurveTest, ThreeFloatKeyframe) {
scoped_ptr<KeyframedFloatAnimationCurve> curve(
KeyframedFloatAnimationCurve::Create());
- curve->AddKeyframe(FloatKeyframe::Create(0.0, 2.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(1.0, 4.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(2.0, 8.f, nullptr));
- EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f));
- EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f));
- EXPECT_FLOAT_EQ(3.f, curve->GetValue(0.5f));
- EXPECT_FLOAT_EQ(4.f, curve->GetValue(1.f));
- EXPECT_FLOAT_EQ(6.f, curve->GetValue(1.5f));
- EXPECT_FLOAT_EQ(8.f, curve->GetValue(2.f));
- EXPECT_FLOAT_EQ(8.f, curve->GetValue(3.f));
+ curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 4.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), 8.f, nullptr));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
+ EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
+ EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
}
// Tests that a float animation with multiple keys at a given time works sanely.
TEST(KeyframedAnimationCurveTest, RepeatedFloatKeyTimes) {
scoped_ptr<KeyframedFloatAnimationCurve> curve(
KeyframedFloatAnimationCurve::Create());
- curve->AddKeyframe(FloatKeyframe::Create(0.0, 4.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(1.0, 4.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(1.0, 6.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(2.0, 6.f, nullptr));
+ curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 4.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 4.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 6.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), 6.f, nullptr));
- EXPECT_FLOAT_EQ(4.f, curve->GetValue(-1.f));
- EXPECT_FLOAT_EQ(4.f, curve->GetValue(0.f));
- EXPECT_FLOAT_EQ(4.f, curve->GetValue(0.5f));
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
// There is a discontinuity at 1. Any value between 4 and 6 is valid.
- float value = curve->GetValue(1.f);
+ float value = curve->GetValue(base::TimeDelta::FromSecondsD(1.f));
EXPECT_TRUE(value >= 4 && value <= 6);
- EXPECT_FLOAT_EQ(6.f, curve->GetValue(1.5f));
- EXPECT_FLOAT_EQ(6.f, curve->GetValue(2.f));
- EXPECT_FLOAT_EQ(6.f, curve->GetValue(3.f));
+ EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
+ EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
+ EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
}
// Tests that a transform animation with one keyframe works as expected.
@@ -175,13 +210,14 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations;
operations.AppendTranslate(2.f, 0.f, 0.f);
- curve->AddKeyframe(TransformKeyframe::Create(0.f, operations, nullptr));
+ curve->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations, nullptr));
- ExpectTranslateX(2.f, curve->GetValue(-1.f));
- ExpectTranslateX(2.f, curve->GetValue(0.f));
- ExpectTranslateX(2.f, curve->GetValue(0.5f));
- ExpectTranslateX(2.f, curve->GetValue(1.f));
- ExpectTranslateX(2.f, curve->GetValue(2.f));
+ ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
}
// Tests that a transform animation with two keyframes works as expected.
@@ -193,13 +229,15 @@
TransformOperations operations2;
operations2.AppendTranslate(4.f, 0.f, 0.f);
- curve->AddKeyframe(TransformKeyframe::Create(0.f, operations1, nullptr));
- curve->AddKeyframe(TransformKeyframe::Create(1.f, operations2, nullptr));
- ExpectTranslateX(2.f, curve->GetValue(-1.f));
- ExpectTranslateX(2.f, curve->GetValue(0.f));
- ExpectTranslateX(3.f, curve->GetValue(0.5f));
- ExpectTranslateX(4.f, curve->GetValue(1.f));
- ExpectTranslateX(4.f, curve->GetValue(2.f));
+ curve->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
+ ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ ExpectTranslateX(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
}
// Tests that a transform animation with three keyframes works as expected.
@@ -212,16 +250,19 @@
operations2.AppendTranslate(4.f, 0.f, 0.f);
TransformOperations operations3;
operations3.AppendTranslate(8.f, 0.f, 0.f);
- curve->AddKeyframe(TransformKeyframe::Create(0.f, operations1, nullptr));
- curve->AddKeyframe(TransformKeyframe::Create(1.f, operations2, nullptr));
- curve->AddKeyframe(TransformKeyframe::Create(2.f, operations3, nullptr));
- ExpectTranslateX(2.f, curve->GetValue(-1.f));
- ExpectTranslateX(2.f, curve->GetValue(0.f));
- ExpectTranslateX(3.f, curve->GetValue(0.5f));
- ExpectTranslateX(4.f, curve->GetValue(1.f));
- ExpectTranslateX(6.f, curve->GetValue(1.5f));
- ExpectTranslateX(8.f, curve->GetValue(2.f));
- ExpectTranslateX(8.f, curve->GetValue(3.f));
+ curve->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(2.0), operations3, nullptr));
+ ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ ExpectTranslateX(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
+ ExpectTranslateX(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
+ ExpectTranslateX(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
}
// Tests that a transform animation with multiple keys at a given time works
@@ -238,23 +279,27 @@
operations3.AppendTranslate(6.f, 0.f, 0.f);
TransformOperations operations4;
operations4.AppendTranslate(6.f, 0.f, 0.f);
- curve->AddKeyframe(TransformKeyframe::Create(0.f, operations1, nullptr));
- curve->AddKeyframe(TransformKeyframe::Create(1.f, operations2, nullptr));
- curve->AddKeyframe(TransformKeyframe::Create(1.f, operations3, nullptr));
- curve->AddKeyframe(TransformKeyframe::Create(2.f, operations4, nullptr));
+ curve->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations3, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(2.0), operations4, nullptr));
- ExpectTranslateX(4.f, curve->GetValue(-1.f));
- ExpectTranslateX(4.f, curve->GetValue(0.f));
- ExpectTranslateX(4.f, curve->GetValue(0.5f));
+ ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
// There is a discontinuity at 1. Any value between 4 and 6 is valid.
- gfx::Transform value = curve->GetValue(1.f);
+ gfx::Transform value = curve->GetValue(base::TimeDelta::FromSecondsD(1.f));
EXPECT_GE(value.matrix().get(0, 3), 4.f);
EXPECT_LE(value.matrix().get(0, 3), 6.f);
- ExpectTranslateX(6.f, curve->GetValue(1.5f));
- ExpectTranslateX(6.f, curve->GetValue(2.f));
- ExpectTranslateX(6.f, curve->GetValue(3.f));
+ ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
+ ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
+ ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
}
// Tests that a filter animation with one keyframe works as expected.
@@ -263,13 +308,14 @@
KeyframedFilterAnimationCurve::Create());
FilterOperations operations;
operations.Append(FilterOperation::CreateBrightnessFilter(2.f));
- curve->AddKeyframe(FilterKeyframe::Create(0.f, operations, nullptr));
+ curve->AddKeyframe(
+ FilterKeyframe::Create(base::TimeDelta(), operations, nullptr));
- ExpectBrightness(2.f, curve->GetValue(-1.f));
- ExpectBrightness(2.f, curve->GetValue(0.f));
- ExpectBrightness(2.f, curve->GetValue(0.5f));
- ExpectBrightness(2.f, curve->GetValue(1.f));
- ExpectBrightness(2.f, curve->GetValue(2.f));
+ ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
}
// Tests that a filter animation with two keyframes works as expected.
@@ -281,13 +327,15 @@
FilterOperations operations2;
operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
- curve->AddKeyframe(FilterKeyframe::Create(0.f, operations1, nullptr));
- curve->AddKeyframe(FilterKeyframe::Create(1.f, operations2, nullptr));
- ExpectBrightness(2.f, curve->GetValue(-1.f));
- ExpectBrightness(2.f, curve->GetValue(0.f));
- ExpectBrightness(3.f, curve->GetValue(0.5f));
- ExpectBrightness(4.f, curve->GetValue(1.f));
- ExpectBrightness(4.f, curve->GetValue(2.f));
+ curve->AddKeyframe(
+ FilterKeyframe::Create(base::TimeDelta(), operations1, nullptr));
+ curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f),
+ operations2, nullptr));
+ ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ ExpectBrightness(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
}
// Tests that a filter animation with three keyframes works as expected.
@@ -300,16 +348,19 @@
operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
FilterOperations operations3;
operations3.Append(FilterOperation::CreateBrightnessFilter(8.f));
- curve->AddKeyframe(FilterKeyframe::Create(0.f, operations1, nullptr));
- curve->AddKeyframe(FilterKeyframe::Create(1.f, operations2, nullptr));
- curve->AddKeyframe(FilterKeyframe::Create(2.f, operations3, nullptr));
- ExpectBrightness(2.f, curve->GetValue(-1.f));
- ExpectBrightness(2.f, curve->GetValue(0.f));
- ExpectBrightness(3.f, curve->GetValue(0.5f));
- ExpectBrightness(4.f, curve->GetValue(1.f));
- ExpectBrightness(6.f, curve->GetValue(1.5f));
- ExpectBrightness(8.f, curve->GetValue(2.f));
- ExpectBrightness(8.f, curve->GetValue(3.f));
+ curve->AddKeyframe(
+ FilterKeyframe::Create(base::TimeDelta(), operations1, nullptr));
+ curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f),
+ operations2, nullptr));
+ curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(2.f),
+ operations3, nullptr));
+ ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ ExpectBrightness(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
+ ExpectBrightness(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
+ ExpectBrightness(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
}
// Tests that a filter animation with multiple keys at a given time works
@@ -326,41 +377,47 @@
operations3.Append(FilterOperation::CreateBrightnessFilter(6.f));
FilterOperations operations4;
operations4.Append(FilterOperation::CreateBrightnessFilter(6.f));
- curve->AddKeyframe(FilterKeyframe::Create(0.f, operations1, nullptr));
- curve->AddKeyframe(FilterKeyframe::Create(1.f, operations2, nullptr));
- curve->AddKeyframe(FilterKeyframe::Create(1.f, operations3, nullptr));
- curve->AddKeyframe(FilterKeyframe::Create(2.f, operations4, nullptr));
+ curve->AddKeyframe(
+ FilterKeyframe::Create(base::TimeDelta(), operations1, nullptr));
+ curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f),
+ operations2, nullptr));
+ curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f),
+ operations3, nullptr));
+ curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(2.f),
+ operations4, nullptr));
- ExpectBrightness(4.f, curve->GetValue(-1.f));
- ExpectBrightness(4.f, curve->GetValue(0.f));
- ExpectBrightness(4.f, curve->GetValue(0.5f));
+ ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
// There is a discontinuity at 1. Any value between 4 and 6 is valid.
- FilterOperations value = curve->GetValue(1.f);
+ FilterOperations value = curve->GetValue(base::TimeDelta::FromSecondsD(1.f));
EXPECT_EQ(1u, value.size());
EXPECT_EQ(FilterOperation::BRIGHTNESS, value.at(0).type());
EXPECT_GE(value.at(0).amount(), 4);
EXPECT_LE(value.at(0).amount(), 6);
- ExpectBrightness(6.f, curve->GetValue(1.5f));
- ExpectBrightness(6.f, curve->GetValue(2.f));
- ExpectBrightness(6.f, curve->GetValue(3.f));
+ ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
+ ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
+ ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
}
// Tests that the keyframes may be added out of order.
TEST(KeyframedAnimationCurveTest, UnsortedKeyframes) {
scoped_ptr<KeyframedFloatAnimationCurve> curve(
KeyframedFloatAnimationCurve::Create());
- curve->AddKeyframe(FloatKeyframe::Create(2.0, 8.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(0.0, 2.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(1.0, 4.f, nullptr));
- EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f));
- EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f));
- EXPECT_FLOAT_EQ(3.f, curve->GetValue(0.5f));
- EXPECT_FLOAT_EQ(4.f, curve->GetValue(1.f));
- EXPECT_FLOAT_EQ(6.f, curve->GetValue(1.5f));
- EXPECT_FLOAT_EQ(8.f, curve->GetValue(2.f));
- EXPECT_FLOAT_EQ(8.f, curve->GetValue(3.f));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), 8.f, nullptr));
+ curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 4.f, nullptr));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
+ EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
+ EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
}
// Tests that a cubic bezier timing function works as expected.
@@ -368,16 +425,19 @@
scoped_ptr<KeyframedFloatAnimationCurve> curve(
KeyframedFloatAnimationCurve::Create());
curve->AddKeyframe(FloatKeyframe::Create(
- 0.0, 0.f, CubicBezierTimingFunction::Create(0.25f, 0.f, 0.75f, 1.f)));
- curve->AddKeyframe(FloatKeyframe::Create(1.0, 1.f, nullptr));
+ base::TimeDelta(), 0.f,
+ CubicBezierTimingFunction::Create(0.25f, 0.f, 0.75f, 1.f)));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 1.f, nullptr));
- EXPECT_FLOAT_EQ(0.f, curve->GetValue(0.f));
- EXPECT_LT(0.f, curve->GetValue(0.25f));
- EXPECT_GT(0.25f, curve->GetValue(0.25f));
- EXPECT_NEAR(curve->GetValue(0.5f), 0.5f, 0.00015f);
- EXPECT_LT(0.75f, curve->GetValue(0.75f));
- EXPECT_GT(1.f, curve->GetValue(0.75f));
- EXPECT_FLOAT_EQ(1.f, curve->GetValue(1.f));
+ EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ EXPECT_LT(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)));
+ EXPECT_GT(0.25f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)));
+ EXPECT_NEAR(curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)), 0.5f,
+ 0.00015f);
+ EXPECT_LT(0.75f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
+ EXPECT_GT(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
+ EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
}
// Tests that animated bounds are computed as expected.
@@ -386,13 +446,16 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations1;
- curve->AddKeyframe(TransformKeyframe::Create(0.0, operations1, nullptr));
+ curve->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
operations1.AppendTranslate(2.0, 3.0, -1.0);
- curve->AddKeyframe(TransformKeyframe::Create(0.5, operations1, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(0.5f), operations1, nullptr));
TransformOperations operations2;
operations2.AppendTranslate(4.0, 1.0, 2.0);
- curve->AddKeyframe(TransformKeyframe::Create(
- 1.0, operations2, EaseTimingFunction::Create()));
+ curve->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), operations2,
+ EaseTimingFunction::Create()));
gfx::BoxF box(2.f, 3.f, 4.f, 1.f, 3.f, 2.f);
gfx::BoxF bounds;
@@ -408,23 +471,27 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations1;
- curve->AddKeyframe(TransformKeyframe::Create(0.0, operations1, nullptr));
+ curve->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
operations1.AppendTranslate(2.0, 3.0, -1.0);
TransformOperations operations2;
operations2.AppendTranslate(4.0, 1.0, 2.0);
- curve->AddKeyframe(TransformKeyframe::Create(1.0, operations2, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.f), operations2, nullptr));
EXPECT_FALSE(curve->AffectsScale());
TransformOperations operations3;
operations3.AppendScale(2.f, 2.f, 2.f);
- curve->AddKeyframe(TransformKeyframe::Create(2.0, operations3, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(2.f), operations3, nullptr));
EXPECT_TRUE(curve->AffectsScale());
TransformOperations operations4;
operations3.AppendTranslate(2.f, 2.f, 2.f);
- curve->AddKeyframe(TransformKeyframe::Create(3.0, operations4, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(3.f), operations4, nullptr));
EXPECT_TRUE(curve->AffectsScale());
}
@@ -435,23 +502,27 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations1;
- curve->AddKeyframe(TransformKeyframe::Create(0.0, operations1, nullptr));
+ curve->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
operations1.AppendTranslate(2.0, 3.0, -1.0);
TransformOperations operations2;
operations2.AppendTranslate(4.0, 1.0, 2.0);
- curve->AddKeyframe(TransformKeyframe::Create(1.0, operations2, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.f), operations2, nullptr));
EXPECT_TRUE(curve->IsTranslation());
TransformOperations operations3;
operations3.AppendScale(2.f, 2.f, 2.f);
- curve->AddKeyframe(TransformKeyframe::Create(2.0, operations3, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(2.f), operations3, nullptr));
EXPECT_FALSE(curve->IsTranslation());
TransformOperations operations4;
operations3.AppendTranslate(2.f, 2.f, 2.f);
- curve->AddKeyframe(TransformKeyframe::Create(3.0, operations4, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(3.f), operations4, nullptr));
EXPECT_FALSE(curve->IsTranslation());
}
@@ -462,10 +533,12 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations1;
- curve->AddKeyframe(TransformKeyframe::Create(0.0, operations1, nullptr));
+ curve->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
operations1.AppendScale(2.f, -3.f, 1.f);
- curve->AddKeyframe(TransformKeyframe::Create(
- 1.0, operations1, EaseTimingFunction::Create()));
+ curve->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), operations1,
+ EaseTimingFunction::Create()));
float maximum_scale = 0.f;
EXPECT_TRUE(curve->MaximumTargetScale(true, &maximum_scale));
@@ -473,16 +546,18 @@
TransformOperations operations2;
operations2.AppendScale(6.f, 3.f, 2.f);
- curve->AddKeyframe(TransformKeyframe::Create(
- 2.0, operations2, EaseTimingFunction::Create()));
+ curve->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), operations2,
+ EaseTimingFunction::Create()));
EXPECT_TRUE(curve->MaximumTargetScale(true, &maximum_scale));
EXPECT_EQ(6.f, maximum_scale);
TransformOperations operations3;
operations3.AppendRotate(1.f, 0.f, 0.f, 90.f);
- curve->AddKeyframe(TransformKeyframe::Create(
- 3.0, operations3, EaseTimingFunction::Create()));
+ curve->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta::FromSecondsD(3.f), operations3,
+ EaseTimingFunction::Create()));
EXPECT_FALSE(curve->MaximumTargetScale(true, &maximum_scale));
@@ -492,12 +567,13 @@
TransformOperations operations4;
operations4.AppendScale(0.4f, 0.2f, 0.6f);
- curve2->AddKeyframe(TransformKeyframe::Create(
- 0.0, operations4, EaseTimingFunction::Create()));
+ curve2->AddKeyframe(TransformKeyframe::Create(base::TimeDelta(), operations4,
+ EaseTimingFunction::Create()));
TransformOperations operations5;
operations5.AppendScale(0.5f, 0.3f, -0.8f);
- curve2->AddKeyframe(TransformKeyframe::Create(
- 1.0, operations5, EaseTimingFunction::Create()));
+ curve2->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), operations5,
+ EaseTimingFunction::Create()));
EXPECT_TRUE(curve2->MaximumTargetScale(true, &maximum_scale));
EXPECT_EQ(0.8f, maximum_scale);
@@ -510,17 +586,20 @@
TEST(KeyframedAnimationCurveTest, CurveTiming) {
scoped_ptr<KeyframedFloatAnimationCurve> curve(
KeyframedFloatAnimationCurve::Create());
- curve->AddKeyframe(FloatKeyframe::Create(0.0, 0.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(1.0, 1.f, nullptr));
+ curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr));
curve->SetTimingFunction(
CubicBezierTimingFunction::Create(0.75f, 0.f, 0.25f, 1.f).Pass());
- EXPECT_FLOAT_EQ(0.f, curve->GetValue(-1.f));
- EXPECT_FLOAT_EQ(0.f, curve->GetValue(0.f));
- EXPECT_NEAR(0.05f, curve->GetValue(0.25f), 0.005f);
- EXPECT_FLOAT_EQ(0.5f, curve->GetValue(0.5f));
- EXPECT_NEAR(0.95f, curve->GetValue(0.75f), 0.005f);
- EXPECT_FLOAT_EQ(1.f, curve->GetValue(1.f));
- EXPECT_FLOAT_EQ(1.f, curve->GetValue(2.f));
+ EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ EXPECT_NEAR(0.05f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)),
+ 0.005f);
+ EXPECT_FLOAT_EQ(0.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ EXPECT_NEAR(0.95f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)),
+ 0.005f);
+ EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
}
// Tests that an animation with a curve and keyframe timing function works as
@@ -529,22 +608,26 @@
scoped_ptr<KeyframedFloatAnimationCurve> curve(
KeyframedFloatAnimationCurve::Create());
curve->AddKeyframe(FloatKeyframe::Create(
- 0.0,
- 0.f,
+ base::TimeDelta(), 0.f,
CubicBezierTimingFunction::Create(0.35f, 0.f, 0.65f, 1.f).Pass()));
- curve->AddKeyframe(FloatKeyframe::Create(1.0, 1.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr));
// Curve timing function producing outputs outside of range [0,1].
curve->SetTimingFunction(
CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f).Pass());
- EXPECT_FLOAT_EQ(0.f, curve->GetValue(-1.f));
- EXPECT_FLOAT_EQ(0.f, curve->GetValue(0.f));
- EXPECT_FLOAT_EQ(0.f, curve->GetValue(0.25f)); // Clamped. c(.25) < 0
- EXPECT_NEAR(0.17f, curve->GetValue(0.42f), 0.005f); // c(.42)=.27, k(.27)=.17
- EXPECT_FLOAT_EQ(0.5f, curve->GetValue(0.5f));
- EXPECT_NEAR(0.83f, curve->GetValue(0.58f), 0.005f); // c(.58)=.73, k(.73)=.83
- EXPECT_FLOAT_EQ(1.f, curve->GetValue(0.75f)); // Clamped. c(.75) > 1
- EXPECT_FLOAT_EQ(1.f, curve->GetValue(1.f));
- EXPECT_FLOAT_EQ(1.f, curve->GetValue(2.f));
+ EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(
+ 0.25f))); // Clamped. c(.25) < 0
+ EXPECT_NEAR(0.17f, curve->GetValue(base::TimeDelta::FromSecondsD(0.42f)),
+ 0.005f); // c(.42)=.27, k(.27)=.17
+ EXPECT_FLOAT_EQ(0.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
+ EXPECT_NEAR(0.83f, curve->GetValue(base::TimeDelta::FromSecondsD(0.58f)),
+ 0.005f); // c(.58)=.73, k(.73)=.83
+ EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(
+ 0.75f))); // Clamped. c(.75) > 1
+ EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
+ EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
}
// Tests that an animation with a curve timing function and multiple keyframes
@@ -552,21 +635,28 @@
TEST(KeyframedAnimationCurveTest, CurveTimingMultipleKeyframes) {
scoped_ptr<KeyframedFloatAnimationCurve> curve(
KeyframedFloatAnimationCurve::Create());
- curve->AddKeyframe(FloatKeyframe::Create(0.0, 0.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(1.0, 1.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(2.0, 3.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(3.0, 6.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(4.0, 9.f, nullptr));
+ curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), 3.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(3.f), 6.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(4.f), 9.f, nullptr));
curve->SetTimingFunction(
CubicBezierTimingFunction::Create(0.5f, 0.f, 0.5f, 1.f).Pass());
- EXPECT_FLOAT_EQ(0.f, curve->GetValue(-1.f));
- EXPECT_FLOAT_EQ(0.f, curve->GetValue(0.f));
- EXPECT_NEAR(0.42f, curve->GetValue(1.f), 0.005f);
- EXPECT_NEAR(1.f, curve->GetValue(1.455f), 0.005f);
- EXPECT_FLOAT_EQ(3.f, curve->GetValue(2.f));
- EXPECT_NEAR(8.72f, curve->GetValue(3.5f), 0.01f);
- EXPECT_FLOAT_EQ(9.f, curve->GetValue(4.f));
- EXPECT_FLOAT_EQ(9.f, curve->GetValue(5.f));
+ EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
+ EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
+ EXPECT_NEAR(0.42f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)),
+ 0.005f);
+ EXPECT_NEAR(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.455f)),
+ 0.005f);
+ EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
+ EXPECT_NEAR(8.72f, curve->GetValue(base::TimeDelta::FromSecondsD(3.5f)),
+ 0.01f);
+ EXPECT_FLOAT_EQ(9.f, curve->GetValue(base::TimeDelta::FromSecondsD(4.f)));
+ EXPECT_FLOAT_EQ(9.f, curve->GetValue(base::TimeDelta::FromSecondsD(5.f)));
}
// Tests that an animation with a curve timing function that overshoots works as
@@ -574,16 +664,22 @@
TEST(KeyframedAnimationCurveTest, CurveTimingOvershootMultipeKeyframes) {
scoped_ptr<KeyframedFloatAnimationCurve> curve(
KeyframedFloatAnimationCurve::Create());
- curve->AddKeyframe(FloatKeyframe::Create(0.0, 0.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(1.0, 1.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(2.0, 3.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(3.0, 6.f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(4.0, 9.f, nullptr));
+ curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 1.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), 3.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(3.0), 6.f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(4.0), 9.f, nullptr));
// Curve timing function producing outputs outside of range [0,1].
curve->SetTimingFunction(
CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f).Pass());
- EXPECT_LE(curve->GetValue(1.f), 0.f); // c(.25) < 0
- EXPECT_GE(curve->GetValue(3.f), 9.f); // c(.75) > 1
+ EXPECT_LE(curve->GetValue(base::TimeDelta::FromSecondsD(1.f)),
+ 0.f); // c(.25) < 0
+ EXPECT_GE(curve->GetValue(base::TimeDelta::FromSecondsD(3.f)),
+ 9.f); // c(.75) > 1
}
} // namespace
diff --git a/cc/animation/layer_animation_controller.cc b/cc/animation/layer_animation_controller.cc
index f621ad3..c9d81cf 100644
--- a/cc/animation/layer_animation_controller.cc
+++ b/cc/animation/layer_animation_controller.cc
@@ -148,8 +148,8 @@
if (!animation->InEffect(monotonic_time))
continue;
- double trimmed =
- animation->TrimTimeToCurrentIteration(monotonic_time).InSecondsF();
+ base::TimeDelta trimmed =
+ animation->TrimTimeToCurrentIteration(monotonic_time);
switch (animation->target_property()) {
case Animation::Opacity: {
AnimationEvent event(AnimationEvent::PropertyUpdate,
@@ -861,9 +861,8 @@
if (!animations_[i]->InEffect(monotonic_time))
continue;
- double trimmed = animations_[i]
- ->TrimTimeToCurrentIteration(monotonic_time)
- .InSecondsF();
+ base::TimeDelta trimmed =
+ animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
switch (animations_[i]->target_property()) {
case Animation::Transform: {
diff --git a/cc/animation/layer_animation_controller_unittest.cc b/cc/animation/layer_animation_controller_unittest.cc
index 4fa3d84..464a973 100644
--- a/cc/animation/layer_animation_controller_unittest.cc
+++ b/cc/animation/layer_animation_controller_unittest.cc
@@ -510,9 +510,11 @@
// Create simple Transform animation.
TransformOperations operations;
- curve->AddKeyframe(TransformKeyframe::Create(0, operations, nullptr));
+ curve->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations, nullptr));
operations.AppendTranslate(delta_x, delta_y, 0);
- curve->AddKeyframe(TransformKeyframe::Create(1, operations, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations, nullptr));
scoped_ptr<Animation> animation(
Animation::Create(curve.Pass(), 1, 0, Animation::Transform));
@@ -559,10 +561,12 @@
FilterOperations start_filters;
start_filters.Append(FilterOperation::CreateBrightnessFilter(1.f));
- curve->AddKeyframe(FilterKeyframe::Create(0, start_filters, nullptr));
+ curve->AddKeyframe(
+ FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr));
FilterOperations end_filters;
end_filters.Append(FilterOperation::CreateBrightnessFilter(2.f));
- curve->AddKeyframe(FilterKeyframe::Create(1, end_filters, nullptr));
+ curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
+ end_filters, nullptr));
scoped_ptr<Animation> animation(
Animation::Create(curve.Pass(), 1, 0, Animation::Filter));
@@ -606,10 +610,12 @@
// Create simple Filter animation.
FilterOperations start_filters;
start_filters.Append(FilterOperation::CreateBrightnessFilter(1.f));
- curve->AddKeyframe(FilterKeyframe::Create(0, start_filters, nullptr));
+ curve->AddKeyframe(
+ FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr));
FilterOperations end_filters;
end_filters.Append(FilterOperation::CreateBrightnessFilter(2.f));
- curve->AddKeyframe(FilterKeyframe::Create(1, end_filters, nullptr));
+ curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
+ end_filters, nullptr));
scoped_ptr<Animation> animation(
Animation::Create(curve.Pass(), 1, 0, Animation::Filter));
@@ -1465,9 +1471,11 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations1;
- curve1->AddKeyframe(TransformKeyframe::Create(0.0, operations1, nullptr));
+ curve1->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
operations1.AppendTranslate(10.0, 15.0, 0.0);
- curve1->AddKeyframe(TransformKeyframe::Create(1.0, operations1, nullptr));
+ curve1->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations1, nullptr));
scoped_ptr<Animation> animation(
Animation::Create(curve1.Pass(), 1, 1, Animation::Transform));
@@ -1477,9 +1485,11 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations2;
- curve2->AddKeyframe(TransformKeyframe::Create(0.0, operations2, nullptr));
+ curve2->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr));
operations2.AppendScale(2.0, 3.0, 4.0);
- curve2->AddKeyframe(TransformKeyframe::Create(1.0, operations2, nullptr));
+ curve2->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
animation = Animation::Create(curve2.Pass(), 2, 2, Animation::Transform);
controller_impl->AddAnimation(animation.Pass());
@@ -1511,9 +1521,11 @@
TransformOperations operations3;
gfx::Transform transform3;
transform3.Scale3d(1.0, 2.0, 3.0);
- curve3->AddKeyframe(TransformKeyframe::Create(0.0, operations3, nullptr));
+ curve3->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations3, nullptr));
operations3.AppendMatrix(transform3);
- curve3->AddKeyframe(TransformKeyframe::Create(1.0, operations3, nullptr));
+ curve3->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations3, nullptr));
animation = Animation::Create(curve3.Pass(), 3, 3, Animation::Transform);
controller_impl->AddAnimation(animation.Pass());
EXPECT_FALSE(controller_impl->TransformAnimationBoundsForBox(box, &bounds));
@@ -1781,9 +1793,11 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations1;
- curve1->AddKeyframe(TransformKeyframe::Create(0.0, operations1, nullptr));
+ curve1->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
operations1.AppendTranslate(10.0, 15.0, 0.0);
- curve1->AddKeyframe(TransformKeyframe::Create(1.0, operations1, nullptr));
+ curve1->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations1, nullptr));
scoped_ptr<Animation> animation(
Animation::Create(curve1.Pass(), 2, 2, Animation::Transform));
@@ -1796,9 +1810,11 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations2;
- curve2->AddKeyframe(TransformKeyframe::Create(0.0, operations2, nullptr));
+ curve2->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr));
operations2.AppendScale(2.0, 3.0, 4.0);
- curve2->AddKeyframe(TransformKeyframe::Create(1.0, operations2, nullptr));
+ curve2->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
animation = Animation::Create(curve2.Pass(), 3, 3, Animation::Transform);
controller_impl->AddAnimation(animation.Pass());
@@ -1831,9 +1847,11 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations1;
- curve1->AddKeyframe(TransformKeyframe::Create(0.0, operations1, nullptr));
+ curve1->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
operations1.AppendTranslate(10.0, 15.0, 0.0);
- curve1->AddKeyframe(TransformKeyframe::Create(1.0, operations1, nullptr));
+ curve1->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations1, nullptr));
scoped_ptr<Animation> animation(
Animation::Create(curve1.Pass(), 2, 2, Animation::Transform));
@@ -1846,9 +1864,11 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations2;
- curve2->AddKeyframe(TransformKeyframe::Create(0.0, operations2, nullptr));
+ curve2->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr));
operations2.AppendScale(2.0, 3.0, 4.0);
- curve2->AddKeyframe(TransformKeyframe::Create(1.0, operations2, nullptr));
+ curve2->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
animation = Animation::Create(curve2.Pass(), 3, 3, Animation::Transform);
controller_impl->AddAnimation(animation.Pass());
@@ -1876,9 +1896,11 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations1;
- curve1->AddKeyframe(TransformKeyframe::Create(0.0, operations1, nullptr));
+ curve1->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
operations1.AppendScale(2.0, 3.0, 4.0);
- curve1->AddKeyframe(TransformKeyframe::Create(1.0, operations1, nullptr));
+ curve1->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations1, nullptr));
scoped_ptr<Animation> animation(
Animation::Create(curve1.Pass(), 1, 1, Animation::Transform));
@@ -1891,9 +1913,11 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations2;
- curve2->AddKeyframe(TransformKeyframe::Create(0.0, operations2, nullptr));
+ curve2->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations2, nullptr));
operations2.AppendScale(6.0, 5.0, 4.0);
- curve2->AddKeyframe(TransformKeyframe::Create(1.0, operations2, nullptr));
+ curve2->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
animation = Animation::Create(curve2.Pass(), 2, 2, Animation::Transform);
controller_impl->AddAnimation(animation.Pass());
@@ -1905,9 +1929,11 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations3;
- curve3->AddKeyframe(TransformKeyframe::Create(0.0, operations3, nullptr));
+ curve3->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations3, nullptr));
operations3.AppendPerspective(6.0);
- curve3->AddKeyframe(TransformKeyframe::Create(1.0, operations3, nullptr));
+ curve3->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations3, nullptr));
animation = Animation::Create(curve3.Pass(), 3, 3, Animation::Transform);
controller_impl->AddAnimation(animation.Pass());
@@ -1933,10 +1959,12 @@
KeyframedTransformAnimationCurve::Create());
TransformOperations operations1;
operations1.AppendScale(1.0, 2.0, 3.0);
- curve1->AddKeyframe(TransformKeyframe::Create(0.0, operations1, nullptr));
+ curve1->AddKeyframe(
+ TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
TransformOperations operations2;
operations2.AppendScale(4.0, 5.0, 6.0);
- curve1->AddKeyframe(TransformKeyframe::Create(1.0, operations2, nullptr));
+ curve1->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
scoped_ptr<Animation> animation_owned(
Animation::Create(curve1.Pass(), 1, 1, Animation::Transform));
diff --git a/cc/animation/scroll_offset_animation_curve.cc b/cc/animation/scroll_offset_animation_curve.cc
index e0b1a3b..9567263 100644
--- a/cc/animation/scroll_offset_animation_curve.cc
+++ b/cc/animation/scroll_offset_animation_curve.cc
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "cc/animation/timing_function.h"
+#include "cc/base/time_util.h"
#include "ui/gfx/animation/tween.h"
const double kDurationDivisor = 60.0;
@@ -65,17 +66,18 @@
target_value_.DeltaFrom(initial_value_));
}
-gfx::ScrollOffset ScrollOffsetAnimationCurve::GetValue(double t) const {
- double duration = (total_animation_duration_ - last_retarget_).InSecondsF();
- t -= last_retarget_.InSecondsF();
+gfx::ScrollOffset ScrollOffsetAnimationCurve::GetValue(
+ base::TimeDelta t) const {
+ base::TimeDelta duration = total_animation_duration_ - last_retarget_;
+ t -= last_retarget_;
- if (t <= 0)
+ if (t <= base::TimeDelta())
return initial_value_;
if (t >= duration)
return target_value_;
- double progress = (timing_function_->GetValue(t / duration));
+ double progress = timing_function_->GetValue(TimeUtil::Divide(t, duration));
return gfx::ScrollOffset(
gfx::Tween::FloatValueBetween(
progress, initial_value_.x(), target_value_.x()),
@@ -105,7 +107,8 @@
void ScrollOffsetAnimationCurve::UpdateTarget(
double t,
const gfx::ScrollOffset& new_target) {
- gfx::ScrollOffset current_position = GetValue(t);
+ gfx::ScrollOffset current_position =
+ GetValue(base::TimeDelta::FromSecondsD(t));
gfx::Vector2dF old_delta = target_value_.DeltaFrom(initial_value_);
gfx::Vector2dF new_delta = new_target.DeltaFrom(current_position);
diff --git a/cc/animation/scroll_offset_animation_curve.h b/cc/animation/scroll_offset_animation_curve.h
index 50dfb17..c4ae70b 100644
--- a/cc/animation/scroll_offset_animation_curve.h
+++ b/cc/animation/scroll_offset_animation_curve.h
@@ -24,7 +24,7 @@
~ScrollOffsetAnimationCurve() override;
void SetInitialValue(const gfx::ScrollOffset& initial_value);
- gfx::ScrollOffset GetValue(double t) const;
+ gfx::ScrollOffset GetValue(base::TimeDelta t) const;
gfx::ScrollOffset target_value() const { return target_value_; }
void UpdateTarget(double t, const gfx::ScrollOffset& new_target);
diff --git a/cc/animation/scroll_offset_animation_curve_unittest.cc b/cc/animation/scroll_offset_animation_curve_unittest.cc
index d57814e..cb3e914 100644
--- a/cc/animation/scroll_offset_animation_curve_unittest.cc
+++ b/cc/animation/scroll_offset_animation_curve_unittest.cc
@@ -5,6 +5,7 @@
#include "cc/animation/scroll_offset_animation_curve.h"
#include "cc/animation/timing_function.h"
+#include "cc/base/time_util.h"
#include "cc/test/geometry_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -63,24 +64,28 @@
EaseInOutTimingFunction::Create().Pass()));
curve->SetInitialValue(initial_value);
- double duration_in_seconds = curve->Duration().InSecondsF();
+ base::TimeDelta duration = curve->Duration();
EXPECT_GT(curve->Duration().InSecondsF(), 0);
EXPECT_LT(curve->Duration().InSecondsF(), 0.1);
EXPECT_EQ(AnimationCurve::ScrollOffset, curve->Type());
- EXPECT_EQ(duration_in_seconds, curve->Duration().InSecondsF());
+ EXPECT_EQ(duration, curve->Duration());
- EXPECT_VECTOR2DF_EQ(initial_value, curve->GetValue(-1.0));
- EXPECT_VECTOR2DF_EQ(initial_value, curve->GetValue(0.0));
- EXPECT_VECTOR2DF_EQ(gfx::ScrollOffset(6.f, 30.f),
- curve->GetValue(duration_in_seconds / 2.0));
- EXPECT_VECTOR2DF_EQ(target_value, curve->GetValue(duration_in_seconds));
- EXPECT_VECTOR2DF_EQ(target_value, curve->GetValue(duration_in_seconds + 1.0));
+ EXPECT_VECTOR2DF_EQ(initial_value,
+ curve->GetValue(base::TimeDelta::FromSecondsD(-1.0)));
+ EXPECT_VECTOR2DF_EQ(initial_value, curve->GetValue(base::TimeDelta()));
+ EXPECT_VECTOR2DF_NEAR(gfx::ScrollOffset(6.f, 30.f),
+ curve->GetValue(TimeUtil::Scale(duration, 0.5f)),
+ 0.00025);
+ EXPECT_VECTOR2DF_EQ(target_value, curve->GetValue(duration));
+ EXPECT_VECTOR2DF_EQ(
+ target_value,
+ curve->GetValue(duration + base::TimeDelta::FromSecondsD(1.0)));
// Verify that GetValue takes the timing function into account.
- gfx::ScrollOffset value = curve->GetValue(duration_in_seconds / 4.0);
- EXPECT_NEAR(3.0333f, value.x(), 0.00015f);
- EXPECT_NEAR(37.4168f, value.y(), 0.00015f);
+ gfx::ScrollOffset value = curve->GetValue(TimeUtil::Scale(duration, 0.25f));
+ EXPECT_NEAR(3.0333f, value.x(), 0.0002f);
+ EXPECT_NEAR(37.4168f, value.y(), 0.0002f);
}
// Verify that a clone behaves exactly like the original.
@@ -92,32 +97,34 @@
target_value,
EaseInOutTimingFunction::Create().Pass()));
curve->SetInitialValue(initial_value);
- double duration_in_seconds = curve->Duration().InSecondsF();
+ base::TimeDelta duration = curve->Duration();
scoped_ptr<AnimationCurve> clone(curve->Clone().Pass());
EXPECT_EQ(AnimationCurve::ScrollOffset, clone->Type());
- EXPECT_EQ(duration_in_seconds, clone->Duration().InSecondsF());
+ EXPECT_EQ(duration, clone->Duration());
EXPECT_VECTOR2DF_EQ(initial_value,
- clone->ToScrollOffsetAnimationCurve()->GetValue(-1.0));
- EXPECT_VECTOR2DF_EQ(initial_value,
- clone->ToScrollOffsetAnimationCurve()->GetValue(0.0));
- EXPECT_VECTOR2DF_EQ(gfx::ScrollOffset(6.f, 30.f),
clone->ToScrollOffsetAnimationCurve()->GetValue(
- duration_in_seconds / 2.0));
+ base::TimeDelta::FromSecondsD(-1.0)));
EXPECT_VECTOR2DF_EQ(
- target_value,
- clone->ToScrollOffsetAnimationCurve()->GetValue(duration_in_seconds));
+ initial_value,
+ clone->ToScrollOffsetAnimationCurve()->GetValue(base::TimeDelta()));
+ EXPECT_VECTOR2DF_NEAR(gfx::ScrollOffset(6.f, 30.f),
+ clone->ToScrollOffsetAnimationCurve()->GetValue(
+ TimeUtil::Scale(duration, 0.5f)),
+ 0.00025);
+ EXPECT_VECTOR2DF_EQ(
+ target_value, clone->ToScrollOffsetAnimationCurve()->GetValue(duration));
EXPECT_VECTOR2DF_EQ(target_value,
clone->ToScrollOffsetAnimationCurve()->GetValue(
- duration_in_seconds + 1.0));
+ duration + base::TimeDelta::FromSecondsD(1.f)));
// Verify that the timing function was cloned correctly.
gfx::ScrollOffset value = clone->ToScrollOffsetAnimationCurve()->GetValue(
- duration_in_seconds / 4.0);
- EXPECT_NEAR(3.0333f, value.x(), 0.00015f);
- EXPECT_NEAR(37.4168f, value.y(), 0.00015f);
+ TimeUtil::Scale(duration, 0.25f));
+ EXPECT_NEAR(3.0333f, value.x(), 0.0002f);
+ EXPECT_NEAR(37.4168f, value.y(), 0.0002f);
}
TEST(ScrollOffsetAnimationCurveTest, UpdateTarget) {
@@ -128,21 +135,23 @@
target_value, EaseInOutTimingFunction::Create().Pass()));
curve->SetInitialValue(initial_value);
EXPECT_EQ(1.0, curve->Duration().InSecondsF());
- EXPECT_EQ(1800.0, curve->GetValue(0.5).y());
- EXPECT_EQ(3600.0, curve->GetValue(1.0).y());
+ EXPECT_EQ(1800.0, curve->GetValue(base::TimeDelta::FromSecondsD(0.5)).y());
+ EXPECT_EQ(3600.0, curve->GetValue(base::TimeDelta::FromSecondsD(1.0)).y());
curve->UpdateTarget(0.5, gfx::ScrollOffset(0.0, 9900.0));
EXPECT_EQ(2.0, curve->Duration().InSecondsF());
- EXPECT_EQ(1800.0, curve->GetValue(0.5).y());
- EXPECT_NEAR(5566.49, curve->GetValue(1.0).y(), 0.01);
- EXPECT_EQ(9900.0, curve->GetValue(2.0).y());
+ EXPECT_EQ(1800.0, curve->GetValue(base::TimeDelta::FromSecondsD(0.5)).y());
+ EXPECT_NEAR(5566.49, curve->GetValue(base::TimeDelta::FromSecondsD(1.0)).y(),
+ 0.01);
+ EXPECT_EQ(9900.0, curve->GetValue(base::TimeDelta::FromSecondsD(2.0)).y());
curve->UpdateTarget(1.0, gfx::ScrollOffset(0.0, 7200.0));
EXPECT_NEAR(1.674, curve->Duration().InSecondsF(), 0.01);
- EXPECT_NEAR(5566.49, curve->GetValue(1.0).y(), 0.01);
- EXPECT_EQ(7200.0, curve->GetValue(1.674).y());
+ EXPECT_NEAR(5566.49, curve->GetValue(base::TimeDelta::FromSecondsD(1.0)).y(),
+ 0.01);
+ EXPECT_EQ(7200.0, curve->GetValue(base::TimeDelta::FromSecondsD(1.674)).y());
}
} // namespace
diff --git a/cc/base/time_util.h b/cc/base/time_util.h
index dc07e74..06682c2 100644
--- a/cc/base/time_util.h
+++ b/cc/base/time_util.h
@@ -18,6 +18,11 @@
static_cast<double>(time_delta.ToInternalValue()) * value));
}
+ static double Divide(base::TimeDelta dividend, base::TimeDelta divisor) {
+ return static_cast<double>(dividend.ToInternalValue()) /
+ static_cast<double>(divisor.ToInternalValue());
+ }
+
static base::TimeDelta Mod(base::TimeDelta dividend,
base::TimeDelta divisor) {
return base::TimeDelta::FromInternalValue(dividend.ToInternalValue() %
diff --git a/cc/blink/web_content_layer_impl.cc b/cc/blink/web_content_layer_impl.cc
index 6dfdad9..d0a4cca 100644
--- a/cc/blink/web_content_layer_impl.cc
+++ b/cc/blink/web_content_layer_impl.cc
@@ -19,13 +19,12 @@
namespace cc_blink {
WebContentLayerImpl::WebContentLayerImpl(blink::WebContentLayerClient* client)
- : client_(client), ignore_lcd_text_change_(false) {
+ : client_(client) {
if (WebLayerImpl::UsingPictureLayer())
layer_ = make_scoped_ptr(new WebLayerImpl(PictureLayer::Create(this)));
else
layer_ = make_scoped_ptr(new WebLayerImpl(ContentLayer::Create(this)));
layer_->layer()->SetIsDrawable(true);
- can_use_lcd_text_ = layer_->layer()->can_use_lcd_text();
}
WebContentLayerImpl::~WebContentLayerImpl() {
@@ -54,30 +53,16 @@
if (!client_)
return;
+ // TODO(danakj): Stop passing this to blink it should always use LCD when it
+ // wants to. crbug.com/430617
+ bool can_use_lcd_text = true;
client_->paintContents(
- canvas,
- clip,
- can_use_lcd_text_,
+ canvas, clip, can_use_lcd_text,
graphics_context_status == ContentLayerClient::GRAPHICS_CONTEXT_ENABLED
? blink::WebContentLayerClient::GraphicsContextEnabled
: blink::WebContentLayerClient::GraphicsContextDisabled);
}
-void WebContentLayerImpl::DidChangeLayerCanUseLCDText() {
- // It is important to make this comparison because the LCD text status
- // here can get out of sync with that in the layer.
- if (can_use_lcd_text_ == layer_->layer()->can_use_lcd_text())
- return;
-
- // LCD text cannot be enabled once disabled.
- if (layer_->layer()->can_use_lcd_text() && ignore_lcd_text_change_)
- return;
-
- can_use_lcd_text_ = layer_->layer()->can_use_lcd_text();
- ignore_lcd_text_change_ = true;
- layer_->invalidate();
-}
-
bool WebContentLayerImpl::FillsBoundsCompletely() const {
return false;
}
diff --git a/cc/blink/web_content_layer_impl.h b/cc/blink/web_content_layer_impl.h
index b9bb871..2966bd4 100644
--- a/cc/blink/web_content_layer_impl.h
+++ b/cc/blink/web_content_layer_impl.h
@@ -40,7 +40,6 @@
const gfx::Rect& clip,
ContentLayerClient::GraphicsContextStatus
graphics_context_status) override;
- void DidChangeLayerCanUseLCDText() override;
bool FillsBoundsCompletely() const override;
scoped_ptr<WebLayerImpl> layer_;
diff --git a/cc/blink/web_filter_animation_curve_impl.cc b/cc/blink/web_filter_animation_curve_impl.cc
index 606929e..bdbffe8 100644
--- a/cc/blink/web_filter_animation_curve_impl.cc
+++ b/cc/blink/web_filter_animation_curve_impl.cc
@@ -32,7 +32,8 @@
static_cast<const WebFilterOperationsImpl&>(keyframe.value())
.AsFilterOperations();
curve_->AddKeyframe(cc::FilterKeyframe::Create(
- keyframe.time(), filter_operations, CreateTimingFunction(type)));
+ base::TimeDelta::FromSecondsD(keyframe.time()), filter_operations,
+ CreateTimingFunction(type)));
}
void WebFilterAnimationCurveImpl::add(const WebFilterKeyframe& keyframe,
@@ -44,8 +45,7 @@
static_cast<const WebFilterOperationsImpl&>(keyframe.value())
.AsFilterOperations();
curve_->AddKeyframe(cc::FilterKeyframe::Create(
- keyframe.time(),
- filter_operations,
+ base::TimeDelta::FromSecondsD(keyframe.time()), filter_operations,
cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2)));
}
diff --git a/cc/blink/web_float_animation_curve_impl.cc b/cc/blink/web_float_animation_curve_impl.cc
index e5eee53..d85f57c 100644
--- a/cc/blink/web_float_animation_curve_impl.cc
+++ b/cc/blink/web_float_animation_curve_impl.cc
@@ -31,8 +31,9 @@
void WebFloatAnimationCurveImpl::add(const WebFloatKeyframe& keyframe,
TimingFunctionType type) {
- curve_->AddKeyframe(cc::FloatKeyframe::Create(
- keyframe.time, keyframe.value, CreateTimingFunction(type)));
+ curve_->AddKeyframe(
+ cc::FloatKeyframe::Create(base::TimeDelta::FromSecondsD(keyframe.time),
+ keyframe.value, CreateTimingFunction(type)));
}
void WebFloatAnimationCurveImpl::add(const WebFloatKeyframe& keyframe,
@@ -41,8 +42,7 @@
double x2,
double y2) {
curve_->AddKeyframe(cc::FloatKeyframe::Create(
- keyframe.time,
- keyframe.value,
+ base::TimeDelta::FromSecondsD(keyframe.time), keyframe.value,
cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2)));
}
@@ -59,7 +59,7 @@
}
float WebFloatAnimationCurveImpl::getValue(double time) const {
- return curve_->GetValue(time);
+ return curve_->GetValue(base::TimeDelta::FromSecondsD(time));
}
scoped_ptr<cc::AnimationCurve>
diff --git a/cc/blink/web_scroll_offset_animation_curve_impl.cc b/cc/blink/web_scroll_offset_animation_curve_impl.cc
index ba55d5b..cef276c 100644
--- a/cc/blink/web_scroll_offset_animation_curve_impl.cc
+++ b/cc/blink/web_scroll_offset_animation_curve_impl.cc
@@ -34,7 +34,8 @@
}
WebFloatPoint WebScrollOffsetAnimationCurveImpl::getValue(double time) const {
- gfx::ScrollOffset value = curve_->GetValue(time);
+ gfx::ScrollOffset value =
+ curve_->GetValue(base::TimeDelta::FromSecondsD(time));
return WebFloatPoint(value.x(), value.y());
}
diff --git a/cc/blink/web_transform_animation_curve_impl.cc b/cc/blink/web_transform_animation_curve_impl.cc
index f91d94b..86f3602 100644
--- a/cc/blink/web_transform_animation_curve_impl.cc
+++ b/cc/blink/web_transform_animation_curve_impl.cc
@@ -36,7 +36,8 @@
static_cast<const WebTransformOperationsImpl&>(keyframe.value())
.AsTransformOperations();
curve_->AddKeyframe(cc::TransformKeyframe::Create(
- keyframe.time(), transform_operations, CreateTimingFunction(type)));
+ base::TimeDelta::FromSecondsD(keyframe.time()), transform_operations,
+ CreateTimingFunction(type)));
}
void WebTransformAnimationCurveImpl::add(const WebTransformKeyframe& keyframe,
@@ -48,8 +49,7 @@
static_cast<const WebTransformOperationsImpl&>(keyframe.value())
.AsTransformOperations();
curve_->AddKeyframe(cc::TransformKeyframe::Create(
- keyframe.time(),
- transform_operations,
+ base::TimeDelta::FromSecondsD(keyframe.time()), transform_operations,
cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2)));
}
diff --git a/cc/input/top_controls_manager.cc b/cc/input/top_controls_manager.cc
index cd3534c..ddde672 100644
--- a/cc/input/top_controls_manager.cc
+++ b/cc/input/top_controls_manager.cc
@@ -167,7 +167,7 @@
if (!top_controls_animation_ || !client_->HaveRootScrollLayer())
return gfx::Vector2dF();
- double time = (monotonic_time - base::TimeTicks()).InMillisecondsF();
+ base::TimeDelta time = monotonic_time - base::TimeTicks();
float old_offset = client_->ControlsTopOffset();
SetControlsTopOffset(top_controls_animation_->GetValue(time));
@@ -199,16 +199,15 @@
return;
top_controls_animation_ = KeyframedFloatAnimationCurve::Create();
- double start_time =
- (gfx::FrameTime::Now() - base::TimeTicks()).InMillisecondsF();
+ base::TimeDelta start_time = gfx::FrameTime::Now() - base::TimeTicks();
top_controls_animation_->AddKeyframe(
FloatKeyframe::Create(start_time, client_->ControlsTopOffset(), nullptr));
float max_ending_offset =
(direction == SHOWING_CONTROLS ? 1 : -1) * top_controls_height_;
- top_controls_animation_->AddKeyframe(
- FloatKeyframe::Create(start_time + kShowHideMaxDurationMs,
- client_->ControlsTopOffset() + max_ending_offset,
- EaseTimingFunction::Create()));
+ top_controls_animation_->AddKeyframe(FloatKeyframe::Create(
+ start_time + base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs),
+ client_->ControlsTopOffset() + max_ending_offset,
+ EaseTimingFunction::Create()));
animation_direction_ = direction;
client_->DidChangeTopControlsPosition();
}
@@ -241,8 +240,8 @@
if (!top_controls_animation_)
return true;
- double time_ms = (time - base::TimeTicks()).InMillisecondsF();
- float new_offset = top_controls_animation_->GetValue(time_ms);
+ base::TimeDelta animation_time = time - base::TimeTicks();
+ float new_offset = top_controls_animation_->GetValue(animation_time);
if ((animation_direction_ == SHOWING_CONTROLS && new_offset >= 0) ||
(animation_direction_ == HIDING_CONTROLS
diff --git a/cc/layers/content_layer.cc b/cc/layers/content_layer.cc
index 88031e4..53c7120 100644
--- a/cc/layers/content_layer.cc
+++ b/cc/layers/content_layer.cc
@@ -36,9 +36,7 @@
}
ContentLayer::ContentLayer(ContentLayerClient* client)
- : TiledLayer(),
- client_(client),
- can_use_lcd_text_last_frame_(can_use_lcd_text()) {
+ : TiledLayer(), client_(client) {
}
ContentLayer::~ContentLayer() {}
@@ -74,7 +72,6 @@
true);
CreateUpdaterIfNeeded();
- UpdateCanUseLCDText();
}
bool updated = TiledLayer::Update(queue, occlusion);
@@ -118,15 +115,6 @@
updater_->SetOpaque(opaque);
}
-void ContentLayer::UpdateCanUseLCDText() {
- if (can_use_lcd_text_last_frame_ == can_use_lcd_text())
- return;
-
- can_use_lcd_text_last_frame_ = can_use_lcd_text();
- if (client_)
- client_->DidChangeLayerCanUseLCDText();
-}
-
bool ContentLayer::SupportsLCDText() const {
return true;
}
diff --git a/cc/layers/content_layer.h b/cc/layers/content_layer.h
index fe0bd37..22dd8fd 100644
--- a/cc/layers/content_layer.h
+++ b/cc/layers/content_layer.h
@@ -65,11 +65,8 @@
// TiledLayer implementation.
void CreateUpdaterIfNeeded() override;
- void UpdateCanUseLCDText();
-
ContentLayerClient* client_;
scoped_refptr<ContentLayerUpdater> updater_;
- bool can_use_lcd_text_last_frame_;
DISALLOW_COPY_AND_ASSIGN(ContentLayer);
};
diff --git a/cc/layers/content_layer_client.h b/cc/layers/content_layer_client.h
index 0140513..ea22e97 100644
--- a/cc/layers/content_layer_client.h
+++ b/cc/layers/content_layer_client.h
@@ -27,10 +27,6 @@
const gfx::Rect& clip,
GraphicsContextStatus gc_status) = 0;
- // Called by the content layer during the update phase.
- // If the client paints LCD text, it may want to invalidate the layer.
- virtual void DidChangeLayerCanUseLCDText() = 0;
-
// If true the layer may skip clearing the background before rasterizing,
// because it will cover any uncleared data with content.
virtual bool FillsBoundsCompletely() const = 0;
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc
index 4dfe86a..460726f 100644
--- a/cc/layers/layer_unittest.cc
+++ b/cc/layers/layer_unittest.cc
@@ -1144,8 +1144,9 @@
static bool AddTestAnimation(Layer* layer) {
scoped_ptr<KeyframedFloatAnimationCurve> curve =
KeyframedFloatAnimationCurve::Create();
- curve->AddKeyframe(FloatKeyframe::Create(0.0, 0.3f, nullptr));
- curve->AddKeyframe(FloatKeyframe::Create(1.0, 0.7f, nullptr));
+ curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.3f, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 0.7f, nullptr));
scoped_ptr<Animation> animation =
Animation::Create(curve.Pass(), 0, 0, Animation::Opacity);
diff --git a/cc/layers/picture_image_layer.h b/cc/layers/picture_image_layer.h
index 3575d88..3f8d68d 100644
--- a/cc/layers/picture_image_layer.h
+++ b/cc/layers/picture_image_layer.h
@@ -27,7 +27,6 @@
SkCanvas* canvas,
const gfx::Rect& clip,
ContentLayerClient::GraphicsContextStatus gc_status) override;
- void DidChangeLayerCanUseLCDText() override {}
bool FillsBoundsCompletely() const override;
protected:
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc
index 029e99d..d734538 100644
--- a/cc/layers/picture_layer.cc
+++ b/cc/layers/picture_layer.cc
@@ -23,7 +23,7 @@
recording_source_(new PicturePile),
instrumentation_object_tracker_(id()),
update_source_frame_number_(-1),
- can_use_lcd_text_last_frame_(can_use_lcd_text()),
+ can_use_lcd_text_for_update_(true),
is_mask_(false) {
}
@@ -101,18 +101,14 @@
update_source_frame_number_ = layer_tree_host()->source_frame_number();
bool updated = Layer::Update(queue, occlusion);
- {
- base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
- true);
- UpdateCanUseLCDText();
- }
+ bool can_use_lcd_text_changed = UpdateCanUseLCDText();
gfx::Rect visible_layer_rect = gfx::ScaleToEnclosingRect(
visible_content_rect(), 1.f / contents_scale_x());
gfx::Size layer_size = paint_properties().bounds;
if (last_updated_visible_content_rect_ == visible_content_rect() &&
- recording_source_->GetSize() == layer_size &&
+ recording_source_->GetSize() == layer_size && !can_use_lcd_text_changed &&
pending_invalidation_.IsEmpty()) {
// Only early out if the visible content rect of this layer hasn't changed.
return updated;
@@ -141,8 +137,9 @@
// for them.
DCHECK(client_);
updated |= recording_source_->UpdateAndExpandInvalidation(
- client_, &recording_invalidation_, layer_size, visible_layer_rect,
- update_source_frame_number_, Picture::RECORD_NORMALLY);
+ client_, &recording_invalidation_, can_use_lcd_text_for_update_,
+ layer_size, visible_layer_rect, update_source_frame_number_,
+ Picture::RECORD_NORMALLY);
last_updated_visible_content_rect_ = visible_content_rect();
if (updated) {
@@ -164,13 +161,14 @@
return true;
}
-void PictureLayer::UpdateCanUseLCDText() {
- if (can_use_lcd_text_last_frame_ == can_use_lcd_text())
- return;
+bool PictureLayer::UpdateCanUseLCDText() {
+ if (!can_use_lcd_text_for_update_)
+ return false; // Don't allow the LCD text state to change once disabled.
+ if (can_use_lcd_text_for_update_ == can_use_lcd_text())
+ return false;
- can_use_lcd_text_last_frame_ = can_use_lcd_text();
- if (client_)
- client_->DidChangeLayerCanUseLCDText();
+ can_use_lcd_text_for_update_ = can_use_lcd_text();
+ return true;
}
skia::RefPtr<SkPicture> PictureLayer::GetPicture() const {
diff --git a/cc/layers/picture_layer.h b/cc/layers/picture_layer.h
index e4acb1f..01a37a3 100644
--- a/cc/layers/picture_layer.h
+++ b/cc/layers/picture_layer.h
@@ -50,7 +50,7 @@
~PictureLayer() override;
bool HasDrawableContent() const override;
- void UpdateCanUseLCDText();
+ bool UpdateCanUseLCDText();
private:
ContentLayerClient* client_;
@@ -64,7 +64,7 @@
gfx::Rect last_updated_visible_content_rect_;
int update_source_frame_number_;
- bool can_use_lcd_text_last_frame_;
+ bool can_use_lcd_text_for_update_;
bool is_mask_;
DISALLOW_COPY_AND_ASSIGN(PictureLayer);
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 111a0e7..937aa77 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -645,7 +645,7 @@
// TODO(danakj): Remove this when no longer swapping tilings.
if (!twin_layer->tilings_)
return nullptr;
- return twin_layer->tilings_->TilingAtScale(tiling->contents_scale());
+ return twin_layer->tilings_->FindTilingWithScale(tiling->contents_scale());
}
PictureLayerTiling* PictureLayerImpl::GetRecycledTwinTiling(
@@ -653,7 +653,7 @@
PictureLayerImpl* recycled_twin = GetRecycledTwinLayer();
if (!recycled_twin || !recycled_twin->tilings_)
return nullptr;
- return recycled_twin->tilings_->TilingAtScale(tiling->contents_scale());
+ return recycled_twin->tilings_->FindTilingWithScale(tiling->contents_scale());
}
TilePriority::PriorityBin PictureLayerImpl::GetMaxTilePriorityBin() const {
@@ -889,13 +889,7 @@
if (!tilings_ || tilings_->num_tilings() == 0)
return;
- for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
- PictureLayerTiling* tiling = tilings_->tiling_at(i);
- if (tiling->contents_scale() == contents_scale) {
- tilings_->Remove(tiling);
- break;
- }
- }
+ tilings_->RemoveTilingWithScale(contents_scale);
if (tilings_->num_tilings() == 0)
ResetRasterScale();
SanityCheckTilingState();
@@ -908,44 +902,32 @@
ResetRasterScale();
}
-namespace {
-
-inline float PositiveRatio(float float1, float float2) {
- DCHECK_GT(float1, 0);
- DCHECK_GT(float2, 0);
- return float1 > float2 ? float1 / float2 : float2 / float1;
-}
-
-} // namespace
-
void PictureLayerImpl::AddTilingsForRasterScale() {
- PictureLayerTiling* high_res = nullptr;
- PictureLayerTiling* low_res = nullptr;
+ // Reset all resolution enums on tilings, we'll be setting new values in this
+ // function.
+ tilings_->MarkAllTilingsNonIdeal();
- for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
- PictureLayerTiling* tiling = tilings_->tiling_at(i);
- if (tiling->contents_scale() == raster_contents_scale_)
- high_res = tiling;
- if (tiling->contents_scale() == low_res_raster_contents_scale_)
- low_res = tiling;
-
- // Reset all tilings to non-ideal until the end of this function.
- tiling->set_resolution(NON_IDEAL_RESOLUTION);
- }
-
- if (!high_res) {
+ PictureLayerTiling* high_res =
+ tilings_->FindTilingWithScale(raster_contents_scale_);
+ // We always need a high res tiling, so create one if it doesn't exist.
+ if (!high_res)
high_res = AddTiling(raster_contents_scale_);
- if (raster_contents_scale_ == low_res_raster_contents_scale_)
- low_res = high_res;
- }
+
+ // Try and find a low res tiling.
+ PictureLayerTiling* low_res = nullptr;
+ if (raster_contents_scale_ == low_res_raster_contents_scale_)
+ low_res = high_res;
+ else
+ low_res = tilings_->FindTilingWithScale(low_res_raster_contents_scale_);
// Only create new low res tilings when the transform is static. This
// prevents wastefully creating a paired low res tiling for every new high res
// tiling during a pinch or a CSS animation.
+ bool can_have_low_res = layer_tree_impl()->create_low_res_tiling();
+ bool needs_low_res = !low_res;
bool is_pinching = layer_tree_impl()->PinchGestureActive();
- if (layer_tree_impl()->create_low_res_tiling() && !is_pinching &&
- !draw_properties().screen_space_transform_is_animating && !low_res &&
- low_res != high_res)
+ bool is_animating = draw_properties().screen_space_transform_is_animating;
+ if (can_have_low_res && needs_low_res && !is_pinching && !is_animating)
low_res = AddTiling(low_res_raster_contents_scale_);
// Set low-res if we have one.
@@ -999,21 +981,6 @@
return false;
}
-float PictureLayerImpl::SnappedContentsScale(float scale) {
- // If a tiling exists within the max snapping ratio, snap to its scale.
- float snapped_contents_scale = scale;
- float snapped_ratio = kSnapToExistingTilingRatio;
- for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
- float tiling_contents_scale = tilings_->tiling_at(i)->contents_scale();
- float ratio = PositiveRatio(tiling_contents_scale, scale);
- if (ratio < snapped_ratio) {
- snapped_contents_scale = tiling_contents_scale;
- snapped_ratio = ratio;
- }
- }
- return snapped_contents_scale;
-}
-
void PictureLayerImpl::RecalculateRasterScales() {
float old_raster_contents_scale = raster_contents_scale_;
float old_raster_page_scale = raster_page_scale_;
@@ -1058,7 +1025,8 @@
while (desired_contents_scale < ideal_contents_scale_)
desired_contents_scale *= kMaxScaleRatioDuringPinch;
}
- raster_contents_scale_ = SnappedContentsScale(desired_contents_scale);
+ raster_contents_scale_ = tilings_->GetSnappedContentsScale(
+ desired_contents_scale, kSnapToExistingTilingRatio);
raster_page_scale_ =
raster_contents_scale_ / raster_device_scale_ / raster_source_scale_;
}
@@ -1142,14 +1110,14 @@
// TODO(danakj): Remove the tilings_ check when we create them in the
// constructor.
if (twin->tilings_) {
- for (size_t i = 0; i < twin->tilings_->num_tilings(); ++i) {
- PictureLayerTiling* tiling = twin->tilings_->tiling_at(i);
- if (tiling->resolution() == LOW_RESOLUTION)
- twin_low_res_scale = tiling->contents_scale();
- }
+ PictureLayerTiling* tiling =
+ twin->tilings_->FindTilingWithResolution(LOW_RESOLUTION);
+ if (tiling)
+ twin_low_res_scale = tiling->contents_scale();
}
}
+ // TODO(vmpstr): Put this logic into PictureLayerTilingSet.
std::vector<PictureLayerTiling*> to_remove;
for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
PictureLayerTiling* tiling = tilings_->tiling_at(i);
@@ -1269,12 +1237,8 @@
}
float PictureLayerImpl::MaximumTilingContentsScale() const {
- float max_contents_scale = MinimumContentsScale();
- for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
- const PictureLayerTiling* tiling = tilings_->tiling_at(i);
- max_contents_scale = std::max(max_contents_scale, tiling->contents_scale());
- }
- return max_contents_scale;
+ float max_contents_scale = tilings_->GetMaximumContentsScale();
+ return std::max(max_contents_scale, MinimumContentsScale());
}
void PictureLayerImpl::UpdateIdealScales() {
@@ -1310,9 +1274,7 @@
std::set<const Tile*>* tiles) const {
if (!tilings_)
return;
-
- for (size_t i = 0; i < tilings_->num_tilings(); ++i)
- tilings_->tiling_at(i)->GetAllTilesForTracing(tiles);
+ tilings_->GetAllTilesForTracing(tiles);
}
void PictureLayerImpl::AsValueInto(base::debug::TracedValue* state) const {
@@ -1394,31 +1356,34 @@
gfx::Rect rect = GetViewportForTilePriorityInContentSpace();
rect.Intersect(visible_rect_for_tile_priority_);
- for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
- PictureLayerTiling* tiling = tilings_->tiling_at(i);
- if (tiling->resolution() != HIGH_RESOLUTION &&
- tiling->resolution() != LOW_RESOLUTION)
+ // The high resolution tiling is the only tiling that can mark tiles as
+ // requiring either draw or activation. There is an explicit check in those
+ // callbacks to return false if they are not high resolution tilings. This
+ // check needs to remain since there are other callers of that function that
+ // rely on it. However, for the purposes of this function, we don't have to
+ // check other tilings.
+ PictureLayerTiling* tiling =
+ tilings_->FindTilingWithResolution(HIGH_RESOLUTION);
+ if (!tiling)
+ return true;
+
+ for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter;
+ ++iter) {
+ const Tile* tile = *iter;
+ // A null tile (i.e. missing recording) can just be skipped.
+ // TODO(vmpstr): Verify this is true if we create tiles in raster
+ // iterators.
+ if (!tile)
continue;
- for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter;
- ++iter) {
- const Tile* tile = *iter;
- // A null tile (i.e. missing recording) can just be skipped.
- // TODO(vmpstr): Verify this is true if we create tiles in raster
- // iterators.
- if (!tile)
- continue;
-
- // We can't check tile->required_for_activation, because that value might
- // be out of date. It is updated in the raster/eviction iterators.
- // TODO(vmpstr): Remove the comment once you can't access this information
- // from the tile.
- if ((tiling->*is_tile_required_callback)(tile) &&
- !tile->IsReadyToDraw()) {
- TRACE_EVENT_INSTANT0("cc", "Tile required, but not ready to draw.",
- TRACE_EVENT_SCOPE_THREAD);
- return false;
- }
+ // We can't check tile->required_for_activation, because that value might
+ // be out of date. It is updated in the raster/eviction iterators.
+ // TODO(vmpstr): Remove the comment once you can't access this information
+ // from the tile.
+ if ((tiling->*is_tile_required_callback)(tile) && !tile->IsReadyToDraw()) {
+ TRACE_EVENT_INSTANT0("cc", "Tile required, but not ready to draw.",
+ TRACE_EVENT_SCOPE_THREAD);
+ return false;
}
}
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h
index 78b13fc..12209a8 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -168,7 +168,6 @@
void CleanUpTilingsOnActiveLayer(
std::vector<PictureLayerTiling*> used_tilings);
float MinimumContentsScale() const;
- float SnappedContentsScale(float new_contents_scale);
void ResetRasterScale();
gfx::Rect GetViewportForTilePriorityInContentSpace() const;
PictureLayerImpl* GetRecycledTwinLayer() const;
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 1d7e2ee..931e979 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -2283,9 +2283,9 @@
float new_scale = 1.f;
active_layer_->ReleaseResources();
pending_layer_->ReleaseResources();
- EXPECT_FALSE(active_layer_->tilings()->TilingAtScale(new_scale));
+ EXPECT_FALSE(active_layer_->tilings()->FindTilingWithScale(new_scale));
pending_layer_->AddTiling(new_scale);
- EXPECT_TRUE(active_layer_->tilings()->TilingAtScale(new_scale));
+ EXPECT_TRUE(active_layer_->tilings()->FindTilingWithScale(new_scale));
// UpdateDrawProperties early-outs if the tree doesn't need it. It is also
// responsible for calling ManageTilings. These checks verify that
@@ -2294,7 +2294,7 @@
EXPECT_TRUE(host_impl_.active_tree()->needs_update_draw_properties());
host_impl_.active_tree()->UpdateDrawProperties();
PictureLayerTiling* high_res =
- active_layer_->tilings()->TilingAtScale(new_scale);
+ active_layer_->tilings()->FindTilingWithScale(new_scale);
ASSERT_TRUE(!!high_res);
EXPECT_EQ(HIGH_RESOLUTION, high_res->resolution());
}
@@ -2304,8 +2304,8 @@
const float kScale = 1.f;
pending_layer_->AddTiling(kScale);
- EXPECT_TRUE(pending_layer_->tilings()->TilingAtScale(kScale));
- EXPECT_TRUE(active_layer_->tilings()->TilingAtScale(kScale));
+ EXPECT_TRUE(pending_layer_->tilings()->FindTilingWithScale(kScale));
+ EXPECT_TRUE(active_layer_->tilings()->FindTilingWithScale(kScale));
// Gpu rasterization is disabled by default.
EXPECT_FALSE(host_impl_.use_gpu_rasterization());
@@ -2317,8 +2317,8 @@
// Make sure that we can still add tiling to the pending layer,
// that gets synced to the active layer.
pending_layer_->AddTiling(kScale);
- EXPECT_TRUE(pending_layer_->tilings()->TilingAtScale(kScale));
- EXPECT_TRUE(active_layer_->tilings()->TilingAtScale(kScale));
+ EXPECT_TRUE(pending_layer_->tilings()->FindTilingWithScale(kScale));
+ EXPECT_TRUE(active_layer_->tilings()->FindTilingWithScale(kScale));
// Toggling the gpu rasterization clears all tilings on both trees.
EXPECT_TRUE(host_impl_.use_gpu_rasterization());
@@ -2347,7 +2347,7 @@
// Sanity checks.
ASSERT_EQ(3u, active_layer_->tilings()->num_tilings());
- ASSERT_EQ(tiling, active_layer_->tilings()->TilingAtScale(0.5f));
+ ASSERT_EQ(tiling, active_layer_->tilings()->FindTilingWithScale(0.5f));
// Now, set the bounds to be 1x1 (so that minimum contents scale becomes
// 1.0f). Note that we should also ensure that the pending layer needs post
@@ -2368,12 +2368,12 @@
// violate minimum contents scale. At the same time, we should've created a
// new high res tiling at scale 1.0f.
EXPECT_EQ(2u, pending_layer_->tilings()->num_tilings());
- ASSERT_TRUE(pending_layer_->tilings()->TilingAtScale(1.0f));
+ ASSERT_TRUE(pending_layer_->tilings()->FindTilingWithScale(1.0f));
EXPECT_EQ(HIGH_RESOLUTION,
- pending_layer_->tilings()->TilingAtScale(1.0f)->resolution());
- ASSERT_TRUE(pending_layer_->tilings()->TilingAtScale(1.5f));
+ pending_layer_->tilings()->FindTilingWithScale(1.0f)->resolution());
+ ASSERT_TRUE(pending_layer_->tilings()->FindTilingWithScale(1.5f));
EXPECT_EQ(NON_IDEAL_RESOLUTION,
- pending_layer_->tilings()->TilingAtScale(1.5f)->resolution());
+ pending_layer_->tilings()->FindTilingWithScale(1.5f)->resolution());
}
TEST_F(PictureLayerImplTest, NoLowResTilingWithGpuRasterization) {
@@ -4504,7 +4504,7 @@
Region invalidation(layer_rect);
recording_source->UpdateAndExpandInvalidation(
- &client, &invalidation, layer_bounds, layer_rect, frame_number++,
+ &client, &invalidation, false, layer_bounds, layer_rect, frame_number++,
Picture::RECORD_NORMALLY);
scoped_refptr<RasterSource> pending_raster_source =
@@ -4571,7 +4571,7 @@
Region invalidation1(layer_rect);
recording_source->UpdateAndExpandInvalidation(
- &client, &invalidation1, layer_bounds, layer_rect, frame_number++,
+ &client, &invalidation1, false, layer_bounds, layer_rect, frame_number++,
Picture::RECORD_NORMALLY);
scoped_refptr<RasterSource> raster_source1 =
@@ -4589,7 +4589,7 @@
Region invalidation2(layer_rect);
recording_source->UpdateAndExpandInvalidation(
- &client, &invalidation2, layer_bounds, layer_rect, frame_number++,
+ &client, &invalidation2, false, layer_bounds, layer_rect, frame_number++,
Picture::RECORD_NORMALLY);
scoped_refptr<RasterSource> raster_source2 =
diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc
index 7873b48..3f81ef8 100644
--- a/cc/layers/picture_layer_unittest.cc
+++ b/cc/layers/picture_layer_unittest.cc
@@ -24,7 +24,6 @@
SkCanvas* canvas,
const gfx::Rect& clip,
ContentLayerClient::GraphicsContextStatus gc_status) override {}
- void DidChangeLayerCanUseLCDText() override {}
bool FillsBoundsCompletely() const override { return false; };
};
diff --git a/cc/resources/gpu_raster_worker_pool.cc b/cc/resources/gpu_raster_worker_pool.cc
index c913970..d29855a 100644
--- a/cc/resources/gpu_raster_worker_pool.cc
+++ b/cc/resources/gpu_raster_worker_pool.cc
@@ -41,15 +41,19 @@
bool use_distance_field_text =
use_distance_field_text_ ||
raster_source->ShouldAttemptToUseDistanceFieldText();
- SkSurface* sk_surface = lock_.GetSkSurface(use_distance_field_text);
+ SkSurface* sk_surface = lock_.GetSkSurface(use_distance_field_text,
+ raster_source->CanUseLCDText());
if (!sk_surface)
return;
SkPictureRecorder recorder;
gfx::Size size = resource_->size();
+ const int flags = SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag;
skia::RefPtr<SkCanvas> canvas =
- skia::SharePtr(recorder.beginRecording(size.width(), size.height()));
+ skia::SharePtr(recorder.beginRecording(size.width(), size.height(),
+ NULL, flags));
+
canvas->save();
raster_source->PlaybackToCanvas(canvas.get(), rect, scale);
diff --git a/cc/resources/picture.cc b/cc/resources/picture.cc
index c35da96..9a45ad1 100644
--- a/cc/resources/picture.cc
+++ b/cc/resources/picture.cc
@@ -210,12 +210,14 @@
DCHECK(!picture_);
DCHECK(!tile_grid_info.fTileInterval.isEmpty());
- SkTileGridFactory factory(tile_grid_info);
+ // TODO(mtklein): If SkRTree sticks, clean up tile_grid_info. skbug.com/3085
+ SkRTreeFactory factory;
SkPictureRecorder recorder;
skia::RefPtr<SkCanvas> canvas;
canvas = skia::SharePtr(recorder.beginRecording(
- layer_rect_.width(), layer_rect_.height(), &factory));
+ layer_rect_.width(), layer_rect_.height(), &factory,
+ SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag));
ContentLayerClient::GraphicsContextStatus graphics_context_status =
ContentLayerClient::GRAPHICS_CONTEXT_ENABLED;
diff --git a/cc/resources/picture_layer_tiling_set.cc b/cc/resources/picture_layer_tiling_set.cc
index 060bd27..35170a0 100644
--- a/cc/resources/picture_layer_tiling_set.cc
+++ b/cc/resources/picture_layer_tiling_set.cc
@@ -5,6 +5,7 @@
#include "cc/resources/picture_layer_tiling_set.h"
#include <limits>
+#include <set>
namespace cc {
@@ -17,6 +18,12 @@
}
};
+inline float LargerRatio(float float1, float float2) {
+ DCHECK_GT(float1, 0.f);
+ DCHECK_GT(float2, 0.f);
+ return float1 > float2 ? float1 / float2 : float2 / float1;
+}
+
} // namespace
// static
@@ -43,6 +50,11 @@
tilings_[i]->RemoveTilesInRegion(region);
}
+void PictureLayerTilingSet::MarkAllTilingsNonIdeal() {
+ for (auto* tiling : tilings_)
+ tiling->set_resolution(NON_IDEAL_RESOLUTION);
+}
+
bool PictureLayerTilingSet::SyncTilings(const PictureLayerTilingSet& other,
const gfx::Size& new_layer_bounds,
const Region& layer_invalidation,
@@ -58,7 +70,7 @@
// Remove any tilings that aren't in |other| or don't meet the minimum.
for (size_t i = 0; i < tilings_.size(); ++i) {
float scale = tilings_[i]->contents_scale();
- if (scale >= minimum_contents_scale && !!other.TilingAtScale(scale))
+ if (scale >= minimum_contents_scale && !!other.FindTilingWithScale(scale))
continue;
// Swap with the last element and remove it.
tilings_.swap(tilings_.begin() + i, tilings_.end() - 1);
@@ -73,7 +85,7 @@
float contents_scale = other.tilings_[i]->contents_scale();
if (contents_scale < minimum_contents_scale)
continue;
- if (PictureLayerTiling* this_tiling = TilingAtScale(contents_scale)) {
+ if (PictureLayerTiling* this_tiling = FindTilingWithScale(contents_scale)) {
this_tiling->set_resolution(other.tilings_[i]->resolution());
this_tiling->UpdateTilesToCurrentRasterSource(
@@ -127,7 +139,8 @@
return num_high_res;
}
-PictureLayerTiling* PictureLayerTilingSet::TilingAtScale(float scale) const {
+PictureLayerTiling* PictureLayerTilingSet::FindTilingWithScale(
+ float scale) const {
for (size_t i = 0; i < tilings_.size(); ++i) {
if (tilings_[i]->contents_scale() == scale)
return tilings_[i];
@@ -135,6 +148,17 @@
return NULL;
}
+PictureLayerTiling* PictureLayerTilingSet::FindTilingWithResolution(
+ TileResolution resolution) const {
+ auto iter = std::find_if(tilings_.begin(), tilings_.end(),
+ [resolution](const PictureLayerTiling* tiling) {
+ return tiling->resolution() == resolution;
+ });
+ if (iter == tilings_.end())
+ return NULL;
+ return *iter;
+}
+
void PictureLayerTilingSet::RemoveAllTilings() {
tilings_.clear();
}
@@ -147,11 +171,45 @@
tilings_.erase(iter);
}
+void PictureLayerTilingSet::RemoveTilingWithScale(float scale) {
+ auto iter = std::find_if(tilings_.begin(), tilings_.end(),
+ [scale](const PictureLayerTiling* tiling) {
+ return tiling->contents_scale() == scale;
+ });
+ if (iter == tilings_.end())
+ return;
+ tilings_.erase(iter);
+}
+
void PictureLayerTilingSet::RemoveAllTiles() {
for (size_t i = 0; i < tilings_.size(); ++i)
tilings_[i]->Reset();
}
+float PictureLayerTilingSet::GetSnappedContentsScale(
+ float start_scale,
+ float snap_to_existing_tiling_ratio) const {
+ // If a tiling exists within the max snapping ratio, snap to its scale.
+ float snapped_contents_scale = start_scale;
+ float snapped_ratio = snap_to_existing_tiling_ratio;
+ for (const auto* tiling : tilings_) {
+ float tiling_contents_scale = tiling->contents_scale();
+ float ratio = LargerRatio(tiling_contents_scale, start_scale);
+ if (ratio < snapped_ratio) {
+ snapped_contents_scale = tiling_contents_scale;
+ snapped_ratio = ratio;
+ }
+ }
+ return snapped_contents_scale;
+}
+
+float PictureLayerTilingSet::GetMaximumContentsScale() const {
+ if (tilings_.empty())
+ return 0.f;
+ // The first tiling has the largest contents scale.
+ return tilings_[0]->contents_scale();
+}
+
bool PictureLayerTilingSet::UpdateTilePriorities(
const gfx::Rect& required_rect_in_layer_space,
float ideal_contents_scale,
@@ -181,6 +239,12 @@
return true;
}
+void PictureLayerTilingSet::GetAllTilesForTracing(
+ std::set<const Tile*>* tiles) const {
+ for (auto* tiling : tilings_)
+ tiling->GetAllTilesForTracing(tiles);
+}
+
PictureLayerTilingSet::CoverageIterator::CoverageIterator(
const PictureLayerTilingSet* set,
float contents_scale,
diff --git a/cc/resources/picture_layer_tiling_set.h b/cc/resources/picture_layer_tiling_set.h
index 489bc0c..661dd24 100644
--- a/cc/resources/picture_layer_tiling_set.h
+++ b/cc/resources/picture_layer_tiling_set.h
@@ -5,6 +5,8 @@
#ifndef CC_RESOURCES_PICTURE_LAYER_TILING_SET_H_
#define CC_RESOURCES_PICTURE_LAYER_TILING_SET_H_
+#include <set>
+
#include "cc/base/region.h"
#include "cc/base/scoped_ptr_vector.h"
#include "cc/resources/picture_layer_tiling.h"
@@ -64,13 +66,28 @@
return tilings_[idx];
}
- PictureLayerTiling* TilingAtScale(float scale) const;
+ PictureLayerTiling* FindTilingWithScale(float scale) const;
+ PictureLayerTiling* FindTilingWithResolution(TileResolution resolution) const;
+
+ void MarkAllTilingsNonIdeal();
+
+ // If a tiling exists whose scale is within |snap_to_existing_tiling_ratio|
+ // ratio of |start_scale|, then return that tiling's scale. Otherwise, return
+ // |start_scale|. If multiple tilings match the criteria, return the one with
+ // the least ratio to |start_scale|.
+ float GetSnappedContentsScale(float start_scale,
+ float snap_to_existing_tiling_ratio) const;
+
+ // Returns the maximum contents scale of all tilings, or 0 if no tilings
+ // exist.
+ float GetMaximumContentsScale() const;
// Remove all tilings.
void RemoveAllTilings();
// Remove one tiling.
void Remove(PictureLayerTiling* tiling);
+ void RemoveTilingWithScale(float scale);
// Remove all tiles; keep all tilings.
void RemoveAllTiles();
@@ -82,6 +99,8 @@
const Occlusion& occlusion_in_layer_space,
bool can_require_tiles_for_activation);
+ void GetAllTilesForTracing(std::set<const Tile*>* tiles) const;
+
// For a given rect, iterates through tiles that can fill it. If no
// set of tiles with resources can fill the rect, then it will iterate
// through null tiles with valid geometry_rect() until the rect is full.
diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc
index 2a215a8..7acc55b 100644
--- a/cc/resources/picture_layer_tiling_set_unittest.cc
+++ b/cc/resources/picture_layer_tiling_set_unittest.cc
@@ -430,14 +430,14 @@
for (size_t i = 0; i < arraysize(target_scales); ++i)
target_->AddTiling(target_scales[i], target_bounds_);
- PictureLayerTiling* tiling1 = source_->TilingAtScale(1.f);
+ PictureLayerTiling* tiling1 = source_->FindTilingWithScale(1.f);
ASSERT_TRUE(tiling1);
tiling1->CreateAllTilesForTesting();
EXPECT_EQ(tiling1->contents_scale(), 1.f);
Tile* tile1 = FindTileAtOrigin(tiling1);
ASSERT_TRUE(tile1);
- PictureLayerTiling* tiling2 = source_->TilingAtScale(2.f);
+ PictureLayerTiling* tiling2 = source_->FindTilingWithScale(2.f);
tiling2->CreateAllTilesForTesting();
ASSERT_TRUE(tiling2);
EXPECT_EQ(tiling2->contents_scale(), 2.f);
@@ -448,11 +448,11 @@
SyncTilings(new_bounds);
VerifyTargetEqualsSource(new_bounds);
- EXPECT_EQ(tiling1, source_->TilingAtScale(1.f));
+ EXPECT_EQ(tiling1, source_->FindTilingWithScale(1.f));
EXPECT_EQ(tile1, FindTileAtOrigin(tiling1));
EXPECT_FALSE(tiling1->live_tiles_rect().IsEmpty());
- EXPECT_EQ(tiling2, source_->TilingAtScale(2.f));
+ EXPECT_EQ(tiling2, source_->FindTilingWithScale(2.f));
EXPECT_EQ(tile2, FindTileAtOrigin(tiling2));
EXPECT_FALSE(tiling2->live_tiles_rect().IsEmpty());
}
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc
index eed12ea..97cd127 100644
--- a/cc/resources/picture_pile.cc
+++ b/cc/resources/picture_pile.cc
@@ -164,6 +164,7 @@
PicturePile::PicturePile()
: min_contents_scale_(0),
slow_down_raster_scale_factor_for_debug_(0),
+ can_use_lcd_text_(true),
has_any_recordings_(false),
is_solid_color_(false),
solid_color_(SK_ColorTRANSPARENT),
@@ -181,18 +182,30 @@
bool PicturePile::UpdateAndExpandInvalidation(
ContentLayerClient* painter,
Region* invalidation,
+ bool can_use_lcd_text,
const gfx::Size& layer_size,
const gfx::Rect& visible_layer_rect,
int frame_number,
Picture::RecordingMode recording_mode) {
+ bool can_use_lcd_text_changed = can_use_lcd_text_ != can_use_lcd_text;
+ can_use_lcd_text_ = can_use_lcd_text;
+
bool updated = false;
- Region resize_invalidation;
+ Region synthetic_invalidation;
gfx::Size old_tiling_size = GetSize();
if (old_tiling_size != layer_size) {
tiling_.SetTilingSize(layer_size);
updated = true;
}
+ if (can_use_lcd_text_changed) {
+ // When LCD text is enabled/disabled, we must drop any raster tiles for
+ // the pile, so they can be recreated in a manner consistent with the new
+ // setting. We do this with |synthetic_invalidation| since we don't need to
+ // do a new recording, just invalidate rastered content.
+ synthetic_invalidation.Union(gfx::Rect(GetSize()));
+ updated = true;
+ }
gfx::Rect interest_rect = visible_layer_rect;
interest_rect.Inset(-pixel_record_distance_, -pixel_record_distance_);
@@ -356,11 +369,11 @@
exposed_top,
exposed_left_until - exposed_left,
exposed_bottom - exposed_top);
- resize_invalidation.Union(left_rect);
- resize_invalidation.Union(right_rect);
- resize_invalidation.Union(top_rect);
- resize_invalidation.Union(bottom_rect);
- resize_invalidation.Union(exposed_rect);
+ synthetic_invalidation.Union(left_rect);
+ synthetic_invalidation.Union(right_rect);
+ synthetic_invalidation.Union(top_rect);
+ synthetic_invalidation.Union(bottom_rect);
+ synthetic_invalidation.Union(exposed_rect);
}
if (min_toss_y < tiling_.num_tiles_y()) {
// The same thing occurs here as in the case above, but the invalidation
@@ -392,11 +405,11 @@
exposed_top,
exposed_right - exposed_left,
exposed_top_until - exposed_top);
- resize_invalidation.Union(left_rect);
- resize_invalidation.Union(right_rect);
- resize_invalidation.Union(top_rect);
- resize_invalidation.Union(bottom_rect);
- resize_invalidation.Union(exposed_rect);
+ synthetic_invalidation.Union(left_rect);
+ synthetic_invalidation.Union(right_rect);
+ synthetic_invalidation.Union(top_rect);
+ synthetic_invalidation.Union(bottom_rect);
+ synthetic_invalidation.Union(exposed_rect);
}
}
@@ -458,7 +471,7 @@
invalidation->Union(invalidation_expanded_to_full_tiles);
}
- invalidation->Union(resize_invalidation);
+ invalidation->Union(synthetic_invalidation);
// Make a list of all invalid tiles; we will attempt to
// cluster these into multiple invalidation regions.
diff --git a/cc/resources/picture_pile.h b/cc/resources/picture_pile.h
index e252e97..e1c1b46 100644
--- a/cc/resources/picture_pile.h
+++ b/cc/resources/picture_pile.h
@@ -25,6 +25,7 @@
bool UpdateAndExpandInvalidation(
ContentLayerClient* painter,
Region* invalidation,
+ bool can_use_lcd_text,
const gfx::Size& layer_size,
const gfx::Rect& visible_layer_rect,
int frame_number,
@@ -94,6 +95,7 @@
float min_contents_scale_;
SkTileGridFactory::TileGridInfo tile_grid_info_;
int slow_down_raster_scale_factor_for_debug_;
+ bool can_use_lcd_text_;
// A hint about whether there are any recordings. This may be a false
// positive.
bool has_any_recordings_;
diff --git a/cc/resources/picture_pile_impl.cc b/cc/resources/picture_pile_impl.cc
index 7416538..2655d24 100644
--- a/cc/resources/picture_pile_impl.cc
+++ b/cc/resources/picture_pile_impl.cc
@@ -38,6 +38,7 @@
PicturePileImpl::PicturePileImpl()
: background_color_(SK_ColorTRANSPARENT),
requires_clear_(true),
+ can_use_lcd_text_(false),
is_solid_color_(false),
solid_color_(SK_ColorTRANSPARENT),
has_any_recordings_(false),
@@ -52,6 +53,7 @@
tiling_(other->tiling_),
background_color_(SK_ColorTRANSPARENT),
requires_clear_(true),
+ can_use_lcd_text_(other->can_use_lcd_text_),
is_solid_color_(other->is_solid_color_),
solid_color_(other->solid_color_),
recorded_viewport_(other->recorded_viewport_),
@@ -437,6 +439,10 @@
}
}
+bool PicturePileImpl::CanUseLCDText() const {
+ return can_use_lcd_text_;
+}
+
PicturePileImpl::PixelRefIterator::PixelRefIterator(
const gfx::Rect& content_rect,
float contents_scale,
diff --git a/cc/resources/picture_pile_impl.h b/cc/resources/picture_pile_impl.h
index b4209e3..d7d0399 100644
--- a/cc/resources/picture_pile_impl.h
+++ b/cc/resources/picture_pile_impl.h
@@ -61,6 +61,7 @@
bool IsSolidColor() const override;
SkColor GetSolidColor() const override;
bool HasRecordings() const override;
+ bool CanUseLCDText() const override;
// Tracing functionality.
void DidBeginTracing() override;
@@ -110,6 +111,7 @@
TilingData tiling_;
SkColor background_color_;
bool requires_clear_;
+ bool can_use_lcd_text_;
bool is_solid_color_;
SkColor solid_color_;
gfx::Rect recorded_viewport_;
diff --git a/cc/resources/picture_pile_unittest.cc b/cc/resources/picture_pile_unittest.cc
index 0a9a907..98ce3b1 100644
--- a/cc/resources/picture_pile_unittest.cc
+++ b/cc/resources/picture_pile_unittest.cc
@@ -39,9 +39,9 @@
const gfx::Size& layer_size,
const gfx::Rect& visible_layer_rect) {
frame_number_++;
- return pile_.UpdateAndExpandInvalidation(&client_, invalidation, layer_size,
- visible_layer_rect, frame_number_,
- Picture::RECORD_NORMALLY);
+ return pile_.UpdateAndExpandInvalidation(
+ &client_, invalidation, false, layer_size, visible_layer_rect,
+ frame_number_, Picture::RECORD_NORMALLY);
}
bool UpdateWholePile() {
diff --git a/cc/resources/raster_source.h b/cc/resources/raster_source.h
index 5f200db..3584436 100644
--- a/cc/resources/raster_source.h
+++ b/cc/resources/raster_source.h
@@ -93,6 +93,9 @@
virtual void AsValueInto(base::debug::TracedValue* array) const = 0;
virtual skia::RefPtr<SkPicture> GetFlattenedPicture() = 0;
+ // Return true if LCD anti-aliasing may be used when rastering text.
+ virtual bool CanUseLCDText() const = 0;
+
protected:
friend class base::RefCountedThreadSafe<RasterSource>;
diff --git a/cc/resources/raster_worker_pool.cc b/cc/resources/raster_worker_pool.cc
index ca26edd..4511f9d 100644
--- a/cc/resources/raster_worker_pool.cc
+++ b/cc/resources/raster_worker_pool.cc
@@ -228,28 +228,26 @@
SkColorType buffer_color_type = ResourceFormatToSkColorType(format);
bool needs_copy = buffer_color_type != info.colorType();
- // TODO(danakj): Make a SkSurfaceProps with an SkPixelGeometry to enable or
- // disable LCD text.
- // TODO(danakj): Disable LCD text on Mac during layout tests:
- // https://cs.chromium.org#chromium/src/third_party/WebKit/Source/platform/fonts/mac/FontPlatformDataMac.mm&l=55
- // TODO(danakj): On Windows when LCD text is disabled, ask skia to draw LCD
- // text offscreen and downsample it to AA text.
- // https://cs.chromium.org#chromium/src/third_party/WebKit/Source/platform/fonts/win/FontPlatformDataWin.cpp&l=86
- SkSurfaceProps* surface_props = nullptr;
+ // Use unknown pixel geometry to disable LCD text.
+ SkSurfaceProps surface_props(0, kUnknown_SkPixelGeometry);
+ if (raster_source->CanUseLCDText()) {
+ // LegacyFontHost will get LCD text and skia figures out what type to use.
+ surface_props = SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);
+ }
if (!stride)
stride = info.minRowBytes();
if (!needs_copy) {
skia::RefPtr<SkSurface> surface = skia::AdoptRef(
- SkSurface::NewRasterDirect(info, memory, stride, surface_props));
+ SkSurface::NewRasterDirect(info, memory, stride, &surface_props));
skia::RefPtr<SkCanvas> canvas = skia::SharePtr(surface->getCanvas());
raster_source->PlaybackToCanvas(canvas.get(), rect, scale);
return;
}
skia::RefPtr<SkSurface> surface =
- skia::AdoptRef(SkSurface::NewRaster(info, surface_props));
+ skia::AdoptRef(SkSurface::NewRaster(info, &surface_props));
skia::RefPtr<SkCanvas> canvas = skia::SharePtr(surface->getCanvas());
raster_source->PlaybackToCanvas(canvas.get(), rect, scale);
diff --git a/cc/resources/recording_source.h b/cc/resources/recording_source.h
index 19eea72..173e1a0 100644
--- a/cc/resources/recording_source.h
+++ b/cc/resources/recording_source.h
@@ -28,6 +28,7 @@
virtual bool UpdateAndExpandInvalidation(
ContentLayerClient* painter,
Region* invalidation,
+ bool can_use_lcd_text,
const gfx::Size& layer_size,
const gfx::Rect& visible_layer_rect,
int frame_number,
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index 2518972..06bb5f0 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -1112,15 +1112,15 @@
}
SkSurface* ResourceProvider::ScopedWriteLockGr::GetSkSurface(
- bool use_distance_field_text) {
+ bool use_distance_field_text,
+ bool can_use_lcd_text) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(resource_->locked_for_write);
- // If the surface doesn't exist, or doesn't have the correct dff setting,
- // recreate the surface within the resource.
- if (!resource_->sk_surface ||
- use_distance_field_text !=
- resource_->sk_surface->props().isUseDistanceFieldFonts()) {
+ bool create_surface =
+ !resource_->sk_surface.get() ||
+ !SurfaceHasMatchingProperties(use_distance_field_text, can_use_lcd_text);
+ if (create_surface) {
class GrContext* gr_context = resource_provider_->GrContext();
// TODO(alokp): Implement TestContextProvider::GrContext().
if (!gr_context)
@@ -1139,15 +1139,34 @@
skia::AdoptRef(gr_context->wrapBackendTexture(desc));
if (!gr_texture)
return nullptr;
- SkSurface::TextRenderMode text_render_mode =
- use_distance_field_text ? SkSurface::kDistanceField_TextRenderMode
- : SkSurface::kStandard_TextRenderMode;
+ uint32_t flags = use_distance_field_text
+ ? SkSurfaceProps::kUseDistanceFieldFonts_Flag
+ : 0;
+ // Use unknown pixel geometry to disable LCD text.
+ SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry);
+ if (can_use_lcd_text) {
+ // LegacyFontHost will get LCD text and skia figures out what type to use.
+ surface_props =
+ SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType);
+ }
resource_->sk_surface = skia::AdoptRef(SkSurface::NewRenderTargetDirect(
- gr_texture->asRenderTarget(), text_render_mode));
+ gr_texture->asRenderTarget(), &surface_props));
}
return resource_->sk_surface.get();
}
+bool ResourceProvider::ScopedWriteLockGr::SurfaceHasMatchingProperties(
+ bool use_distance_field_text,
+ bool can_use_lcd_text) const {
+ const SkSurface* surface = resource_->sk_surface.get();
+ bool surface_uses_distance_field_text =
+ surface->props().isUseDistanceFieldFonts();
+ bool surface_can_use_lcd_text =
+ surface->props().pixelGeometry() != kUnknown_SkPixelGeometry;
+ return use_distance_field_text == surface_uses_distance_field_text &&
+ can_use_lcd_text == surface_can_use_lcd_text;
+}
+
ResourceProvider::SynchronousFence::SynchronousFence(
gpu::gles2::GLES2Interface* gl)
: gl_(gl), has_synchronized_(true) {
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h
index 40103f6..c2f349f 100644
--- a/cc/resources/resource_provider.h
+++ b/cc/resources/resource_provider.h
@@ -335,9 +335,13 @@
ResourceProvider::ResourceId resource_id);
~ScopedWriteLockGr();
- SkSurface* GetSkSurface(bool use_distance_field_text);
+ SkSurface* GetSkSurface(bool use_distance_field_text,
+ bool can_use_lcd_text);
private:
+ bool SurfaceHasMatchingProperties(bool use_distance_field_text,
+ bool can_use_lcd_text) const;
+
ResourceProvider* resource_provider_;
ResourceProvider::Resource* resource_;
base::ThreadChecker thread_checker_;
diff --git a/cc/test/animation_test_common.cc b/cc/test/animation_test_common.cc
index fba3166..602374f 100644
--- a/cc/test/animation_test_common.cc
+++ b/cc/test/animation_test_common.cc
@@ -8,6 +8,7 @@
#include "cc/animation/keyframed_animation_curve.h"
#include "cc/animation/layer_animation_controller.h"
#include "cc/animation/transform_operations.h"
+#include "cc/base/time_util.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
@@ -35,8 +36,10 @@
if (!use_timing_function)
func = EaseTimingFunction::Create();
if (duration > 0.0)
- curve->AddKeyframe(FloatKeyframe::Create(0.0, start_opacity, func.Pass()));
- curve->AddKeyframe(FloatKeyframe::Create(duration, end_opacity, nullptr));
+ curve->AddKeyframe(
+ FloatKeyframe::Create(base::TimeDelta(), start_opacity, func.Pass()));
+ curve->AddKeyframe(FloatKeyframe::Create(
+ base::TimeDelta::FromSecondsD(duration), end_opacity, nullptr));
int id = AnimationIdProvider::NextAnimationId();
@@ -60,11 +63,12 @@
curve(KeyframedTransformAnimationCurve::Create());
if (duration > 0.0) {
- curve->AddKeyframe(
- TransformKeyframe::Create(0.0, start_operations, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(base::TimeDelta(),
+ start_operations, nullptr));
}
- curve->AddKeyframe(TransformKeyframe::Create(duration, operations, nullptr));
+ curve->AddKeyframe(TransformKeyframe::Create(
+ base::TimeDelta::FromSecondsD(duration), operations, nullptr));
int id = AnimationIdProvider::NextAnimationId();
@@ -106,12 +110,14 @@
FilterOperations start_filters;
start_filters.Append(
FilterOperation::CreateBrightnessFilter(start_brightness));
- curve->AddKeyframe(FilterKeyframe::Create(0.0, start_filters, nullptr));
+ curve->AddKeyframe(
+ FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr));
}
FilterOperations filters;
filters.Append(FilterOperation::CreateBrightnessFilter(end_brightness));
- curve->AddKeyframe(FilterKeyframe::Create(duration, filters, nullptr));
+ curve->AddKeyframe(FilterKeyframe::Create(
+ base::TimeDelta::FromSecondsD(duration), filters, nullptr));
int id = AnimationIdProvider::NextAnimationId();
@@ -137,7 +143,7 @@
return duration_;
}
-float FakeFloatAnimationCurve::GetValue(double now) const {
+float FakeFloatAnimationCurve::GetValue(base::TimeDelta now) const {
return 0.0f;
}
@@ -155,7 +161,7 @@
return duration_;
}
-gfx::Transform FakeTransformTransition::GetValue(double time) const {
+gfx::Transform FakeTransformTransition::GetValue(base::TimeDelta time) const {
return gfx::Transform();
}
@@ -188,11 +194,11 @@
return duration_;
}
-float FakeFloatTransition::GetValue(double time) const {
- time /= duration_.InSecondsF();
- if (time >= 1.0)
- time = 1.0;
- return (1.0 - time) * from_ + time * to_;
+float FakeFloatTransition::GetValue(base::TimeDelta time) const {
+ double progress = TimeUtil::Divide(time, duration_);
+ if (progress >= 1.0)
+ progress = 1.0;
+ return (1.0 - progress) * from_ + progress * to_;
}
FakeLayerAnimationValueObserver::FakeLayerAnimationValueObserver()
diff --git a/cc/test/animation_test_common.h b/cc/test/animation_test_common.h
index a69f0c9..2c41518 100644
--- a/cc/test/animation_test_common.h
+++ b/cc/test/animation_test_common.h
@@ -27,7 +27,7 @@
~FakeFloatAnimationCurve() override;
base::TimeDelta Duration() const override;
- float GetValue(double now) const override;
+ float GetValue(base::TimeDelta now) const override;
scoped_ptr<AnimationCurve> Clone() const override;
private:
@@ -40,7 +40,7 @@
~FakeTransformTransition() override;
base::TimeDelta Duration() const override;
- gfx::Transform GetValue(double time) const override;
+ gfx::Transform GetValue(base::TimeDelta time) const override;
bool AnimatedBoundsForBox(const gfx::BoxF& box,
gfx::BoxF* bounds) const override;
bool AffectsScale() const override;
@@ -60,7 +60,7 @@
~FakeFloatTransition() override;
base::TimeDelta Duration() const override;
- float GetValue(double time) const override;
+ float GetValue(base::TimeDelta time) const override;
scoped_ptr<AnimationCurve> Clone() const override;
diff --git a/cc/test/fake_content_layer_client.h b/cc/test/fake_content_layer_client.h
index 7a7cc44..141bc97 100644
--- a/cc/test/fake_content_layer_client.h
+++ b/cc/test/fake_content_layer_client.h
@@ -31,7 +31,6 @@
SkCanvas* canvas,
const gfx::Rect& rect,
ContentLayerClient::GraphicsContextStatus gc_status) override;
- void DidChangeLayerCanUseLCDText() override {}
bool FillsBoundsCompletely() const override;
void set_fill_with_nonsolid_color(bool nonsolid) {
diff --git a/cc/test/fake_picture_layer.cc b/cc/test/fake_picture_layer.cc
index 1a19bc7..a475667 100644
--- a/cc/test/fake_picture_layer.cc
+++ b/cc/test/fake_picture_layer.cc
@@ -13,7 +13,8 @@
update_count_(0),
push_properties_count_(0),
output_surface_created_count_(0),
- always_update_resources_(false) {
+ always_update_resources_(false),
+ disable_lcd_text_(false) {
SetBounds(gfx::Size(1, 1));
SetIsDrawable(true);
}
@@ -38,6 +39,8 @@
bool FakePictureLayer::Update(ResourceUpdateQueue* queue,
const OcclusionTracker<Layer>* occlusion) {
+ if (disable_lcd_text_)
+ draw_properties().can_use_lcd_text = false;
bool updated = PictureLayer::Update(queue, occlusion);
update_count_++;
return updated || always_update_resources_;
diff --git a/cc/test/fake_picture_layer.h b/cc/test/fake_picture_layer.h
index f42a14d..d101155 100644
--- a/cc/test/fake_picture_layer.h
+++ b/cc/test/fake_picture_layer.h
@@ -35,6 +35,8 @@
always_update_resources_ = always_update_resources;
}
+ void disable_lcd_text() { disable_lcd_text_ = true; }
+
bool Update(ResourceUpdateQueue* queue,
const OcclusionTracker<Layer>* occlusion) override;
@@ -55,6 +57,7 @@
size_t push_properties_count_;
size_t output_surface_created_count_;
bool always_update_resources_;
+ bool disable_lcd_text_;
};
} // namespace cc
diff --git a/cc/test/geometry_test_utils.h b/cc/test/geometry_test_utils.h
index d8829e0..b743f58 100644
--- a/cc/test/geometry_test_utils.h
+++ b/cc/test/geometry_test_utils.h
@@ -68,6 +68,12 @@
EXPECT_FLOAT_EQ((expected).y(), (actual).y()); \
} while (false)
+#define EXPECT_VECTOR2DF_NEAR(expected, actual, abs_error) \
+ do { \
+ EXPECT_NEAR((expected).x(), (actual).x(), (abs_error)); \
+ EXPECT_NEAR((expected).y(), (actual).y(), (abs_error)); \
+ } while (false)
+
#define EXPECT_FLOAT_ARRAY_EQ(expected, actual, count) \
do { \
for (int i = 0; i < count; i++) { \
diff --git a/cc/test/layer_tree_host_common_test.cc b/cc/test/layer_tree_host_common_test.cc
index 33e0caf..8441657 100644
--- a/cc/test/layer_tree_host_common_test.cc
+++ b/cc/test/layer_tree_host_common_test.cc
@@ -59,7 +59,8 @@
float device_scale_factor,
float page_scale_factor,
Layer* page_scale_application_layer,
- bool can_use_lcd_text) {
+ bool can_use_lcd_text,
+ bool layers_always_allowed_lcd_text) {
EXPECT_TRUE(page_scale_application_layer || (page_scale_factor == 1.f));
gfx::Transform identity_matrix;
gfx::Size device_viewport_size =
@@ -77,6 +78,7 @@
inputs.page_scale_factor = page_scale_factor;
inputs.page_scale_application_layer = page_scale_application_layer;
inputs.can_use_lcd_text = can_use_lcd_text;
+ inputs.layers_always_allowed_lcd_text = layers_always_allowed_lcd_text;
inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
}
@@ -86,7 +88,8 @@
float device_scale_factor,
float page_scale_factor,
LayerImpl* page_scale_application_layer,
- bool can_use_lcd_text) {
+ bool can_use_lcd_text,
+ bool layers_always_allowed_lcd_text) {
gfx::Transform identity_matrix;
gfx::Size device_viewport_size =
gfx::Size(root_layer->bounds().width() * device_scale_factor,
@@ -103,6 +106,7 @@
inputs.page_scale_factor = page_scale_factor;
inputs.page_scale_application_layer = page_scale_application_layer;
inputs.can_use_lcd_text = can_use_lcd_text;
+ inputs.layers_always_allowed_lcd_text = layers_always_allowed_lcd_text;
inputs.can_adjust_raster_scales = true;
++render_surface_layer_list_count_;
diff --git a/cc/test/layer_tree_host_common_test.h b/cc/test/layer_tree_host_common_test.h
index 38b57d4..456183f 100644
--- a/cc/test/layer_tree_host_common_test.h
+++ b/cc/test/layer_tree_host_common_test.h
@@ -68,30 +68,29 @@
float device_scale_factor,
float page_scale_factor,
Layer* page_scale_application_layer,
- bool can_use_lcd_text);
+ bool can_use_lcd_text,
+ bool layers_always_allowed_lcd_text);
void ExecuteCalculateDrawProperties(LayerImpl* root_layer,
float device_scale_factor,
float page_scale_factor,
LayerImpl* page_scale_application_layer,
- bool can_use_lcd_text);
+ bool can_use_lcd_text,
+ bool layers_always_allowed_lcd_text);
template <class LayerType>
void ExecuteCalculateDrawProperties(LayerType* root_layer) {
LayerType* page_scale_application_layer = NULL;
- ExecuteCalculateDrawProperties(
- root_layer, 1.f, 1.f, page_scale_application_layer, false);
+ ExecuteCalculateDrawProperties(root_layer, 1.f, 1.f,
+ page_scale_application_layer, false, false);
}
template <class LayerType>
void ExecuteCalculateDrawProperties(LayerType* root_layer,
float device_scale_factor) {
LayerType* page_scale_application_layer = NULL;
- ExecuteCalculateDrawProperties(root_layer,
- device_scale_factor,
- 1.f,
- page_scale_application_layer,
- false);
+ ExecuteCalculateDrawProperties(root_layer, device_scale_factor, 1.f,
+ page_scale_application_layer, false, false);
}
template <class LayerType>
@@ -99,11 +98,9 @@
float device_scale_factor,
float page_scale_factor,
LayerType* page_scale_application_layer) {
- ExecuteCalculateDrawProperties(root_layer,
- device_scale_factor,
+ ExecuteCalculateDrawProperties(root_layer, device_scale_factor,
page_scale_factor,
- page_scale_application_layer,
- false);
+ page_scale_application_layer, false, false);
}
RenderSurfaceLayerList* render_surface_layer_list() const {
diff --git a/cc/test/layer_tree_pixel_resource_test.cc b/cc/test/layer_tree_pixel_resource_test.cc
index fa2bbb8..4542d2a 100644
--- a/cc/test/layer_tree_pixel_resource_test.cc
+++ b/cc/test/layer_tree_pixel_resource_test.cc
@@ -25,14 +25,14 @@
case GL_GPU_RASTER_2D_DRAW:
case GL_ZERO_COPY_2D_DRAW:
case GL_ZERO_COPY_RECT_DRAW:
+ case GL_ONE_COPY_2D_STAGING_2D_DRAW:
case GL_ASYNC_UPLOAD_2D_DRAW:
return true;
case GL_ZERO_COPY_EXTERNAL_DRAW:
- case GL_ONE_COPY_2D_STAGING_2D_DRAW:
case GL_ONE_COPY_RECT_STAGING_2D_DRAW:
case GL_ONE_COPY_EXTERNAL_STAGING_2D_DRAW:
// These should all be enabled in practice.
- // TODO(reveman): one copy not supported in unit tests yet.
+ // TODO(reveman): one copy with rect not supported in unit tests yet.
// TODO(enne): look into getting texture external oes enabled.
return false;
}
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc
index ef0ba22..23bfcf2 100644
--- a/cc/test/layer_tree_pixel_test.cc
+++ b/cc/test/layer_tree_pixel_test.cc
@@ -107,7 +107,7 @@
EXPECT_TRUE(PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir));
base::FilePath ref_file_path = test_data_dir.Append(ref_file_);
- CommandLine* cmd = CommandLine::ForCurrentProcess();
+ base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
if (cmd->HasSwitch(switches::kCCRebaselinePixeltests))
EXPECT_TRUE(WritePNGFile(*result_bitmap_, ref_file_path, true));
EXPECT_TRUE(MatchesPNGFile(*result_bitmap_,
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 89cc554..a22c7af 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -490,7 +490,7 @@
// Tests should timeout quickly unless --cc-layer-tree-test-no-timeout was
// specified (for running in a debugger).
- CommandLine* command_line = CommandLine::ForCurrentProcess();
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(switches::kCCLayerTreeTestNoTimeout))
timeout_seconds_ = 5;
}
@@ -524,10 +524,8 @@
Layer* layer_to_receive_animation) {
main_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeTest::DispatchAddAnimation,
- main_thread_weak_ptr_,
- base::Unretained(layer_to_receive_animation),
- 0.000001));
+ base::Bind(&LayerTreeTest::DispatchAddAnimation, main_thread_weak_ptr_,
+ base::Unretained(layer_to_receive_animation), 0.000004));
}
void LayerTreeTest::PostAddInstantAnimationToMainThread(
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index 3a9b45b..28c0dc0 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -114,7 +114,7 @@
if (!result_bitmap_)
return false;
- CommandLine* cmd = CommandLine::ForCurrentProcess();
+ base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
if (cmd->HasSwitch(switches::kCCRebaselinePixeltests))
return WritePNGFile(*result_bitmap_, test_data_dir.Append(ref_file), true);
diff --git a/cc/test/solid_color_content_layer_client.h b/cc/test/solid_color_content_layer_client.h
index a851b72..7a962cf 100644
--- a/cc/test/solid_color_content_layer_client.h
+++ b/cc/test/solid_color_content_layer_client.h
@@ -16,7 +16,6 @@
explicit SolidColorContentLayerClient(SkColor color) : color_(color) {}
// ContentLayerClient implementation.
- void DidChangeLayerCanUseLCDText() override {}
void PaintContents(
SkCanvas* canvas,
const gfx::Rect& rect,
diff --git a/cc/test/test_in_process_context_provider.cc b/cc/test/test_in_process_context_provider.cc
index 34b0493..847bc92 100644
--- a/cc/test/test_in_process_context_provider.cc
+++ b/cc/test/test_in_process_context_provider.cc
@@ -129,6 +129,7 @@
ContextProvider::Capabilities capabilities;
capabilities.gpu.image = true;
capabilities.gpu.texture_rectangle = true;
+ capabilities.gpu.sync_query = true;
return capabilities;
}
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index f85d4e7..808bf21 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -845,17 +845,12 @@
// Change this if this information is required.
int render_surface_layer_list_id = 0;
LayerTreeHostCommon::CalcDrawPropsMainInputs inputs(
- root_layer,
- device_viewport_size(),
- gfx::Transform(),
- device_scale_factor_,
- page_scale_factor_,
- page_scale_layer,
- GetRendererCapabilities().max_texture_size,
- settings_.can_use_lcd_text,
+ root_layer, device_viewport_size(), gfx::Transform(),
+ device_scale_factor_, page_scale_factor_, page_scale_layer,
+ GetRendererCapabilities().max_texture_size, settings_.can_use_lcd_text,
+ settings_.layers_always_allowed_lcd_text,
can_render_to_separate_surface,
- settings_.layer_transforms_should_scale_layer_contents,
- &update_list,
+ settings_.layer_transforms_should_scale_layer_contents, &update_list,
render_surface_layer_list_id);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index 0ff6608..6863850 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -1269,6 +1269,7 @@
const LayerType* page_scale_application_layer;
bool can_adjust_raster_scales;
bool can_render_to_separate_surface;
+ bool layers_always_allowed_lcd_text;
};
template<typename LayerType>
@@ -1791,13 +1792,19 @@
// causes jank.
bool adjust_text_aa =
!animating_opacity_to_screen && !animating_transform_to_screen;
- // To avoid color fringing, LCD text should only be used on opaque layers with
- // just integral translation.
- bool layer_can_use_lcd_text =
- data_from_ancestor.subtree_can_use_lcd_text &&
- accumulated_draw_opacity == 1.f &&
- layer_draw_properties.target_space_transform.
- IsIdentityOrIntegerTranslation();
+ bool layer_can_use_lcd_text = true;
+ bool subtree_can_use_lcd_text = true;
+ if (!globals.layers_always_allowed_lcd_text) {
+ // To avoid color fringing, LCD text should only be used on opaque layers
+ // with just integral translation.
+ subtree_can_use_lcd_text = data_from_ancestor.subtree_can_use_lcd_text &&
+ accumulated_draw_opacity == 1.f &&
+ layer_draw_properties.target_space_transform
+ .IsIdentityOrIntegerTranslation();
+ // Also disable LCD text locally for non-opaque content.
+ layer_can_use_lcd_text = subtree_can_use_lcd_text &&
+ layer->contents_opaque();
+ }
gfx::Rect content_rect(layer->content_bounds());
@@ -1995,7 +2002,7 @@
// If the new render surface is drawn translucent or with a non-integral
// translation then the subtree that gets drawn on this render surface
// cannot use LCD text.
- data_for_children.subtree_can_use_lcd_text = layer_can_use_lcd_text;
+ data_for_children.subtree_can_use_lcd_text = subtree_can_use_lcd_text;
render_surface_layer_list->push_back(layer);
} else {
@@ -2374,6 +2381,8 @@
globals->can_render_to_separate_surface =
inputs.can_render_to_separate_surface;
globals->can_adjust_raster_scales = inputs.can_adjust_raster_scales;
+ globals->layers_always_allowed_lcd_text =
+ inputs.layers_always_allowed_lcd_text;
data_for_recursion->parent_matrix = scaled_device_transform;
data_for_recursion->full_hierarchy_matrix = identity_matrix;
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h
index 089fe29..349b341 100644
--- a/cc/trees/layer_tree_host_common.h
+++ b/cc/trees/layer_tree_host_common.h
@@ -40,6 +40,7 @@
const LayerType* page_scale_application_layer,
int max_texture_size,
bool can_use_lcd_text,
+ bool layers_always_allowed_lcd_text,
bool can_render_to_separate_surface,
bool can_adjust_raster_scales,
RenderSurfaceLayerListType* render_surface_layer_list,
@@ -52,6 +53,7 @@
page_scale_application_layer(page_scale_application_layer),
max_texture_size(max_texture_size),
can_use_lcd_text(can_use_lcd_text),
+ layers_always_allowed_lcd_text(layers_always_allowed_lcd_text),
can_render_to_separate_surface(can_render_to_separate_surface),
can_adjust_raster_scales(can_adjust_raster_scales),
render_surface_layer_list(render_surface_layer_list),
@@ -66,6 +68,7 @@
const LayerType* page_scale_application_layer;
int max_texture_size;
bool can_use_lcd_text;
+ bool layers_always_allowed_lcd_text;
bool can_render_to_separate_surface;
bool can_adjust_raster_scales;
RenderSurfaceLayerListType* render_surface_layer_list;
@@ -222,6 +225,7 @@
NULL,
std::numeric_limits<int>::max() / 2,
false,
+ false,
true,
false,
render_surface_layer_list,
@@ -246,6 +250,7 @@
NULL,
std::numeric_limits<int>::max() / 2,
false,
+ false,
true,
false,
render_surface_layer_list,
diff --git a/cc/trees/layer_tree_host_common_perftest.cc b/cc/trees/layer_tree_host_common_perftest.cc
index 12e7a5e..39bcbe6 100644
--- a/cc/trees/layer_tree_host_common_perftest.cc
+++ b/cc/trees/layer_tree_host_common_perftest.cc
@@ -93,19 +93,17 @@
RenderSurfaceLayerList update_list;
LayerTreeHostCommon::CalcDrawPropsMainInputs inputs(
layer_tree_host()->root_layer(),
- layer_tree_host()->device_viewport_size(),
- gfx::Transform(),
+ layer_tree_host()->device_viewport_size(), gfx::Transform(),
layer_tree_host()->device_scale_factor(),
layer_tree_host()->page_scale_factor(),
- layer_tree_host()->page_scale_layer(),
- max_texture_size,
+ layer_tree_host()->page_scale_layer(), max_texture_size,
layer_tree_host()->settings().can_use_lcd_text,
+ layer_tree_host()->settings().layers_always_allowed_lcd_text,
can_render_to_separate_surface,
layer_tree_host()
->settings()
.layer_transforms_should_scale_layer_contents,
- &update_list,
- 0);
+ &update_list, 0);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
timer_.NextLap();
@@ -147,18 +145,15 @@
LayerTreeHostImpl* host_impl) {
LayerImplList update_list;
LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
- active_tree->root_layer(),
- active_tree->DrawViewportSize(),
- host_impl->DrawTransform(),
- active_tree->device_scale_factor(),
+ active_tree->root_layer(), active_tree->DrawViewportSize(),
+ host_impl->DrawTransform(), active_tree->device_scale_factor(),
active_tree->total_page_scale_factor(),
- active_tree->InnerViewportContainerLayer(),
- max_texture_size,
+ active_tree->InnerViewportContainerLayer(), max_texture_size,
host_impl->settings().can_use_lcd_text,
+ host_impl->settings().layers_always_allowed_lcd_text,
can_render_to_separate_surface,
host_impl->settings().layer_transforms_should_scale_layer_contents,
- &update_list,
- 0);
+ &update_list, 0);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
}
};
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index b40f66d..7a282c1 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -59,7 +59,6 @@
SkCanvas* canvas,
const gfx::Rect& clip,
ContentLayerClient::GraphicsContextStatus gc_status) override {}
- void DidChangeLayerCanUseLCDText() override {}
bool FillsBoundsCompletely() const override { return false; }
};
@@ -5644,13 +5643,14 @@
ASSERT_EQ(2u, root->render_surface()->layer_list().size());
}
-typedef std::tr1::tuple<bool, bool> LCDTextTestParam;
+using LCDTextTestParam = std::tr1::tuple<bool, bool, bool>;
class LCDTextTest
: public LayerTreeHostCommonTestBase,
public testing::TestWithParam<LCDTextTestParam> {
protected:
virtual void SetUp() {
can_use_lcd_text_ = std::tr1::get<0>(GetParam());
+ layers_always_allowed_lcd_text_ = std::tr1::get<1>(GetParam());
root_ = Layer::Create();
child_ = Layer::Create();
@@ -5658,6 +5658,10 @@
child_->AddChild(grand_child_.get());
root_->AddChild(child_.get());
+ root_->SetContentsOpaque(true);
+ child_->SetContentsOpaque(true);
+ grand_child_->SetContentsOpaque(true);
+
gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(root_.get(),
identity_matrix,
@@ -5681,13 +5685,14 @@
true,
false);
- child_->SetForceRenderSurface(std::tr1::get<1>(GetParam()));
+ child_->SetForceRenderSurface(std::tr1::get<2>(GetParam()));
host_ = CreateFakeLayerTreeHost();
host_->SetRootLayer(root_);
}
bool can_use_lcd_text_;
+ bool layers_always_allowed_lcd_text_;
scoped_ptr<FakeLayerTreeHost> host_;
scoped_refptr<Layer> root_;
scoped_refptr<Layer> child_;
@@ -5695,108 +5700,131 @@
};
TEST_P(LCDTextTest, CanUseLCDText) {
+ bool expect_lcd_text = can_use_lcd_text_ || layers_always_allowed_lcd_text_;
+ bool expect_not_lcd_text = layers_always_allowed_lcd_text_;
+
// Case 1: Identity transform.
gfx::Transform identity_matrix;
- ExecuteCalculateDrawProperties(
- root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
- EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
- EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text());
- EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text());
+ ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
+ layers_always_allowed_lcd_text_);
+ EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());
// Case 2: Integral translation.
gfx::Transform integral_translation;
integral_translation.Translate(1.0, 2.0);
child_->SetTransform(integral_translation);
- ExecuteCalculateDrawProperties(
- root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
- EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
- EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text());
- EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text());
+ ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
+ layers_always_allowed_lcd_text_);
+ EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());
// Case 3: Non-integral translation.
gfx::Transform non_integral_translation;
non_integral_translation.Translate(1.5, 2.5);
child_->SetTransform(non_integral_translation);
- ExecuteCalculateDrawProperties(
- root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
- EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
- EXPECT_FALSE(child_->can_use_lcd_text());
- EXPECT_FALSE(grand_child_->can_use_lcd_text());
+ ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
+ layers_always_allowed_lcd_text_);
+ EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
+ EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text());
+ EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text());
// Case 4: Rotation.
gfx::Transform rotation;
rotation.Rotate(10.0);
child_->SetTransform(rotation);
- ExecuteCalculateDrawProperties(
- root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
- EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
- EXPECT_FALSE(child_->can_use_lcd_text());
- EXPECT_FALSE(grand_child_->can_use_lcd_text());
+ ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
+ layers_always_allowed_lcd_text_);
+ EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
+ EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text());
+ EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text());
// Case 5: Scale.
gfx::Transform scale;
scale.Scale(2.0, 2.0);
child_->SetTransform(scale);
- ExecuteCalculateDrawProperties(
- root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
- EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
- EXPECT_FALSE(child_->can_use_lcd_text());
- EXPECT_FALSE(grand_child_->can_use_lcd_text());
+ ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
+ layers_always_allowed_lcd_text_);
+ EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
+ EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text());
+ EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text());
// Case 6: Skew.
gfx::Transform skew;
skew.SkewX(10.0);
child_->SetTransform(skew);
- ExecuteCalculateDrawProperties(
- root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
- EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
- EXPECT_FALSE(child_->can_use_lcd_text());
- EXPECT_FALSE(grand_child_->can_use_lcd_text());
+ ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
+ layers_always_allowed_lcd_text_);
+ EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
+ EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text());
+ EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text());
// Case 7: Translucent.
child_->SetTransform(identity_matrix);
child_->SetOpacity(0.5f);
- ExecuteCalculateDrawProperties(
- root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
- EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
- EXPECT_FALSE(child_->can_use_lcd_text());
- EXPECT_FALSE(grand_child_->can_use_lcd_text());
+ ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
+ layers_always_allowed_lcd_text_);
+ EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
+ EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text());
+ EXPECT_EQ(expect_not_lcd_text, grand_child_->can_use_lcd_text());
// Case 8: Sanity check: restore transform and opacity.
child_->SetTransform(identity_matrix);
child_->SetOpacity(1.f);
- ExecuteCalculateDrawProperties(
- root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
- EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
- EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text());
- EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text());
+ ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
+ layers_always_allowed_lcd_text_);
+ EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());
+
+ // Case 9: Non-opaque content.
+ child_->SetContentsOpaque(false);
+ ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
+ layers_always_allowed_lcd_text_);
+ EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
+ EXPECT_EQ(expect_not_lcd_text, child_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());
+
+ // Case 10: Sanity check: restore content opaqueness.
+ child_->SetContentsOpaque(true);
+ ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
+ layers_always_allowed_lcd_text_);
+ EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());
}
TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) {
+ bool expect_lcd_text = can_use_lcd_text_ || layers_always_allowed_lcd_text_;
+
// Sanity check: Make sure can_use_lcd_text_ is set on each node.
- ExecuteCalculateDrawProperties(
- root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
- EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
- EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text());
- EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text());
+ ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
+ layers_always_allowed_lcd_text_);
+ EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());
// Add opacity animation.
child_->SetOpacity(0.9f);
AddOpacityTransitionToController(
child_->layer_animation_controller(), 10.0, 0.9f, 0.1f, false);
- ExecuteCalculateDrawProperties(
- root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
+ ExecuteCalculateDrawProperties(root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_,
+ layers_always_allowed_lcd_text_);
// Text AA should not be adjusted while animation is active.
// Make sure LCD text AA setting remains unchanged.
- EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
- EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text());
- EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, child_->can_use_lcd_text());
+ EXPECT_EQ(expect_lcd_text, grand_child_->can_use_lcd_text());
}
INSTANTIATE_TEST_CASE_P(LayerTreeHostCommonTest,
LCDTextTest,
- testing::Combine(testing::Bool(), testing::Bool()));
+ testing::Combine(testing::Bool(),
+ testing::Bool(),
+ testing::Bool()));
TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayer) {
FakeImplProxy proxy;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index ffe2ddb..bb1be98 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -2567,7 +2567,18 @@
bool consume_by_top_controls = ShouldTopControlsConsumeScroll(scroll_delta);
- for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
+ // There's an edge case where the outer viewport isn't scrollable when the
+ // scroll starts, however, as the top controls show the outer viewport becomes
+ // scrollable. Therefore, always try scrolling the outer viewport before the
+ // inner.
+ // TODO(bokan): Move the top controls logic out of the loop since the scroll
+ // that causes the outer viewport to become scrollable will still be applied
+ // to the inner viewport.
+ LayerImpl* start_layer = CurrentlyScrollingLayer();
+ if (start_layer == InnerViewportScrollLayer() && OuterViewportScrollLayer())
+ start_layer = OuterViewportScrollLayer();
+
+ for (LayerImpl* layer_impl = start_layer;
layer_impl;
layer_impl = layer_impl->parent()) {
if (!layer_impl->scrollable())
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 0b9d976..51377d2 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -2319,6 +2319,8 @@
const gfx::Size& outer_viewport_size,
const gfx::Size& scroll_layer_size) {
CreateHostImpl(settings_, CreateOutputSurface());
+ host_impl_->SetTopControlsLayoutHeight(
+ settings_.top_controls_height);
scoped_ptr<LayerImpl> root =
LayerImpl::Create(host_impl_->active_tree(), 1);
@@ -2364,8 +2366,6 @@
outer_viewport_scroll_layer_id);
host_impl_->SetViewportSize(inner_viewport_size);
- host_impl_->SetTopControlsLayoutHeight(
- settings_.top_controls_height);
LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer();
EXPECT_EQ(inner_viewport_size, root_clip_ptr->bounds());
}
@@ -2402,6 +2402,81 @@
inner_viewport_scroll_layer->FixedContainerSizeDelta());
}
+// In this test, the outer viewport is initially unscrollable. We test that a
+// scroll initiated on the inner viewport, causing the top controls to show and
+// thus making the outer viewport scrollable, still scrolls the outer viewport.
+TEST_F(LayerTreeHostImplTopControlsTest,
+ TopControlsOuterViewportBecomesScrollable) {
+ SetupTopControlsAndScrollLayerWithVirtualViewport(
+ gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100));
+ DrawFrame();
+
+ LayerImpl *inner_scroll =
+ host_impl_->active_tree()->InnerViewportScrollLayer();
+ LayerImpl *inner_container =
+ host_impl_->active_tree()->InnerViewportContainerLayer();
+ LayerImpl *outer_scroll =
+ host_impl_->active_tree()->OuterViewportScrollLayer();
+ LayerImpl *outer_container =
+ host_impl_->active_tree()->OuterViewportContainerLayer();
+
+ // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer.
+ outer_scroll->SetDrawsContent(true);
+ host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 1.f, 2.f);
+
+ EXPECT_EQ(InputHandler::ScrollStarted,
+ host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, 50.f));
+
+ // The entire scroll delta should have been used to hide the top controls.
+ // The viewport layers should be resized back to their full sizes.
+ EXPECT_EQ(0.f,
+ host_impl_->active_tree()->total_top_controls_content_offset());
+ EXPECT_EQ(0.f, inner_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(100.f, inner_container->BoundsForScrolling().height());
+ EXPECT_EQ(100.f, outer_container->BoundsForScrolling().height());
+
+ // The inner viewport should be scrollable by 50px * page_scale.
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, 100.f));
+ EXPECT_EQ(50.f, inner_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(0.f, outer_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(gfx::ScrollOffset(), outer_scroll->MaxScrollOffset());
+
+ host_impl_->ScrollEnd();
+
+ EXPECT_EQ(InputHandler::ScrollStarted,
+ host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
+ EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll);
+
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -50.f));
+
+ // The entire scroll delta should have been used to show the top controls.
+ // The outer viewport should be resized to accomodate and scrolled to the
+ // bottom of the document to keep the viewport in place.
+ EXPECT_EQ(50.f,
+ host_impl_->active_tree()->total_top_controls_content_offset());
+ EXPECT_EQ(50.f, outer_container->BoundsForScrolling().height());
+ EXPECT_EQ(50.f, inner_container->BoundsForScrolling().height());
+ EXPECT_EQ(25.f, outer_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(25.f, inner_scroll->TotalScrollOffset().y());
+
+ // Now when we continue scrolling, make sure the outer viewport gets scrolled
+ // since it wasn't scrollable when the scroll began.
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -20.f));
+ EXPECT_EQ(15.f, outer_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(25.f, inner_scroll->TotalScrollOffset().y());
+
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -30.f));
+ EXPECT_EQ(0.f, outer_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(25.f, inner_scroll->TotalScrollOffset().y());
+
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -50.f));
+ host_impl_->ScrollEnd();
+
+ EXPECT_EQ(0.f, outer_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(0.f, inner_scroll->TotalScrollOffset().y());
+}
+
// Test that the fixed position container delta is appropriately adjusted
// by the top controls showing/hiding and page scale doesn't affect it.
TEST_F(LayerTreeHostImplTopControlsTest, FixedContainerDelta) {
diff --git a/cc/trees/layer_tree_host_pixeltest_masks.cc b/cc/trees/layer_tree_host_pixeltest_masks.cc
index f4f174c..4d0717d 100644
--- a/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -24,8 +24,6 @@
explicit MaskContentLayerClient(const gfx::Size& bounds) : bounds_(bounds) {}
~MaskContentLayerClient() override {}
- void DidChangeLayerCanUseLCDText() override {}
-
bool FillsBoundsCompletely() const override { return false; }
void PaintContents(
diff --git a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc
index d703e22..e7dd149 100644
--- a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc
+++ b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc
@@ -59,8 +59,6 @@
explicit BlueYellowLayerClient(gfx::Rect layer_rect)
: layer_rect_(layer_rect) {}
- void DidChangeLayerCanUseLCDText() override {}
-
bool FillsBoundsCompletely() const override { return false; }
void PaintContents(
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index e39a76d..72a5b45 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -1112,7 +1112,6 @@
if (test_layer_)
test_layer_->SetOpacity(0.f);
}
- void DidChangeLayerCanUseLCDText() override {}
bool FillsBoundsCompletely() const override { return false; }
private:
@@ -2306,46 +2305,42 @@
SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
-class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
+class LayerTreeHostTestLCDChange : public LayerTreeHostTest {
public:
- class NotificationClient : public ContentLayerClient {
+ class PaintClient : public FakeContentLayerClient {
public:
- NotificationClient()
- : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
+ PaintClient() : paint_count_(0) {}
- void set_layer(Layer* layer) { layer_ = layer; }
int paint_count() const { return paint_count_; }
- int lcd_notification_count() const { return lcd_notification_count_; }
void PaintContents(
SkCanvas* canvas,
const gfx::Rect& clip,
ContentLayerClient::GraphicsContextStatus gc_status) override {
+ FakeContentLayerClient::PaintContents(canvas, clip, gc_status);
++paint_count_;
}
- void DidChangeLayerCanUseLCDText() override {
- ++lcd_notification_count_;
- layer_->SetNeedsDisplay();
- }
+
bool FillsBoundsCompletely() const override { return false; }
private:
- Layer* layer_;
int paint_count_;
- int lcd_notification_count_;
};
void SetupTree() override {
+ num_tiles_rastered_ = 0;
+
scoped_refptr<Layer> root_layer;
if (layer_tree_host()->settings().impl_side_painting)
root_layer = PictureLayer::Create(&client_);
else
root_layer = ContentLayer::Create(&client_);
+ client_.set_fill_with_nonsolid_color(true);
root_layer->SetIsDrawable(true);
- root_layer->SetBounds(gfx::Size(1, 1));
+ root_layer->SetBounds(gfx::Size(10, 10));
+ root_layer->SetContentsOpaque(true);
layer_tree_host()->SetRootLayer(root_layer);
- client_.set_layer(root_layer.get());
// The expecations are based on the assumption that the default
// LCD settings are:
@@ -2356,49 +2351,76 @@
}
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
- void AfterTest() override {}
- void DidCommit() override {
+ void DidCommitAndDrawFrame() override {
switch (layer_tree_host()->source_frame_number()) {
case 1:
- // The first update consists of one LCD notification and one paint.
- EXPECT_EQ(1, client_.lcd_notification_count());
+ // The first update consists of a paint of the whole layer.
EXPECT_EQ(1, client_.paint_count());
// LCD text must have been enabled on the layer.
EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
PostSetNeedsCommitToMainThread();
break;
case 2:
- // Since nothing changed on layer, there should be no notification
- // or paint on the second update.
- EXPECT_EQ(1, client_.lcd_notification_count());
+ // Since nothing changed on layer, there should be no paint.
EXPECT_EQ(1, client_.paint_count());
// LCD text must not have changed.
EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
- // Change layer opacity that should trigger lcd notification.
+ // Change layer opacity that should trigger lcd change.
layer_tree_host()->root_layer()->SetOpacity(.5f);
- // No need to request a commit - setting opacity will do it.
break;
- default:
- // Verify that there is no extra commit due to layer invalidation.
- EXPECT_EQ(3, layer_tree_host()->source_frame_number());
- // LCD notification count should have incremented due to
- // change in layer opacity.
- EXPECT_EQ(2, client_.lcd_notification_count());
- // Paint count should be incremented due to invalidation.
- EXPECT_EQ(2, client_.paint_count());
+ case 3:
+ // LCD text doesn't require re-recording, so no painting should occur.
+ EXPECT_EQ(1, client_.paint_count());
// LCD text must have been disabled on the layer due to opacity.
EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
+ // Change layer opacity that should not trigger lcd change.
+ layer_tree_host()->root_layer()->SetOpacity(1.f);
+ break;
+ case 4:
+ // LCD text doesn't require re-recording, so no painting should occur.
+ EXPECT_EQ(1, client_.paint_count());
+ // Even though LCD text could be allowed.
+ EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
EndTest();
break;
}
}
+ void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
+ const Tile* tile) override {
+ ++num_tiles_rastered_;
+ }
+
+ void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
+ switch (host_impl->active_tree()->source_frame_number()) {
+ case 0:
+ // The first draw.
+ EXPECT_EQ(1, num_tiles_rastered_);
+ break;
+ case 1:
+ // Nothing changed on the layer.
+ EXPECT_EQ(1, num_tiles_rastered_);
+ break;
+ case 2:
+ // LCD text was disabled, it should be re-rastered with LCD text off.
+ EXPECT_EQ(2, num_tiles_rastered_);
+ break;
+ case 3:
+ // LCD text was enabled but it's sticky and stays off.
+ EXPECT_EQ(2, num_tiles_rastered_);
+ break;
+ }
+ }
+
+ void AfterTest() override {}
+
private:
- NotificationClient client_;
+ PaintClient client_;
+ int num_tiles_rastered_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
+SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestLCDChange);
// Verify that the BeginFrame notification is used to initiate rendering.
class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
@@ -2569,8 +2591,6 @@
layer_->SetBounds(gfx::Size(2, 2));
}
- void DidChangeLayerCanUseLCDText() override {}
-
bool FillsBoundsCompletely() const override { return false; }
private:
@@ -5387,6 +5407,9 @@
FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
layer->SetBounds(gfx::Size(500, 500));
layer->SetContentsOpaque(true);
+ // Avoid LCD text on the layer so we don't cause extra commits when we
+ // pinch.
+ layer->disable_lcd_text();
pinch->AddChild(layer);
layer_tree_host()->RegisterViewportLayers(root, pinch, pinch);
@@ -5433,11 +5456,6 @@
PostNextAfterDraw(host_impl);
break;
case 2:
- // Wait for any activations that need to occur due to starting a pinch,
- // and drawing with a non-identity transform (for eg. LCD text being
- // disabled).
- if (host_impl->pending_tree())
- break;
if (quad_scale_delta != 1.f)
break;
// Drew at page scale 1.5 after pinching in.
@@ -5582,7 +5600,6 @@
void SetupTree() override {
step_ = 1;
continuous_draws_ = 0;
- expect_draw_ = false;
client_.set_fill_with_nonsolid_color(true);
scoped_refptr<Layer> root = Layer::Create();
@@ -5600,6 +5617,9 @@
FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
layer->SetBounds(gfx::Size(500, 500));
layer->SetContentsOpaque(true);
+ // Avoid LCD text on the layer so we don't cause extra commits when we
+ // pinch.
+ layer->disable_lcd_text();
pinch->AddChild(layer);
layer_tree_host()->RegisterViewportLayers(root, pinch, pinch);
@@ -5662,18 +5682,17 @@
EXPECT_EQ(1.f, quad_scale_delta);
break;
case 5:
- // TODO(danakj): We may get one more draw because the NotifyReadyToDraw
- // is asynchronous from the previous draw and happens late.
+ // TODO(danakj): We get more draws before the NotifyReadyToDraw
+ // because it is asynchronous from the previous draw and happens late.
break;
case 6:
- // We may get another draw if we activate due to the pinch (eg LCD text
- // gets disabled).
- if (expect_draw_)
- break;
+ // NotifyReadyToDraw happened. If we were already inside a frame, we may
+ // try to draw once more.
+ break;
+ case 7:
NOTREACHED() << "No draws should happen once we have a complete frame.";
break;
}
- expect_draw_ = false;
return draw_result;
}
@@ -5701,8 +5720,13 @@
}
break;
case 4:
- // TODO(danakj): Now we wait for NotifyReadyToDraw to avoid flakiness
- // since it happens asynchronously.
+ ++step_;
+ break;
+ case 5:
+ // Waiting for NotifyReadyToDraw.
+ break;
+ case 6:
+ // NotifyReadyToDraw happened.
++step_;
break;
}
@@ -5710,21 +5734,17 @@
void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override {
if (step_ == 5) {
- // We should not continue to draw any more. End the test after a timeout
- // to watch for any extraneous draws.
+ ++step_;
+ // NotifyReadyToDraw has happened, we may draw once more, but should not
+ // get any more draws after that. End the test after a timeout to watch
+ // for any extraneous draws.
// TODO(brianderson): We could remove this delay and instead wait until
// the BeginFrameSource decides it doesn't need to send frames anymore,
// or test that it already doesn't here.
EndTestAfterDelayMs(16 * 4);
- ++step_;
- expect_draw_ = true;
}
}
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
- expect_draw_ = true;
- }
-
void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
const Tile* tile) override {
// On step_ == 2, we are preventing texture uploads from completing,
@@ -5739,7 +5759,6 @@
FakeContentLayerClient client_;
int step_;
int continuous_draws_;
- bool expect_draw_;
base::WaitableEvent playback_allowed_event_;
};
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index 9c346e2..8318192 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -8,6 +8,7 @@
#include "cc/animation/layer_animation_controller.h"
#include "cc/animation/scroll_offset_animation_curve.h"
#include "cc/animation/timing_function.h"
+#include "cc/base/time_util.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/test/animation_test_common.h"
@@ -503,11 +504,11 @@
const FloatAnimationCurve* curve =
animation->curve()->ToFloatAnimationCurve();
- float start_opacity = curve->GetValue(0.0);
- float end_opacity = curve->GetValue(curve->Duration().InSecondsF());
+ float start_opacity = curve->GetValue(base::TimeDelta());
+ float end_opacity = curve->GetValue(curve->Duration());
float linearly_interpolated_opacity =
0.25f * end_opacity + 0.75f * start_opacity;
- double time = curve->Duration().InSecondsF() * 0.25;
+ base::TimeDelta time = TimeUtil::Scale(curve->Duration(), 0.25f);
// If the linear timing function associated with this animation was not
// picked up, then the linearly interpolated opacity would be different
// because of the default ease timing function.
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 6b2b37f..c005a18 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -490,18 +490,14 @@
++render_surface_layer_list_id_;
LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
- root_layer(),
- DrawViewportSize(),
- layer_tree_host_impl_->DrawTransform(),
- device_scale_factor(),
- total_page_scale_factor(),
- page_scale_layer,
- resource_provider()->max_texture_size(),
- settings().can_use_lcd_text,
+ root_layer(), DrawViewportSize(),
+ layer_tree_host_impl_->DrawTransform(), device_scale_factor(),
+ total_page_scale_factor(), page_scale_layer,
+ resource_provider()->max_texture_size(), settings().can_use_lcd_text,
+ settings().layers_always_allowed_lcd_text,
can_render_to_separate_surface,
settings().layer_transforms_should_scale_layer_contents,
- &render_surface_layer_list_,
- render_surface_layer_list_id_);
+ &render_surface_layer_list_, render_surface_layer_list_id_);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
}
diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc
index 48c4133..14c1def 100644
--- a/cc/trees/layer_tree_settings.cc
+++ b/cc/trees/layer_tree_settings.cc
@@ -43,6 +43,7 @@
timeout_and_draw_when_animation_checkerboards(true),
maximum_number_of_failed_draws_before_draw_is_forced_(3),
layer_transforms_should_scale_layer_contents(false),
+ layers_always_allowed_lcd_text(false),
minimum_contents_scale(0.0625f),
low_res_contents_scale_factor(0.25f),
top_controls_height(0.f),
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index 3097e59..69ac995 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -54,6 +54,7 @@
bool timeout_and_draw_when_animation_checkerboards;
int maximum_number_of_failed_draws_before_draw_is_forced_;
bool layer_transforms_should_scale_layer_contents;
+ bool layers_always_allowed_lcd_text;
float minimum_contents_scale;
float low_res_contents_scale_factor;
float top_controls_height;
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index cfe8ed9..4fcfea8 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -671,10 +671,10 @@
bool debug_;
// When true, the context is lost when a GL_OUT_OF_MEMORY error occurs.
- bool lose_context_when_out_of_memory_;
+ const bool lose_context_when_out_of_memory_;
// Whether or not to support client side arrays.
- bool support_client_side_arrays_;
+ const bool support_client_side_arrays_;
// Used to check for single threaded access.
int use_count_;
diff --git a/gpu/command_buffer/client/vertex_array_object_manager.h b/gpu/command_buffer/client/vertex_array_object_manager.h
index 8638584..e4c8999 100644
--- a/gpu/command_buffer/client/vertex_array_object_manager.h
+++ b/gpu/command_buffer/client/vertex_array_object_manager.h
@@ -117,7 +117,7 @@
VertexArrayObject* bound_vertex_array_object_;
VertexArrayObjectMap vertex_array_objects_;
- bool support_client_side_arrays_;
+ const bool support_client_side_arrays_;
DISALLOW_COPY_AND_ASSIGN(VertexArrayObjectManager);
};
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn
index 1c43029..351e5c9 100644
--- a/gpu/command_buffer/service/BUILD.gn
+++ b/gpu/command_buffer/service/BUILD.gn
@@ -103,6 +103,8 @@
"shader_translator_cache.cc",
"stream_texture_manager_in_process_android.h",
"stream_texture_manager_in_process_android.cc",
+ "sync_point_manager.h",
+ "sync_point_manager.cc",
"texture_definition.h",
"texture_definition.cc",
"texture_manager.h",
diff --git a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
index f98ca2e..ffb9370 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
+++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
@@ -21,8 +21,8 @@
"#define SamplerType sampler2D\n" \
"#define TextureLookup texture2D\n" SHADER(src)
#define SHADER_RECTANGLE_ARB(src) \
- "#define SamplerType samplerRect\n" \
- "#define TextureLookup textureRect\n" SHADER(src)
+ "#define SamplerType sampler2DRect\n" \
+ "#define TextureLookup texture2DRect\n" SHADER(src)
#define SHADER_EXTERNAL_OES(src) \
"#extension GL_OES_EGL_image_external : require\n" \
"#define SamplerType samplerExternalOES\n" \
diff --git a/gpu/command_buffer/service/sync_point_manager.cc b/gpu/command_buffer/service/sync_point_manager.cc
new file mode 100644
index 0000000..cd8c490
--- /dev/null
+++ b/gpu/command_buffer/service/sync_point_manager.cc
@@ -0,0 +1,84 @@
+// Copyright (c) 2012 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.
+
+#include "gpu/command_buffer/service/sync_point_manager.h"
+
+#include <climits>
+
+#include "base/logging.h"
+#include "base/rand_util.h"
+
+namespace gpu {
+
+static const int kMaxSyncBase = INT_MAX;
+
+SyncPointManager::SyncPointManager()
+ : next_sync_point_(base::RandInt(1, kMaxSyncBase)) {
+ // To reduce the risk that a sync point created in a previous GPU process
+ // will be in flight in the next GPU process, randomize the starting sync
+ // point number. http://crbug.com/373452
+}
+
+SyncPointManager::~SyncPointManager() {
+}
+
+uint32 SyncPointManager::GenerateSyncPoint() {
+ base::AutoLock lock(lock_);
+ uint32 sync_point = next_sync_point_++;
+ // When an integer overflow occurs, don't return 0.
+ if (!sync_point)
+ sync_point = next_sync_point_++;
+
+ // Note: wrapping would take days for a buggy/compromized renderer that would
+ // insert sync points in a loop, but if that were to happen, better explicitly
+ // crash the GPU process than risk worse.
+ // For normal operation (at most a few per frame), it would take ~a year to
+ // wrap.
+ CHECK(sync_point_map_.find(sync_point) == sync_point_map_.end());
+ sync_point_map_.insert(std::make_pair(sync_point, ClosureList()));
+ return sync_point;
+}
+
+void SyncPointManager::RetireSyncPoint(uint32 sync_point) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ ClosureList list;
+ {
+ base::AutoLock lock(lock_);
+ SyncPointMap::iterator it = sync_point_map_.find(sync_point);
+ if (it == sync_point_map_.end()) {
+ LOG(ERROR) << "Attempted to retire sync point that"
+ " didn't exist or was already retired.";
+ return;
+ }
+ list.swap(it->second);
+ sync_point_map_.erase(it);
+ }
+ for (ClosureList::iterator i = list.begin(); i != list.end(); ++i)
+ i->Run();
+}
+
+void SyncPointManager::AddSyncPointCallback(uint32 sync_point,
+ const base::Closure& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ {
+ base::AutoLock lock(lock_);
+ SyncPointMap::iterator it = sync_point_map_.find(sync_point);
+ if (it != sync_point_map_.end()) {
+ it->second.push_back(callback);
+ return;
+ }
+ }
+ callback.Run();
+}
+
+bool SyncPointManager::IsSyncPointRetired(uint32 sync_point) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ {
+ base::AutoLock lock(lock_);
+ SyncPointMap::iterator it = sync_point_map_.find(sync_point);
+ return it == sync_point_map_.end();
+ }
+}
+
+} // namespace gpu
diff --git a/gpu/command_buffer/service/sync_point_manager.h b/gpu/command_buffer/service/sync_point_manager.h
new file mode 100644
index 0000000..8cbf8a8
--- /dev/null
+++ b/gpu/command_buffer/service/sync_point_manager.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2012 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.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_
+#define GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_
+
+#include <vector>
+
+#include "base/callback.h"
+#include "base/containers/hash_tables.h"
+#include "base/memory/ref_counted.h"
+#include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
+#include "gpu/gpu_export.h"
+
+namespace gpu {
+
+// This class manages the sync points, which allow cross-channel
+// synchronization.
+class GPU_EXPORT SyncPointManager
+ : public base::RefCountedThreadSafe<SyncPointManager> {
+ public:
+ SyncPointManager();
+
+ // Generates a sync point, returning its ID. This can me called on any thread.
+ // IDs start at a random number. Never return 0.
+ uint32 GenerateSyncPoint();
+
+ // Retires a sync point. This will call all the registered callbacks for this
+ // sync point. This can only be called on the main thread.
+ void RetireSyncPoint(uint32 sync_point);
+
+ // Adds a callback to the sync point. The callback will be called when the
+ // sync point is retired, or immediately (from within that function) if the
+ // sync point was already retired (or not created yet). This can only be
+ // called on the main thread.
+ void AddSyncPointCallback(uint32 sync_point, const base::Closure& callback);
+
+ bool IsSyncPointRetired(uint32 sync_point);
+
+ private:
+ friend class base::RefCountedThreadSafe<SyncPointManager>;
+ typedef std::vector<base::Closure> ClosureList;
+ typedef base::hash_map<uint32, ClosureList> SyncPointMap;
+
+ ~SyncPointManager();
+
+ base::ThreadChecker thread_checker_;
+
+ // Protects the 2 fields below. Note: callbacks shouldn't be called with this
+ // held.
+ base::Lock lock_;
+ SyncPointMap sync_point_map_;
+ uint32 next_sync_point_;
+
+ DISALLOW_COPY_AND_ASSIGN(SyncPointManager);
+};
+
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_
diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi
index c276d43..358317c 100644
--- a/gpu/command_buffer_service.gypi
+++ b/gpu/command_buffer_service.gypi
@@ -121,6 +121,8 @@
'command_buffer/service/shader_translator_cache.cc',
'command_buffer/service/stream_texture_manager_in_process_android.h',
'command_buffer/service/stream_texture_manager_in_process_android.cc',
+ 'command_buffer/service/sync_point_manager.h',
+ 'command_buffer/service/sync_point_manager.cc',
'command_buffer/service/texture_definition.h',
'command_buffer/service/texture_definition.cc',
'command_buffer/service/texture_manager.h',
diff --git a/net/base/net_log_event_type_list.h b/net/base/net_log_event_type_list.h
index af7c290..494b762 100644
--- a/net/base/net_log_event_type_list.h
+++ b/net/base/net_log_event_type_list.h
@@ -796,6 +796,14 @@
// "headers": <The list of header:value pairs>,
// }
+EVENT_TYPE(URL_REQUEST_FILTERS_SET)
+// This event is logged when a URLRequestJob sets up the filters, if any
+// filters were added to the job. It logs the filters added.
+// The following parameters are attached:
+// {
+// "filters": <The list of filter names>
+// }
+
// ------------------------------------------------------------------------
// HttpCache
// ------------------------------------------------------------------------
@@ -2398,3 +2406,11 @@
// This event is created when SdchDictionaryFetcher starts fetch. It contains
// no parameters.
EVENT_TYPE(SDCH_DICTIONARY_FETCH)
+
+// This event is created if the SdchDictionaryFetcher URLRequest returns
+// no error, but signals an error through bytes_read < 0.
+// It contains the following parameters:
+// {
+// "net_error": <error created>
+// }
+EVENT_TYPE(SDCH_DICTIONARY_FETCH_IMPLIED_ERROR)
diff --git a/net/base/sdch_problem_code_list.h b/net/base/sdch_problem_code_list.h
index 4efc17c..a0d5196 100644
--- a/net/base/sdch_problem_code_list.h
+++ b/net/base/sdch_problem_code_list.h
@@ -55,7 +55,7 @@
SDCH_PROBLEM_CODE(DICTIONARY_COUNT_EXCEEDED, 35)
// defunct = 36, // DICTIONARY_PREVIOUSLY_SCHEDULED_TO_DOWNLOAD used instead.
// defunct = 37, // DICTIONARY_PREVIOUSLY_SCHEDULED_TO_DOWNLOAD used instead.
-SDCH_PROBLEM_CODE(DICTIONARY_FETCH_READ_FAILED, 38)
+// defunct = 38, // No longer paying attention to URLRequest::Read return.
SDCH_PROBLEM_CODE(DICTIONARY_PREVIOUSLY_SCHEDULED_TO_DOWNLOAD, 39)
// Failsafe hack.
diff --git a/net/filter/filter.cc b/net/filter/filter.cc
index c9a56bd..53d6583 100644
--- a/net/filter/filter.cc
+++ b/net/filter/filter.cc
@@ -64,6 +64,24 @@
base::Bind(&NetLogSdchResourceProblemCallback, problem));
}
+std::string FilterTypeAsString(Filter::FilterType type_id) {
+ switch (type_id) {
+ case Filter::FILTER_TYPE_DEFLATE:
+ return "FILTER_TYPE_DEFLATE";
+ case Filter::FILTER_TYPE_GZIP:
+ return "FILTER_TYPE_GZIP";
+ case Filter::FILTER_TYPE_GZIP_HELPING_SDCH:
+ return "FILTER_TYPE_GZIP_HELPING_SDCH";
+ case Filter::FILTER_TYPE_SDCH:
+ return "FILTER_TYPE_SDCH";
+ case Filter::FILTER_TYPE_SDCH_POSSIBLE :
+ return "FILTER_TYPE_SDCH_POSSIBLE ";
+ case Filter::FILTER_TYPE_UNSUPPORTED:
+ return "FILTER_TYPE_UNSUPPORTED";
+ }
+ return "";
+}
+
} // namespace
FilterContext::~FilterContext() {
@@ -340,12 +358,22 @@
return;
}
-Filter::Filter()
+std::string Filter::OrderedFilterList() const {
+ if (next_filter_) {
+ return FilterTypeAsString(type_id_) + "," +
+ next_filter_->OrderedFilterList();
+ } else {
+ return FilterTypeAsString(type_id_);
+ }
+}
+
+Filter::Filter(FilterType type_id)
: stream_buffer_(NULL),
stream_buffer_size_(0),
next_stream_data_(NULL),
stream_data_len_(0),
- last_status_(FILTER_NEED_MORE_DATA) {}
+ last_status_(FILTER_NEED_MORE_DATA),
+ type_id_(type_id) {}
Filter::FilterStatus Filter::CopyOut(char* dest_buffer, int* dest_len) {
int out_len;
@@ -370,7 +398,7 @@
// static
Filter* Filter::InitGZipFilter(FilterType type_id, int buffer_size) {
- scoped_ptr<GZipFilter> gz_filter(new GZipFilter());
+ scoped_ptr<GZipFilter> gz_filter(new GZipFilter(type_id));
gz_filter->InitBuffer(buffer_size);
return gz_filter->InitDecoding(type_id) ? gz_filter.release() : NULL;
}
@@ -379,7 +407,7 @@
Filter* Filter::InitSdchFilter(FilterType type_id,
const FilterContext& filter_context,
int buffer_size) {
- scoped_ptr<SdchFilter> sdch_filter(new SdchFilter(filter_context));
+ scoped_ptr<SdchFilter> sdch_filter(new SdchFilter(type_id, filter_context));
sdch_filter->InitBuffer(buffer_size);
return sdch_filter->InitDecoding(type_id) ? sdch_filter.release() : NULL;
}
diff --git a/net/filter/filter.h b/net/filter/filter.h
index 13489ef..cec8398 100644
--- a/net/filter/filter.h
+++ b/net/filter/filter.h
@@ -225,12 +225,15 @@
static void FixupEncodingTypes(const FilterContext& filter_context,
std::vector<FilterType>* encoding_types);
+ // Returns a string describing the FilterTypes implemented by this filter.
+ std::string OrderedFilterList() const;
+
protected:
friend class GZipUnitTest;
friend class SdchFilterChainingTest;
FRIEND_TEST_ALL_PREFIXES(FilterTest, ThreeFilterChain);
- Filter();
+ explicit Filter(FilterType type_id);
// Filters the data stored in stream_buffer_ and writes the output into the
// dest_buffer passed in.
@@ -294,10 +297,14 @@
// An optional filter to process output from this filter.
scoped_ptr<Filter> next_filter_;
+
// Remember what status or local filter last returned so we can better handle
// chained filters.
FilterStatus last_status_;
+ // The filter type this filter was constructed from.
+ FilterType type_id_;
+
DISALLOW_COPY_AND_ASSIGN(Filter);
};
diff --git a/net/filter/filter_unittest.cc b/net/filter/filter_unittest.cc
index 506284d..5b2446c 100644
--- a/net/filter/filter_unittest.cc
+++ b/net/filter/filter_unittest.cc
@@ -13,7 +13,7 @@
class PassThroughFilter : public Filter {
public:
- PassThroughFilter() {}
+ PassThroughFilter() : Filter(FILTER_TYPE_UNSUPPORTED) {}
FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len) override {
return CopyOut(dest_buffer, dest_len);
diff --git a/net/filter/gzip_filter.cc b/net/filter/gzip_filter.cc
index 36fe01c..6d15ee9 100644
--- a/net/filter/gzip_filter.cc
+++ b/net/filter/gzip_filter.cc
@@ -10,8 +10,9 @@
namespace net {
-GZipFilter::GZipFilter()
- : decoding_status_(DECODING_UNINITIALIZED),
+GZipFilter::GZipFilter(FilterType type)
+ : Filter(type),
+ decoding_status_(DECODING_UNINITIALIZED),
decoding_mode_(DECODE_MODE_UNKNOWN),
gzip_header_status_(GZIP_CHECK_HEADER_IN_PROGRESS),
zlib_header_added_(false),
diff --git a/net/filter/gzip_filter.h b/net/filter/gzip_filter.h
index 597c2e7..42dc320 100644
--- a/net/filter/gzip_filter.h
+++ b/net/filter/gzip_filter.h
@@ -73,7 +73,7 @@
static const int kGZipFooterSize = 8;
// Only to be instantiated by Filter::Factory.
- GZipFilter();
+ GZipFilter(FilterType type);
friend class Filter;
// Parses and verifies the GZip header.
diff --git a/net/filter/sdch_filter.cc b/net/filter/sdch_filter.cc
index d03ff7f..d1eb7f4 100644
--- a/net/filter/sdch_filter.cc
+++ b/net/filter/sdch_filter.cc
@@ -99,8 +99,9 @@
} // namespace
-SdchFilter::SdchFilter(const FilterContext& filter_context)
- : filter_context_(filter_context),
+SdchFilter::SdchFilter(FilterType type, const FilterContext& filter_context)
+ : Filter(type),
+ filter_context_(filter_context),
decoding_status_(DECODING_UNINITIALIZED),
dictionary_hash_(),
dictionary_hash_is_plausible_(false),
diff --git a/net/filter/sdch_filter.h b/net/filter/sdch_filter.h
index a1a6607..bc7788c 100644
--- a/net/filter/sdch_filter.h
+++ b/net/filter/sdch_filter.h
@@ -54,7 +54,7 @@
};
// Only to be instantiated by Filter::Factory.
- explicit SdchFilter(const FilterContext& filter_context);
+ SdchFilter(FilterType type, const FilterContext& filter_context);
friend class Filter;
// Identify the suggested dictionary, and initialize underlying decompressor.
diff --git a/net/http/http_server_properties_manager.cc b/net/http/http_server_properties_manager.cc
index 794030d..41b70b1 100644
--- a/net/http/http_server_properties_manager.cc
+++ b/net/http/http_server_properties_manager.cc
@@ -13,6 +13,7 @@
#include "base/strings/stringprintf.h"
#include "base/thread_task_runner_handle.h"
#include "base/values.h"
+#include "net/base/net_util.h"
namespace net {
@@ -419,7 +420,7 @@
int port = 0;
if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion(
"port", &port) ||
- (port > (1 << 16))) {
+ !IsPortValid(port)) {
DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
detected_corrupted_prefs = true;
continue;
diff --git a/net/http/http_server_properties_manager.h b/net/http/http_server_properties_manager.h
index 4acf76f..22e2499 100644
--- a/net/http/http_server_properties_manager.h
+++ b/net/http/http_server_properties_manager.h
@@ -7,6 +7,7 @@
#include <string>
#include <vector>
+
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
diff --git a/net/http/http_server_properties_manager_unittest.cc b/net/http/http_server_properties_manager_unittest.cc
index db58c92..bb8b68c 100644
--- a/net/http/http_server_properties_manager_unittest.cc
+++ b/net/http/http_server_properties_manager_unittest.cc
@@ -241,6 +241,95 @@
EXPECT_EQ("bar", supports_quic2.address);
}
+TEST_F(HttpServerPropertiesManagerTest, BadCachedHostPortPair) {
+ ExpectCacheUpdate();
+ // The prefs are automaticalls updated in the case corruption is detected.
+ ExpectPrefsUpdate();
+
+ base::DictionaryValue* server_pref_dict = new base::DictionaryValue;
+
+ // Set supports_spdy for www.google.com:65536.
+ server_pref_dict->SetBoolean("supports_spdy", true);
+
+ // Set up alternate_protocol for www.google.com:65536.
+ base::DictionaryValue* alternate_protocol = new base::DictionaryValue;
+ alternate_protocol->SetInteger("port", 80);
+ alternate_protocol->SetString("protocol_str", "npn-spdy/3");
+ server_pref_dict->SetWithoutPathExpansion("alternate_protocol",
+ alternate_protocol);
+
+ // Set up SupportsQuic for www.google.com:65536.
+ base::DictionaryValue* supports_quic = new base::DictionaryValue;
+ supports_quic->SetBoolean("used_quic", true);
+ supports_quic->SetString("address", "foo");
+ server_pref_dict->SetWithoutPathExpansion("supports_quic", supports_quic);
+
+ // Set the server preference for www.google.com:65536.
+ base::DictionaryValue* servers_dict = new base::DictionaryValue;
+ servers_dict->SetWithoutPathExpansion("www.google.com:65536",
+ server_pref_dict);
+
+ base::DictionaryValue* http_server_properties_dict =
+ new base::DictionaryValue;
+ HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1);
+ http_server_properties_dict->SetWithoutPathExpansion("servers", servers_dict);
+
+ // Set up the pref.
+ pref_service_.SetManagedPref(kTestHttpServerProperties,
+ http_server_properties_dict);
+
+ base::RunLoop().RunUntilIdle();
+ Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
+
+ // Verify that nothing is set.
+ EXPECT_FALSE(http_server_props_manager_->SupportsSpdy(
+ net::HostPortPair::FromString("www.google.com:65536")));
+ EXPECT_FALSE(http_server_props_manager_->HasAlternateProtocol(
+ net::HostPortPair::FromString("www.google.com:65536")));
+ net::SupportsQuic supports_quic2 =
+ http_server_props_manager_->GetSupportsQuic(
+ net::HostPortPair::FromString("www.google.com:65536"));
+ EXPECT_FALSE(supports_quic2.used_quic);
+}
+
+TEST_F(HttpServerPropertiesManagerTest, BadCachedAltProtocolPort) {
+ ExpectCacheUpdate();
+ // The prefs are automaticalls updated in the case corruption is detected.
+ ExpectPrefsUpdate();
+
+ base::DictionaryValue* server_pref_dict = new base::DictionaryValue;
+
+ // Set supports_spdy for www.google.com:80.
+ server_pref_dict->SetBoolean("supports_spdy", true);
+
+ // Set up alternate_protocol for www.google.com:80.
+ base::DictionaryValue* alternate_protocol = new base::DictionaryValue;
+ alternate_protocol->SetInteger("port", 65536);
+ alternate_protocol->SetString("protocol_str", "npn-spdy/3");
+ server_pref_dict->SetWithoutPathExpansion("alternate_protocol",
+ alternate_protocol);
+
+ // Set the server preference for www.google.com:80.
+ base::DictionaryValue* servers_dict = new base::DictionaryValue;
+ servers_dict->SetWithoutPathExpansion("www.google.com:80", server_pref_dict);
+
+ base::DictionaryValue* http_server_properties_dict =
+ new base::DictionaryValue;
+ HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1);
+ http_server_properties_dict->SetWithoutPathExpansion("servers", servers_dict);
+
+ // Set up the pref.
+ pref_service_.SetManagedPref(kTestHttpServerProperties,
+ http_server_properties_dict);
+
+ base::RunLoop().RunUntilIdle();
+ Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
+
+ // Verify AlternateProtocol is not set.
+ EXPECT_FALSE(http_server_props_manager_->HasAlternateProtocol(
+ net::HostPortPair::FromString("www.google.com:80")));
+}
+
TEST_F(HttpServerPropertiesManagerTest, SupportsSpdy) {
ExpectPrefsUpdate();
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index baf38bf..6217d57 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -22,6 +22,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/sparse_histogram.h"
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -723,8 +724,8 @@
DCHECK(result.domain_id != DOMAIN_NOT_PINNED);
- UMA_HISTOGRAM_ENUMERATION(
- "Net.PublicKeyPinFailureDomain", result.domain_id, DOMAIN_NUM_EVENTS);
+ UMA_HISTOGRAM_SPARSE_SLOWLY(
+ "Net.PublicKeyPinFailureDomain", result.domain_id);
}
// static
diff --git a/net/ocsp/nss_ocsp.cc b/net/ocsp/nss_ocsp.cc
index 61c65ee..18a476d 100644
--- a/net/ocsp/nss_ocsp.cc
+++ b/net/ocsp/nss_ocsp.cc
@@ -23,6 +23,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
+#include "base/profiler/scoped_tracker.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -297,6 +298,11 @@
}
void OnResponseStarted(URLRequest* request) override {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 OCSPRequestSession::OnResponseStarted"));
+
DCHECK_EQ(request_.get(), request);
DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
@@ -311,6 +317,11 @@
}
void OnReadCompleted(URLRequest* request, int bytes_read) override {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 OCSPRequestSession::OnReadCompleted"));
+
DCHECK_EQ(request_.get(), request);
DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
diff --git a/net/proxy/proxy_script_fetcher_impl.cc b/net/proxy/proxy_script_fetcher_impl.cc
index 0ce507b..4e57121 100644
--- a/net/proxy/proxy_script_fetcher_impl.cc
+++ b/net/proxy/proxy_script_fetcher_impl.cc
@@ -7,6 +7,7 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
+#include "base/profiler/scoped_tracker.h"
#include "base/strings/string_util.h"
#include "net/base/data_url.h"
#include "net/base/io_buffer.h"
@@ -202,6 +203,11 @@
}
void ProxyScriptFetcherImpl::OnResponseStarted(URLRequest* request) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 ProxyScriptFetcherImpl::OnResponseStarted"));
+
DCHECK_EQ(request, cur_request_.get());
if (!request->status().is_success()) {
@@ -237,6 +243,11 @@
void ProxyScriptFetcherImpl::OnReadCompleted(URLRequest* request,
int num_bytes) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 ProxyScriptFetcherImpl::OnReadCompleted"));
+
DCHECK_EQ(request, cur_request_.get());
if (ConsumeBytesRead(request, num_bytes)) {
// Keep reading.
diff --git a/net/url_request/sdch_dictionary_fetcher.cc b/net/url_request/sdch_dictionary_fetcher.cc
index 5ac65ef..9aeed9a 100644
--- a/net/url_request/sdch_dictionary_fetcher.cc
+++ b/net/url_request/sdch_dictionary_fetcher.cc
@@ -9,6 +9,7 @@
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
+#include "base/profiler/scoped_tracker.h"
#include "base/thread_task_runner_handle.h"
#include "net/base/load_flags.h"
#include "net/base/sdch_net_log_params.h"
@@ -81,6 +82,11 @@
}
void SdchDictionaryFetcher::OnResponseStarted(URLRequest* request) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 SdchDictionaryFetcher::OnResponseStarted"));
+
DCHECK(CalledOnValidThread());
DCHECK_EQ(request, current_request_.get());
DCHECK_EQ(next_state_, STATE_REQUEST_STARTED);
@@ -99,6 +105,11 @@
void SdchDictionaryFetcher::OnReadCompleted(URLRequest* request,
int bytes_read) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 SdchDictionaryFetcher::OnReadCompleted"));
+
DCHECK(CalledOnValidThread());
DCHECK_EQ(request, current_request_.get());
DCHECK_EQ(next_state_, STATE_REQUEST_READING);
@@ -199,33 +210,29 @@
next_state_ = STATE_REQUEST_READING;
int bytes_read = 0;
- if (!current_request_->Read(buffer_.get(), kBufferSize, &bytes_read)) {
- if (current_request_->status().is_io_pending())
- return ERR_IO_PENDING;
+ current_request_->Read(buffer_.get(), kBufferSize, &bytes_read);
+ if (current_request_->status().is_io_pending())
+ return ERR_IO_PENDING;
- if (current_request_->status().error() == OK) {
- // This "should never happen", but if it does the result will be
- // an infinite loop. It's not clear how to handle a read failure
- // without a promise to invoke the callback at some point in the future,
- // so the request is failed.
- SdchManager::SdchErrorRecovery(SDCH_DICTIONARY_FETCH_READ_FAILED);
- current_request_->net_log().AddEvent(
- NetLog::TYPE_SDCH_DICTIONARY_ERROR,
- base::Bind(&NetLogSdchDictionaryFetchProblemCallback,
- SDCH_DICTIONARY_FETCH_READ_FAILED, current_request_->url(),
- true));
- DLOG(FATAL)
- << "URLRequest::Read() returned false without IO pending or error!";
- return ERR_FAILED;
- }
+ if (bytes_read < 0 || !current_request_->status().is_success()) {
+ if (current_request_->status().error() != OK)
+ return current_request_->status().error();
- return current_request_->status().error();
+ // An error with request status of OK should not happen,
+ // but there's enough machinery underneath URLRequest::Read()
+ // that this routine checks for that case.
+ net::Error error =
+ current_request_->status().status() == URLRequestStatus::CANCELED ?
+ ERR_ABORTED : ERR_FAILED;
+ current_request_->net_log().AddEventWithNetErrorCode(
+ NetLog::TYPE_SDCH_DICTIONARY_FETCH_IMPLIED_ERROR, error);
+ return error;
}
- if (bytes_read != 0)
- dictionary_.append(buffer_->data(), bytes_read);
- else
+ if (bytes_read == 0)
next_state_ = STATE_REQUEST_COMPLETE;
+ else
+ dictionary_.append(buffer_->data(), bytes_read);
return OK;
}
diff --git a/net/url_request/url_fetcher_core.cc b/net/url_request/url_fetcher_core.cc
index aae47d9..23399f3 100644
--- a/net/url_request/url_fetcher_core.cc
+++ b/net/url_request/url_fetcher_core.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
+#include "base/profiler/scoped_tracker.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
@@ -389,6 +390,11 @@
}
void URLFetcherCore::OnResponseStarted(URLRequest* request) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 URLFetcherCore::OnResponseStarted"));
+
DCHECK_EQ(request, request_.get());
DCHECK(network_task_runner_->BelongsToCurrentThread());
if (request_->status().is_success()) {
@@ -417,6 +423,11 @@
void URLFetcherCore::OnReadCompleted(URLRequest* request,
int bytes_read) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "423948 URLFetcherCore::OnReadCompleted"));
+
DCHECK(request == request_);
DCHECK(network_task_runner_->BelongsToCurrentThread());
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index 3610195..5d32c6f 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -11,6 +11,7 @@
#include "base/profiler/scoped_tracker.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
+#include "base/values.h"
#include "net/base/auth.h"
#include "net/base/host_port_pair.h"
#include "net/base/io_buffer.h"
@@ -21,6 +22,18 @@
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
+namespace {
+
+// Callback for TYPE_URL_REQUEST_FILTERS_SET net-internals event.
+base::Value* FiltersSetCallback(net::Filter* filter,
+ enum net::NetLog::LogLevel /* log_level */) {
+ base::DictionaryValue* event_params = new base::DictionaryValue();
+ event_params->SetString("filters", filter->OrderedFilterList());
+ return event_params;
+}
+
+} // namespace
+
namespace net {
URLRequestJob::URLRequestJob(URLRequest* request,
@@ -424,6 +437,10 @@
request_->GetResponseHeaderByName("content-length", &content_length);
if (!content_length.empty())
base::StringToInt64(content_length, &expected_content_size_);
+ } else {
+ request_->net_log().AddEvent(
+ NetLog::TYPE_URL_REQUEST_FILTERS_SET,
+ base::Bind(&FiltersSetCallback, base::Unretained(filter_.get())));
}
// TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
diff --git a/net/websockets/websocket_stream.cc b/net/websockets/websocket_stream.cc
index 005b6c5..c0d0c4c 100644
--- a/net/websockets/websocket_stream.cc
+++ b/net/websockets/websocket_stream.cc
@@ -8,6 +8,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
#include "base/metrics/sparse_histogram.h"
+#include "base/profiler/scoped_tracker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/load_flags.h"
@@ -222,6 +223,10 @@
};
void Delegate::OnResponseStarted(URLRequest* request) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION("423948 Delegate::OnResponseStarted"));
+
// All error codes, including OK and ABORTED, as with
// Net.ErrorCodesForMainFrame3
UMA_HISTOGRAM_SPARSE_SLOWLY("Net.WebSocket.ErrorCodes",
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index 7daabd4..2751977 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -308,7 +308,6 @@
sources += gypi_skia_core.sources
sources += gypi_skia_effects.sources
sources += gypi_skia_utils.sources
- sources += gypi_skia_pdf.sources
sources += gypi_values.skia_library_sources
if (cpu_arch == "arm") {
@@ -343,7 +342,6 @@
"//third_party/skia/include/utils/SkParsePaint.h",
"//third_party/skia/include/utils/SkParsePath.h",
"//third_party/skia/include/utils/SkRandom.h",
- "//third_party/skia/include/utils/SkWGL.h",
"//third_party/skia/src/utils/SkBitmapHasher.cpp",
"//third_party/skia/src/utils/SkBitmapHasher.h",
@@ -548,6 +546,7 @@
if (skia_support_pdf) {
deps += [ "//third_party/sfntly" ]
+ sources += gypi_skia_pdf.sources
}
if (is_android && !is_debug) {
diff --git a/skia/skia_library.gypi b/skia/skia_library.gypi
index 6879cfc..46259e5 100644
--- a/skia/skia_library.gypi
+++ b/skia/skia_library.gypi
@@ -105,7 +105,6 @@
'../third_party/skia/include/utils/SkParsePaint.h',
'../third_party/skia/include/utils/SkParsePath.h',
'../third_party/skia/include/utils/SkRandom.h',
- '../third_party/skia/include/utils/SkWGL.h',
'../third_party/skia/src/utils/SkBitmapHasher.cpp',
'../third_party/skia/src/utils/SkBitmapHasher.h',
@@ -189,7 +188,8 @@
}],
['skia_support_pdf == 0', {
'sources/': [
- ['exclude', '../third_party/skia/src/pdf/']
+ ['exclude', '../third_party/skia/src/doc/SkDocument_PDF.cpp'],
+ ['exclude', '../third_party/skia/src/pdf/'],
],
}],
['skia_support_pdf == 1', {
diff --git a/sky/viewer/cc/web_content_layer_impl.cc b/sky/viewer/cc/web_content_layer_impl.cc
index 0369b72..261d3a0 100644
--- a/sky/viewer/cc/web_content_layer_impl.cc
+++ b/sky/viewer/cc/web_content_layer_impl.cc
@@ -19,13 +19,12 @@
namespace sky_viewer_cc {
WebContentLayerImpl::WebContentLayerImpl(blink::WebContentLayerClient* client)
- : client_(client), ignore_lcd_text_change_(false) {
+ : client_(client) {
if (WebLayerImpl::UsingPictureLayer())
layer_ = make_scoped_ptr(new WebLayerImpl(PictureLayer::Create(this)));
else
layer_ = make_scoped_ptr(new WebLayerImpl(ContentLayer::Create(this)));
layer_->layer()->SetIsDrawable(true);
- can_use_lcd_text_ = layer_->layer()->can_use_lcd_text();
}
WebContentLayerImpl::~WebContentLayerImpl() {
@@ -55,31 +54,14 @@
return;
blink::WebFloatRect web_opaque;
+ bool can_use_lcd_text = false;
client_->paintContents(
- canvas,
- clip,
- can_use_lcd_text_,
- web_opaque,
+ canvas, clip, can_use_lcd_text, web_opaque,
graphics_context_status == ContentLayerClient::GRAPHICS_CONTEXT_ENABLED
? blink::WebContentLayerClient::GraphicsContextEnabled
: blink::WebContentLayerClient::GraphicsContextDisabled);
}
-void WebContentLayerImpl::DidChangeLayerCanUseLCDText() {
- // It is important to make this comparison because the LCD text status
- // here can get out of sync with that in the layer.
- if (can_use_lcd_text_ == layer_->layer()->can_use_lcd_text())
- return;
-
- // LCD text cannot be enabled once disabled.
- if (layer_->layer()->can_use_lcd_text() && ignore_lcd_text_change_)
- return;
-
- can_use_lcd_text_ = layer_->layer()->can_use_lcd_text();
- ignore_lcd_text_change_ = true;
- layer_->invalidate();
-}
-
bool WebContentLayerImpl::FillsBoundsCompletely() const {
return false;
}
diff --git a/sky/viewer/cc/web_content_layer_impl.h b/sky/viewer/cc/web_content_layer_impl.h
index 8957098..d18446f 100644
--- a/sky/viewer/cc/web_content_layer_impl.h
+++ b/sky/viewer/cc/web_content_layer_impl.h
@@ -40,7 +40,6 @@
const gfx::Rect& clip,
ContentLayerClient::GraphicsContextStatus
graphics_context_status) override;
- virtual void DidChangeLayerCanUseLCDText() override;
virtual bool FillsBoundsCompletely() const override;
scoped_ptr<WebLayerImpl> layer_;
@@ -48,8 +47,6 @@
bool draws_content_;
private:
- bool can_use_lcd_text_;
- bool ignore_lcd_text_change_;
DISALLOW_COPY_AND_ASSIGN(WebContentLayerImpl);
};
diff --git a/sky/viewer/cc/web_filter_animation_curve_impl.cc b/sky/viewer/cc/web_filter_animation_curve_impl.cc
index 6b323b2..560ca16 100644
--- a/sky/viewer/cc/web_filter_animation_curve_impl.cc
+++ b/sky/viewer/cc/web_filter_animation_curve_impl.cc
@@ -32,7 +32,8 @@
static_cast<const WebFilterOperationsImpl&>(keyframe.value())
.AsFilterOperations();
curve_->AddKeyframe(cc::FilterKeyframe::Create(
- keyframe.time(), filter_operations, CreateTimingFunction(type)));
+ base::TimeDelta::FromSecondsD(keyframe.time()), filter_operations,
+ CreateTimingFunction(type)));
}
void WebFilterAnimationCurveImpl::add(const WebFilterKeyframe& keyframe,
@@ -44,8 +45,7 @@
static_cast<const WebFilterOperationsImpl&>(keyframe.value())
.AsFilterOperations();
curve_->AddKeyframe(cc::FilterKeyframe::Create(
- keyframe.time(),
- filter_operations,
+ base::TimeDelta::FromSecondsD(keyframe.time()), filter_operations,
cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2).Pass()));
}
diff --git a/sky/viewer/cc/web_float_animation_curve_impl.cc b/sky/viewer/cc/web_float_animation_curve_impl.cc
index 2812471..f39f881 100644
--- a/sky/viewer/cc/web_float_animation_curve_impl.cc
+++ b/sky/viewer/cc/web_float_animation_curve_impl.cc
@@ -31,8 +31,9 @@
void WebFloatAnimationCurveImpl::add(const WebFloatKeyframe& keyframe,
TimingFunctionType type) {
- curve_->AddKeyframe(cc::FloatKeyframe::Create(
- keyframe.time, keyframe.value, CreateTimingFunction(type)));
+ curve_->AddKeyframe(
+ cc::FloatKeyframe::Create(base::TimeDelta::FromSecondsD(keyframe.time),
+ keyframe.value, CreateTimingFunction(type)));
}
void WebFloatAnimationCurveImpl::add(const WebFloatKeyframe& keyframe,
@@ -41,13 +42,12 @@
double x2,
double y2) {
curve_->AddKeyframe(cc::FloatKeyframe::Create(
- keyframe.time,
- keyframe.value,
+ base::TimeDelta::FromSecondsD(keyframe.time), keyframe.value,
cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2).Pass()));
}
float WebFloatAnimationCurveImpl::getValue(double time) const {
- return curve_->GetValue(time);
+ return curve_->GetValue(base::TimeDelta::FromSecondsD(time));
}
scoped_ptr<cc::AnimationCurve>
diff --git a/sky/viewer/cc/web_transform_animation_curve_impl.cc b/sky/viewer/cc/web_transform_animation_curve_impl.cc
index 11e69ae..0ad02a7 100644
--- a/sky/viewer/cc/web_transform_animation_curve_impl.cc
+++ b/sky/viewer/cc/web_transform_animation_curve_impl.cc
@@ -36,7 +36,8 @@
static_cast<const WebTransformOperationsImpl&>(keyframe.value())
.AsTransformOperations();
curve_->AddKeyframe(cc::TransformKeyframe::Create(
- keyframe.time(), transform_operations, CreateTimingFunction(type)));
+ base::TimeDelta::FromSecondsD(keyframe.time()), transform_operations,
+ CreateTimingFunction(type)));
}
void WebTransformAnimationCurveImpl::add(const WebTransformKeyframe& keyframe,
@@ -48,8 +49,7 @@
static_cast<const WebTransformOperationsImpl&>(keyframe.value())
.AsTransformOperations();
curve_->AddKeyframe(cc::TransformKeyframe::Create(
- keyframe.time(),
- transform_operations,
+ base::TimeDelta::FromSecondsD(keyframe.time()), transform_operations,
cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2).Pass()));
}
diff --git a/third_party/zlib/BUILD.gn b/third_party/zlib/BUILD.gn
index d07fd9a..810fbb7 100644
--- a/third_party/zlib/BUILD.gn
+++ b/third_party/zlib/BUILD.gn
@@ -7,9 +7,11 @@
}
static_library("zlib_x86_simd") {
- if (!is_win && (cpu_arch == "x86" || cpu_arch == "x64")) {
+ if (!is_ios && (cpu_arch == "x86" || cpu_arch == "x64")) {
sources = [ "crc_folding.c", "fill_window_sse.c" ]
- cflags = [ "-msse2", "-msse4.2", "-mpclmul" ]
+ if (!is_win || is_clang) {
+ cflags = [ "-msse4.2", "-mpclmul" ]
+ }
} else {
sources = [ "simd_stub.c"]
}
diff --git a/third_party/zlib/zlib.gyp b/third_party/zlib/zlib.gyp
index 22a48a3..bb478ce 100644
--- a/third_party/zlib/zlib.gyp
+++ b/third_party/zlib/zlib.gyp
@@ -9,15 +9,27 @@
'type': 'static_library',
'conditions': [
['OS!="ios" and (target_arch=="ia32" or target_arch=="x64")', {
- 'cflags' : ["-msse2", "-msse4.2", "-mpclmul"],
+ 'cflags' : ['-msse4.2', '-mpclmul'],
'xcode_settings' : {
- 'OTHER_CFLAGS' : ["-msse4.2", "-mpclmul"],
+ 'OTHER_CFLAGS' : ['-msse4.2', '-mpclmul'],
},
- 'sources' : [ 'crc_folding.c',
- 'fill_window_sse.c']
+ 'sources' : [
+ 'crc_folding.c',
+ 'fill_window_sse.c',
+ ],
+ 'conditions': [
+ ['OS=="win" and clang==1', {
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ 'AdditionalOptions': [ '-msse4.2', '-mpclmul' ],
+ },
+ },
+ }],
+ ],
}, {
'sources' : [ 'simd_stub.c' ],
- }], ['OS=="android"', {
+ }],
+ ['OS=="android"', {
'toolsets': ['target', 'host'],
}],
],
diff --git a/tools/clang/scripts/package.sh b/tools/clang/scripts/package.sh
index afa43bd..f00abb4 100755
--- a/tools/clang/scripts/package.sh
+++ b/tools/clang/scripts/package.sh
@@ -73,6 +73,7 @@
echo "Starting build" | tee -a buildlog.txt
set -exu
+set -o pipefail
# Do a clobber build.
rm -rf "${LLVM_BOOTSTRAP_DIR}"
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 25aa5a5..041087f 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -10,7 +10,9 @@
import re
import shutil
import subprocess
+import stat
import sys
+import time
# Do NOT CHANGE this if you don't know what you're doing -- see
# https://code.google.com/p/chromium/wiki/UpdatingClang
@@ -58,16 +60,16 @@
f.write(s)
-def DeleteFiles(dir, pattern):
- """Delete all files in dir matching pattern."""
- n = 0
- regex = re.compile(r'^' + pattern + r'$')
- for root, _, files in os.walk(dir):
- for f in files:
- if regex.match(f):
- os.remove(os.path.join(root, f))
- n += 1
- return n
+def RmTree(dir):
+ """Delete dir."""
+ def ChmodAndRetry(func, path, _):
+ # Subversion can leave read-only files around.
+ if not os.access(path, os.W_OK):
+ os.chmod(path, stat.S_IWUSR)
+ return func(path)
+ raise
+
+ shutil.rmtree(dir, onerror=ChmodAndRetry)
def ClobberChromiumBuildFiles():
@@ -75,18 +77,21 @@
print 'Clobbering Chromium build files...'
out_dir = os.path.join(CHROMIUM_DIR, 'out')
if os.path.isdir(out_dir):
- shutil.rmtree(out_dir)
+ RmTree(out_dir)
print 'Removed Chromium out dir: %s.' % (out_dir)
-def RunCommand(command, tries=1):
- """Run a command, possibly with multiple retries."""
- for i in range(0, tries):
- print 'Running %s (try #%d)' % (str(command), i + 1)
- if subprocess.call(command, shell=True) == 0:
- return
- print 'Failed.'
- sys.exit(1)
+def RunCommand(command, fail_hard=True):
+ """Run command and return success (True) or failure; or if fail_hard is
+ True, exit on failure."""
+
+ print 'Running %s' % (str(command))
+ if subprocess.call(command, shell=True) == 0:
+ return True
+ print 'Failed.'
+ if fail_hard:
+ sys.exit(1)
+ return False
def CopyFile(src, dst):
@@ -110,8 +115,17 @@
def Checkout(name, url, dir):
"""Checkout the SVN module at url into dir. Use name for the log message."""
print "Checking out %s r%s into '%s'" % (name, LLVM_WIN_REVISION, dir)
- RunCommand(['svn', 'checkout', '--force',
- url + '@' + LLVM_WIN_REVISION, dir], tries=2)
+
+ command = ['svn', 'checkout', '--force', url + '@' + LLVM_WIN_REVISION, dir]
+ if RunCommand(command, fail_hard=False):
+ return
+
+ if os.path.isdir(dir):
+ print "Removing %s." % (dir)
+ RmTree(dir)
+
+ print "Retrying."
+ RunCommand(command)
def AddCMakeToPath():
diff --git a/tools/valgrind/chrome_tests.py b/tools/valgrind/chrome_tests.py
index 27d554e..8f5432f 100755
--- a/tools/valgrind/chrome_tests.py
+++ b/tools/valgrind/chrome_tests.py
@@ -470,9 +470,6 @@
def TestUIBaseUnit(self):
return self.SimpleTest("chrome", "ui_base_unittests")
- def TestUIUnit(self):
- return self.SimpleTest("chrome", "ui_unittests")
-
def TestURL(self):
return self.SimpleTest("chrome", "url_unittests")
@@ -715,7 +712,6 @@
"sync_integration_tests": TestSyncIntegration,
"sync_integration": TestSyncIntegration,
"ui_base_unit": TestUIBaseUnit, "ui_base_unittests": TestUIBaseUnit,
- "ui_unit": TestUIUnit, "ui_unittests": TestUIUnit,
"unit": TestUnit, "unit_tests": TestUnit,
"url": TestURL, "url_unittests": TestURL,
"views": TestViews, "views_unittests": TestViews,
diff --git a/ui/compositor/float_animation_curve_adapter.cc b/ui/compositor/float_animation_curve_adapter.cc
index 3b5e155..d40d701 100644
--- a/ui/compositor/float_animation_curve_adapter.cc
+++ b/ui/compositor/float_animation_curve_adapter.cc
@@ -4,6 +4,8 @@
#include "ui/compositor/float_animation_curve_adapter.h"
+#include "cc/base/time_util.h"
+
namespace ui {
FloatAnimationCurveAdapter::FloatAnimationCurveAdapter(
@@ -26,12 +28,12 @@
tween_type_, initial_value_, target_value_, duration_));
}
-float FloatAnimationCurveAdapter::GetValue(double t) const {
- if (t >= duration_.InSecondsF())
+float FloatAnimationCurveAdapter::GetValue(base::TimeDelta t) const {
+ if (t >= duration_)
return target_value_;
- if (t <= 0.0)
+ if (t <= base::TimeDelta())
return initial_value_;
- double progress = t / duration_.InSecondsF();
+ double progress = cc::TimeUtil::Divide(t, duration_);
return gfx::Tween::FloatValueBetween(
gfx::Tween::CalculateValue(tween_type_, progress),
initial_value_,
diff --git a/ui/compositor/float_animation_curve_adapter.h b/ui/compositor/float_animation_curve_adapter.h
index 88d5870..dc665d4 100644
--- a/ui/compositor/float_animation_curve_adapter.h
+++ b/ui/compositor/float_animation_curve_adapter.h
@@ -23,7 +23,7 @@
// FloatAnimationCurve implementation.
base::TimeDelta Duration() const override;
scoped_ptr<cc::AnimationCurve> Clone() const override;
- float GetValue(double t) const override;
+ float GetValue(base::TimeDelta t) const override;
private:
gfx::Tween::Type tween_type_;
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h
index 74781d1..eb4628d 100644
--- a/ui/compositor/layer.h
+++ b/ui/compositor/layer.h
@@ -333,7 +333,6 @@
SkCanvas* canvas,
const gfx::Rect& clip,
ContentLayerClient::GraphicsContextStatus gc_status) override;
- void DidChangeLayerCanUseLCDText() override {}
bool FillsBoundsCompletely() const override;
cc::Layer* cc_layer() { return cc_layer_; }
diff --git a/ui/compositor/transform_animation_curve_adapter.cc b/ui/compositor/transform_animation_curve_adapter.cc
index 2c11488..1b67ca2 100644
--- a/ui/compositor/transform_animation_curve_adapter.cc
+++ b/ui/compositor/transform_animation_curve_adapter.cc
@@ -4,6 +4,8 @@
#include "ui/compositor/transform_animation_curve_adapter.h"
+#include "cc/base/time_util.h"
+
namespace ui {
TransformAnimationCurveAdapter::TransformAnimationCurveAdapter(
@@ -32,12 +34,12 @@
}
gfx::Transform TransformAnimationCurveAdapter::GetValue(
- double t) const {
- if (t >= duration_.InSecondsF())
+ base::TimeDelta t) const {
+ if (t >= duration_)
return target_value_;
- if (t <= 0.0)
+ if (t <= base::TimeDelta())
return initial_value_;
- double progress = t / duration_.InSecondsF();
+ double progress = cc::TimeUtil::Divide(t, duration_);
gfx::DecomposedTransform to_return;
gfx::BlendDecomposedTransforms(&to_return,
@@ -80,7 +82,8 @@
: base_curve_(base_curve),
initial_value_(initial_value),
duration_(duration) {
- effective_initial_value_ = base_curve_.GetValue(0.0) * initial_value_;
+ effective_initial_value_ =
+ base_curve_.GetValue(base::TimeDelta()) * initial_value_;
}
InverseTransformCurveAdapter::~InverseTransformCurveAdapter() {
@@ -95,9 +98,8 @@
new InverseTransformCurveAdapter(base_curve_, initial_value_, duration_));
}
-gfx::Transform InverseTransformCurveAdapter::GetValue(
- double t) const {
- if (t <= 0.0)
+gfx::Transform InverseTransformCurveAdapter::GetValue(base::TimeDelta t) const {
+ if (t <= base::TimeDelta())
return initial_value_;
gfx::Transform base_transform = base_curve_.GetValue(t);
diff --git a/ui/compositor/transform_animation_curve_adapter.h b/ui/compositor/transform_animation_curve_adapter.h
index c08024d..5bbe6a3 100644
--- a/ui/compositor/transform_animation_curve_adapter.h
+++ b/ui/compositor/transform_animation_curve_adapter.h
@@ -27,7 +27,7 @@
// TransformAnimationCurve implementation.
base::TimeDelta Duration() const override;
scoped_ptr<AnimationCurve> Clone() const override;
- gfx::Transform GetValue(double t) const override;
+ gfx::Transform GetValue(base::TimeDelta t) const override;
bool AnimatedBoundsForBox(const gfx::BoxF& box,
gfx::BoxF* bounds) const override;
bool AffectsScale() const override;
@@ -57,7 +57,7 @@
base::TimeDelta Duration() const override;
scoped_ptr<AnimationCurve> Clone() const override;
- gfx::Transform GetValue(double t) const override;
+ gfx::Transform GetValue(base::TimeDelta t) const override;
bool AnimatedBoundsForBox(const gfx::BoxF& box,
gfx::BoxF* bounds) const override;
bool AffectsScale() const override;