Update from https://crrev.com/308331
Fix ui/compositor/compositor.(h|cpp) based on http://crrev.com/738983002
Fix sky/engine based on current Blink code
R=qsr@chromium.org
Review URL: https://codereview.chromium.org/812543002
diff --git a/DEPS b/DEPS
index b65d15f..79ed2f1 100644
--- a/DEPS
+++ b/DEPS
@@ -22,19 +22,19 @@
'libcxx_revision': '48198f9110397fff47fe7c37cbfa296be7d44d3d',
'libcxxabi_revision': '4ad1009ab3a59fa7a6896d74d5e4de5885697f95',
'sfntly_revision': '1bdaae8fc788a5ac8936d68bf24f37d977a13dac',
- 'skia_revision': '3054be16dfdb0d06233770cbfc338958edef44ea',
+ 'skia_revision': '912ed6ebb8e2813e72ed7a3dec3b6710ba7e7405',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling Skia
# and V8 without interference from each other.
- 'v8_revision': 'a2359f44508afdb9abe8cb89cdfb02a7b48095b2',
+ 'v8_revision': '74869d9a9122e26952e517bcc7ad990078644047',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling ANGLE
# and whatever else without interference from each other.
- "angle_revision": "16545669136028420f67ac496c45c2e9a32ed5a9",
+ "angle_revision": "797ff4c0ecf1b4950f6948175ea38ccbe888de7f",
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling build tools
# and whatever else without interference from each other.
- 'buildtools_revision': '05dd6a24723170d7c6ff35b537ee02947f619891',
+ 'buildtools_revision': '4995faa4a7ad968f1fa1917c26edd5cea295582f',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling PDFium
# and whatever else without interference from each other.
@@ -78,7 +78,7 @@
Var('chromium_git') + '/angle/angle.git' + '@' + Var('angle_revision'),
'src/third_party/icu':
- Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '53ecf0f68b27a004bef5526553b8e5f6c235b80b',
+ Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'b0932a04c79198b0fd44282304eb48a5c1850ea3',
'src/third_party/libc++/trunk':
Var('chromium_git') + '/chromium/llvm-project/libcxx.git' + '@' + Var('libcxx_revision'),
@@ -152,7 +152,7 @@
Var('chromium_git') + '/external/jsr-305.git' + '@' + '642c508235471f7220af6d5df2d3210e3bfc0919',
'src/third_party/android_tools':
- Var('chromium_git') + '/android_tools.git' + '@' + '4f723e2a5fa5b7b8a198072ac19b92344be2b271',
+ Var('chromium_git') + '/android_tools.git' + '@' + '8fe116f93f350dcf73c6fe70db893985bf1b91d5',
'src/third_party/freetype':
Var('chromium_git') + '/chromium/src/third_party/freetype.git' + '@' + 'a2b9955b49034a51dfbc8bf9f4e9d312149cecac',
diff --git a/base/BUILD.gn b/base/BUILD.gn
index fe03aac..de464f9 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -121,6 +121,8 @@
"cancelable_callback.h",
"command_line.cc",
"command_line.h",
+ "chromeos/memory_pressure_observer_chromeos.cc",
+ "chromeos/memory_pressure_observer_chromeos.h",
"compiler_specific.h",
"containers/adapters.h",
"containers/hash_tables.h",
@@ -249,6 +251,8 @@
"ios/ios_util.mm",
"ios/scoped_critical_action.h",
"ios/scoped_critical_action.mm",
+ "ios/weak_nsobject.h",
+ "ios/weak_nsobject.mm",
"json/json_file_value_serializer.cc",
"json/json_file_value_serializer.h",
"json/json_parser.cc",
@@ -771,6 +775,12 @@
"//third_party/modp_b64",
]
+ # Allow more direct string conversions on platforms with native utf8
+ # strings
+ if (is_mac || is_ios || is_chromeos) {
+ defines += [ "SYSTEM_NATIVE_UTF8" ]
+ }
+
if (is_android) {
sources += [
"memory/discardable_memory_ashmem_allocator.cc",
@@ -1187,6 +1197,7 @@
"i18n/time_formatting_unittest.cc",
"i18n/timezone_unittest.cc",
"ios/device_util_unittest.mm",
+ "ios/weak_nsobject_unittest.mm",
"json/json_parser_unittest.cc",
"json/json_reader_unittest.cc",
"json/json_value_converter_unittest.cc",
diff --git a/base/base.gyp b/base/base.gyp
index ec5444a..d3a55b8 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -519,6 +519,7 @@
'i18n/time_formatting_unittest.cc',
'i18n/timezone_unittest.cc',
'ios/device_util_unittest.mm',
+ 'ios/weak_nsobject_unittest.mm',
'json/json_parser_unittest.cc',
'json/json_reader_unittest.cc',
'json/json_value_converter_unittest.cc',
diff --git a/base/base.gypi b/base/base.gypi
index f945166..5ec4142 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -122,6 +122,8 @@
'callback_internal.h',
'callback_list.h',
'cancelable_callback.h',
+ 'chromeos/memory_pressure_observer_chromeos.cc',
+ 'chromeos/memory_pressure_observer_chromeos.h',
'command_line.cc',
'command_line.h',
'compiler_specific.h',
@@ -251,6 +253,8 @@
'ios/ios_util.mm',
'ios/scoped_critical_action.h',
'ios/scoped_critical_action.mm',
+ 'ios/weak_nsobject.h',
+ 'ios/weak_nsobject.mm',
'json/json_file_value_serializer.cc',
'json/json_file_value_serializer.h',
'json/json_parser.cc',
@@ -979,6 +983,11 @@
['OS == "win" and >(nacl_untrusted_build)==1', {
'sources/': [ ['exclude', '\\.h$'] ],
}],
+ # Enable more direct string conversions on platforms with native utf8
+ # strings
+ ['OS=="mac" or OS=="ios" or <(chromeos)==1 or <(chromecast)==1', {
+ 'defines': ['SYSTEM_NATIVE_UTF8'],
+ }],
],
}],
['base_i18n_target==1', {
diff --git a/base/chromeos/OWNERS b/base/chromeos/OWNERS
new file mode 100644
index 0000000..8fda46a
--- /dev/null
+++ b/base/chromeos/OWNERS
@@ -0,0 +1,3 @@
+skuhne@chromium.org
+oshima@chromium.org
+
diff --git a/base/chromeos/memory_pressure_observer_chromeos.cc b/base/chromeos/memory_pressure_observer_chromeos.cc
new file mode 100644
index 0000000..d991e3f
--- /dev/null
+++ b/base/chromeos/memory_pressure_observer_chromeos.cc
@@ -0,0 +1,116 @@
+// 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/chromeos/memory_pressure_observer_chromeos.h"
+
+#include "base/process/process_metrics.h"
+#include "base/time/time.h"
+
+namespace base {
+
+namespace {
+
+// The time between memory pressure checks.
+const int kMemoryPressureIntervalInMS = 1000;
+
+// Converts free percent of memory into a memory pressure value.
+MemoryPressureObserverChromeOS::MemoryPressureLevel
+GetMemoryPressureLevelFromFillLevel(
+ int memory_fill_level) {
+ if (memory_fill_level < 50)
+ return MemoryPressureObserverChromeOS::MEMORY_PRESSURE_LEVEL_LOW;
+ if (memory_fill_level < 75)
+ return MemoryPressureObserverChromeOS::MEMORY_PRESSURE_LEVEL_MODERATE;
+ if (memory_fill_level < 90)
+ return MemoryPressureObserverChromeOS::MEMORY_PRESSURE_LEVEL_HIGH;
+ return MemoryPressureObserverChromeOS::MEMORY_PRESSURE_LEVEL_CRITICAL;
+}
+
+// Gets the used ChromeOS memory in percent.
+int GetUsedMemoryInPercent() {
+ base::SystemMemoryInfoKB info;
+ if (!base::GetSystemMemoryInfo(&info)) {
+ VLOG(1) << "Cannot determine the free memory of the system.";
+ return 0;
+ }
+ // TODO(skuhne): Instead of adding the kernel memory pressure calculation
+ // logic here, we should have a kernel mechanism similar to the low memory
+ // notifier in ChromeOS which offers multiple pressure states.
+ // To track this, we have crbug.com/381196.
+
+ // The available memory consists of "real" and virtual (z)ram memory.
+ // Since swappable memory uses a non pre-deterministic compression and
+ // the compression creates its own "dynamic" in the system, it gets
+ // de-emphasized by the |kSwapWeight| factor.
+ const int kSwapWeight = 4;
+
+ // The total memory we have is the "real memory" plus the virtual (z)ram.
+ int total_memory = info.total + info.swap_total / kSwapWeight;
+
+ // The kernel internally uses 50MB.
+ const int kMinFileMemory = 50 * 1024;
+
+ // Most file memory can be easily reclaimed.
+ int file_memory = info.active_file + info.inactive_file;
+ // unless it is dirty or it's a minimal portion which is required.
+ file_memory -= info.dirty + kMinFileMemory;
+
+ // Available memory is the sum of free, swap and easy reclaimable memory.
+ int available_memory =
+ info.free + info.swap_free / kSwapWeight + file_memory;
+
+ DCHECK(available_memory < total_memory);
+ int percentage = ((total_memory - available_memory) * 100) / total_memory;
+ return percentage;
+}
+
+} // namespace
+
+MemoryPressureObserverChromeOS::MemoryPressureObserverChromeOS()
+ : current_memory_pressure_level_(MEMORY_PRESSURE_LEVEL_LOW) {
+ StartObserving();
+}
+
+MemoryPressureObserverChromeOS::~MemoryPressureObserverChromeOS() {
+ StopObserving();
+}
+
+void MemoryPressureObserverChromeOS::StartObserving() {
+ timer_.Start(FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kMemoryPressureIntervalInMS),
+ base::Bind(&MemoryPressureObserverChromeOS::CheckMemoryPressure,
+ base::Unretained(this)));
+}
+
+void MemoryPressureObserverChromeOS::StopObserving() {
+ // If StartObserving failed, StopObserving will still get called.
+ timer_.Stop();
+}
+
+void MemoryPressureObserverChromeOS::CheckMemoryPressure() {
+ MemoryPressureLevel old_pressure = current_memory_pressure_level_;
+ MemoryPressureLevel new_pressure =
+ GetMemoryPressureLevelFromFillLevel(GetUsedMemoryInPercent());
+ if (old_pressure != new_pressure) {
+ current_memory_pressure_level_ = new_pressure;
+ switch (new_pressure) {
+ case MEMORY_PRESSURE_LEVEL_LOW:
+ // The |MemoryPressureListener| does currently not support this.
+ break;
+ case MEMORY_PRESSURE_LEVEL_MODERATE:
+ MemoryPressureListener::NotifyMemoryPressure(
+ MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
+ break;
+ case MEMORY_PRESSURE_LEVEL_HIGH:
+ // The |MemoryPressureListener| does currently not support this.
+ break;
+ case MEMORY_PRESSURE_LEVEL_CRITICAL:
+ MemoryPressureListener::NotifyMemoryPressure(
+ MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
+ break;
+ }
+ }
+}
+
+} // namespace base
diff --git a/base/chromeos/memory_pressure_observer_chromeos.h b/base/chromeos/memory_pressure_observer_chromeos.h
new file mode 100644
index 0000000..92b1c48
--- /dev/null
+++ b/base/chromeos/memory_pressure_observer_chromeos.h
@@ -0,0 +1,81 @@
+// 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_CHROMEOS_MEMORY_PRESSURE_OBSERVER_CHROMEOS_H_
+#define BASE_CHROMEOS_MEMORY_PRESSURE_OBSERVER_CHROMEOS_H_
+
+#include "base/base_export.h"
+#include "base/macros.h"
+#include "base/memory/memory_pressure_listener.h"
+#include "base/timer/timer.h"
+
+namespace base {
+
+////////////////////////////////////////////////////////////////////////////////
+// MemoryPressureObserverChromeOS
+//
+// A class to handle the observation of our free memory. It notifies the
+// MemoryPressureListener of memory fill level changes, so that it can take
+// action to reduce memory resources accordingly.
+//
+class BASE_EXPORT MemoryPressureObserverChromeOS {
+ public:
+ // This is like the |MemoryPressureListener::MemoryPressureLevel| but it has
+ // more states to allow for a finer grained control as well as a request for
+ // the current status.
+ // TODO(skuhne): If the |MemoryPressureListener| will get extended to support
+ // all these levels, this can be removed.
+ enum MemoryPressureLevel {
+ // There is enough memory available to use.
+ MEMORY_PRESSURE_LEVEL_LOW = 0,
+
+ // Modules are advised to free buffers that are cheap to re-allocate and not
+ // immediately needed.
+ MEMORY_PRESSURE_LEVEL_MODERATE = 1,
+
+ // Modules are advised that they might get unloaded dependent on the OS.
+ // As such they should start to release more memory if possible.
+ MEMORY_PRESSURE_LEVEL_HIGH = 2,
+
+ // At this level, modules are advised to free all possible memory. The
+ // alternative is to be killed by the system, which means all memory will
+ // have to be re-created, plus the cost of a cold start.
+ MEMORY_PRESSURE_LEVEL_CRITICAL = 3,
+ };
+
+ MemoryPressureObserverChromeOS();
+ ~MemoryPressureObserverChromeOS();
+
+ // Get the current memory pressure level.
+ MemoryPressureLevel GetCurrentPressureLevel() {
+ return current_memory_pressure_level_;
+ }
+
+ private:
+ // Starts observing the memory fill level.
+ // Calls to StartObserving should always be matched with calls to
+ // StopObserving.
+ void StartObserving();
+
+ // Stop observing the memory fill level.
+ // May be safely called if StartObserving has not been called.
+ void StopObserving();
+
+ // The function which gets periodically be called to check any changes in the
+ // memory pressure.
+ void CheckMemoryPressure();
+
+ // The current memory pressure.
+ MemoryPressureLevel current_memory_pressure_level_;
+
+ // A periodic timer to check for resource pressure changes. This will get
+ // replaced by a kernel triggered event system (see crbug.com/381196).
+ base::RepeatingTimer<MemoryPressureObserverChromeOS> timer_;
+
+ DISALLOW_COPY_AND_ASSIGN(MemoryPressureObserverChromeOS);
+};
+
+} // namespace base
+
+#endif // BASE_CHROMEOS_MEMORY_PRESSURE_OBSERVER_CHROMEOS_H_
diff --git a/base/debug/trace_event_impl.cc b/base/debug/trace_event_impl.cc
index 1a64eb0..4591286 100644
--- a/base/debug/trace_event_impl.cc
+++ b/base/debug/trace_event_impl.cc
@@ -2358,24 +2358,6 @@
str.at(str.length() - 1) == ' ';
}
-bool CategoryFilter::DoesCategoryGroupContainCategory(
- const char* category_group,
- const char* category) const {
- DCHECK(category);
- CStringTokenizer category_group_tokens(category_group,
- category_group + strlen(category_group), ",");
- while (category_group_tokens.GetNext()) {
- std::string category_group_token = category_group_tokens.token();
- // Don't allow empty tokens, nor tokens with leading or trailing space.
- DCHECK(!CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
- category_group_token))
- << "Disallowed category string";
- if (MatchPattern(category_group_token.c_str(), category))
- return true;
- }
- return false;
-}
-
CategoryFilter::CategoryFilter(const std::string& filter_string) {
if (!filter_string.empty())
Initialize(filter_string);
@@ -2483,30 +2465,61 @@
const char* category_group_name) const {
// TraceLog should call this method only as part of enabling/disabling
// categories.
+
+ bool had_enabled_by_default = false;
+ DCHECK(category_group_name);
+ CStringTokenizer category_group_tokens(
+ category_group_name, category_group_name + strlen(category_group_name),
+ ",");
+ while (category_group_tokens.GetNext()) {
+ std::string category_group_token = category_group_tokens.token();
+ // Don't allow empty tokens, nor tokens with leading or trailing space.
+ DCHECK(!CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
+ category_group_token))
+ << "Disallowed category string";
+ if (IsCategoryEnabled(category_group_token.c_str())) {
+ return true;
+ }
+ if (!MatchPattern(category_group_token.c_str(),
+ TRACE_DISABLED_BY_DEFAULT("*")))
+ had_enabled_by_default = true;
+ }
+ // Do a second pass to check for explicitly disabled categories
+ // (those explicitly enabled have priority due to first pass).
+ category_group_tokens.Reset();
+ while (category_group_tokens.GetNext()) {
+ std::string category_group_token = category_group_tokens.token();
+ for (StringList::const_iterator ci = excluded_.begin();
+ ci != excluded_.end(); ++ci) {
+ if (MatchPattern(category_group_token.c_str(), ci->c_str()))
+ return false;
+ }
+ }
+ // If the category group is not excluded, and there are no included patterns
+ // we consider this category group enabled, as long as it had categories
+ // other than disabled-by-default.
+ return included_.empty() && had_enabled_by_default;
+}
+
+bool CategoryFilter::IsCategoryEnabled(const char* category_name) const {
StringList::const_iterator ci;
// Check the disabled- filters and the disabled-* wildcard first so that a
// "*" filter does not include the disabled.
for (ci = disabled_.begin(); ci != disabled_.end(); ++ci) {
- if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str()))
+ if (MatchPattern(category_name, ci->c_str()))
return true;
}
- if (DoesCategoryGroupContainCategory(category_group_name,
- TRACE_DISABLED_BY_DEFAULT("*")))
+
+ if (MatchPattern(category_name, TRACE_DISABLED_BY_DEFAULT("*")))
return false;
for (ci = included_.begin(); ci != included_.end(); ++ci) {
- if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str()))
+ if (MatchPattern(category_name, ci->c_str()))
return true;
}
- for (ci = excluded_.begin(); ci != excluded_.end(); ++ci) {
- if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str()))
- return false;
- }
- // If the category group is not excluded, and there are no included patterns
- // we consider this pattern enabled.
- return included_.empty();
+ return false;
}
bool CategoryFilter::HasIncludedPatterns() const {
diff --git a/base/debug/trace_event_impl.h b/base/debug/trace_event_impl.h
index ce2e017..c80826c 100644
--- a/base/debug/trace_event_impl.h
+++ b/base/debug/trace_event_impl.h
@@ -320,8 +320,8 @@
// categories are distinguished from included categories by the prefix '-'.
std::string ToString() const;
- // Determines whether category group would be enabled or
- // disabled by this category filter.
+ // Returns true if at least one category in the list is enabled by this
+ // category filter.
bool IsCategoryGroupEnabled(const char* category_group) const;
// Return a list of the synthetic delays specified in this category filter.
@@ -341,6 +341,9 @@
private:
FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, CategoryFilter);
+ // Returns true if category is enable according to this filter.
+ bool IsCategoryEnabled(const char* category_name) const;
+
static bool IsEmptyOrContainsLeadingOrTrailingWhitespace(
const std::string& str);
@@ -351,9 +354,6 @@
void WriteString(const StringList& delays, std::string* out) const;
bool HasIncludedPatterns() const;
- bool DoesCategoryGroupContainCategory(const char* category_group,
- const char* category) const;
-
StringList included_;
StringList disabled_;
StringList excluded_;
diff --git a/base/debug/trace_event_unittest.cc b/base/debug/trace_event_unittest.cc
index 0904954..85cf4eb 100644
--- a/base/debug/trace_event_unittest.cc
+++ b/base/debug/trace_event_unittest.cc
@@ -1615,6 +1615,22 @@
EXPECT_FIND_("disabled-by-default-cc");
EXPECT_FIND_("other_included");
}
+
+ Clear();
+
+ BeginSpecificTrace("other_included");
+ TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("cc") ",other_included",
+ "first", TRACE_EVENT_SCOPE_THREAD);
+ TRACE_EVENT_INSTANT0("other_included," TRACE_DISABLED_BY_DEFAULT("cc"),
+ "second", TRACE_EVENT_SCOPE_THREAD);
+ EndTraceAndFlush();
+
+ {
+ const DictionaryValue* item = NULL;
+ ListValue& trace_parsed = trace_parsed_;
+ EXPECT_FIND_("disabled-by-default-cc,other_included");
+ EXPECT_FIND_("other_included,disabled-by-default-cc");
+ }
}
TEST_F(TraceEventTestFixture, NormallyNoDeepCopy) {
diff --git a/base/files/file_path.cc b/base/files/file_path.cc
index bf37be6..33d5ca1 100644
--- a/base/files/file_path.cc
+++ b/base/files/file_path.cc
@@ -593,7 +593,7 @@
}
std::string FilePath::AsUTF8Unsafe() const {
-#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
+#if defined(SYSTEM_NATIVE_UTF8)
return value();
#else
return WideToUTF8(SysNativeMBToWide(value()));
@@ -601,7 +601,7 @@
}
string16 FilePath::AsUTF16Unsafe() const {
-#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
+#if defined(SYSTEM_NATIVE_UTF8)
return UTF8ToUTF16(value());
#else
return WideToUTF16(SysNativeMBToWide(value()));
@@ -610,7 +610,7 @@
// static
FilePath FilePath::FromUTF8Unsafe(const std::string& utf8) {
-#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
+#if defined(SYSTEM_NATIVE_UTF8)
return FilePath(utf8);
#else
return FilePath(SysWideToNativeMB(UTF8ToWide(utf8)));
@@ -619,7 +619,7 @@
// static
FilePath FilePath::FromUTF16Unsafe(const string16& utf16) {
-#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
+#if defined(SYSTEM_NATIVE_UTF8)
return FilePath(UTF16ToUTF8(utf16));
#else
return FilePath(SysWideToNativeMB(UTF16ToWide(utf16)));
diff --git a/base/ios/weak_nsobject.h b/base/ios/weak_nsobject.h
new file mode 100644
index 0000000..46aecb5
--- /dev/null
+++ b/base/ios/weak_nsobject.h
@@ -0,0 +1,166 @@
+// Copyright 2013 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_IOS_WEAK_NSOBJECT_H_
+#define BASE_IOS_WEAK_NSOBJECT_H_
+
+#import <Foundation/Foundation.h>
+#import <objc/runtime.h>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/threading/non_thread_safe.h"
+#include "base/threading/thread_checker.h"
+
+// WeakNSObject<> is patterned after scoped_nsobject<>, but instead of
+// maintaining ownership of an NSObject subclass object, it will nil itself out
+// when the object is deallocated.
+//
+// WeakNSProtocol<> has the same behavior as WeakNSObject, but can be used
+// with protocols.
+//
+// Example usage (base::WeakNSObject<T>):
+// scoped_nsobject<Foo> foo([[Foo alloc] init]);
+// WeakNSObject<Foo> weak_foo; // No pointer
+// weak_foo.reset(foo) // Now a weak reference is kept.
+// [weak_foo description]; // Returns [foo description].
+// foo.reset(); // The reference is released.
+// [weak_foo description]; // Returns nil, as weak_foo is pointing to nil.
+//
+//
+// Implementation wise a WeakNSObject keeps a reference to a refcounted
+// WeakContainer. There is one unique instance of a WeakContainer per watched
+// NSObject, this relationship is maintained via the ObjectiveC associated
+// object API, indirectly via an ObjectiveC CRBWeakNSProtocolSentinel class.
+//
+// The implementation assumes that the tracked object will be released on the
+// same thread that the WeakNSObject is created on.
+//
+namespace base {
+
+// WeakContainer keeps a weak pointer to an object and clears it when it
+// receives nullify() from the object's sentinel.
+class WeakContainer : public base::RefCountedThreadSafe<WeakContainer> {
+ public:
+ WeakContainer(id object) : object_(object) {}
+ id object() { return object_; }
+ void nullify() {
+ DCHECK(checker_.CalledOnValidThread());
+ object_ = nil;
+ }
+
+ private:
+ friend base::RefCountedThreadSafe<WeakContainer>;
+ ~WeakContainer() {}
+ base::ThreadChecker checker_;
+ id object_;
+};
+
+} // namespace base
+
+// Sentinel for observing the object contained in the weak pointer. The object
+// will be deleted when the weak object is deleted and will notify its
+// container.
+@interface CRBWeakNSProtocolSentinel : NSObject
+// Return the only associated container for this object. There can be only one.
+// Will return null if object is nil .
++ (scoped_refptr<base::WeakContainer>)containerForObject:(id)object;
+@end
+
+namespace base {
+
+// Base class for all WeakNSObject derivatives.
+template <typename NST>
+class WeakNSProtocol : public base::NonThreadSafe {
+ public:
+ explicit WeakNSProtocol(NST object = nil) {
+ container_ = [CRBWeakNSProtocolSentinel containerForObject:object];
+ }
+
+ WeakNSProtocol(const WeakNSProtocol<NST>& that) {
+ container_ = that.container_;
+ }
+
+ ~WeakNSProtocol() {
+ // A WeakNSProtocol object can be allocated on one thread and released on
+ // another. This is not the case for the contained object.
+ DetachFromThread();
+ }
+
+ void reset(NST object = nil) {
+ DCHECK(CalledOnValidThread());
+ container_ = [CRBWeakNSProtocolSentinel containerForObject:object];
+ }
+
+ NST get() const {
+ DCHECK(CalledOnValidThread());
+ if (!container_.get())
+ return nil;
+ return container_->object();
+ }
+
+ WeakNSProtocol& operator=(const WeakNSProtocol<NST>& that) {
+ DCHECK(CalledOnValidThread());
+ container_ = that.container_;
+ return *this;
+ }
+
+ bool operator==(NST that) const {
+ DCHECK(CalledOnValidThread());
+ return get() == that;
+ }
+
+ bool operator!=(NST that) const { return get() != that; }
+
+ operator NST() const { return get(); }
+
+ private:
+ // Refecounted reference to the container tracking the ObjectiveC object this
+ // class encapsulates.
+ scoped_refptr<base::WeakContainer> container_;
+};
+
+// Free functions
+template <class NST>
+bool operator==(NST p1, const WeakNSProtocol<NST>& p2) {
+ return p1 == p2.get();
+}
+
+template <class NST>
+bool operator!=(NST p1, const WeakNSProtocol<NST>& p2) {
+ return p1 != p2.get();
+}
+
+template <typename NST>
+class WeakNSObject : public WeakNSProtocol<NST*> {
+ public:
+ explicit WeakNSObject(NST* object = nil) : WeakNSProtocol<NST*>(object) {}
+
+ WeakNSObject(const WeakNSObject<NST>& that) : WeakNSProtocol<NST*>(that) {}
+
+ WeakNSObject& operator=(const WeakNSObject<NST>& that) {
+ WeakNSProtocol<NST*>::operator=(that);
+ return *this;
+ }
+};
+
+// Specialization to make WeakNSObject<id> work.
+template <>
+class WeakNSObject<id> : public WeakNSProtocol<id> {
+ public:
+ explicit WeakNSObject(id object = nil) : WeakNSProtocol<id>(object) {}
+
+ WeakNSObject(const WeakNSObject<id>& that) : WeakNSProtocol<id>(that) {}
+
+ WeakNSObject& operator=(const WeakNSObject<id>& that) {
+ WeakNSProtocol<id>::operator=(that);
+ return *this;
+ }
+};
+
+} // namespace base
+
+#endif // BASE_IOS_WEAK_NSOBJECT_H_
diff --git a/base/ios/weak_nsobject.mm b/base/ios/weak_nsobject.mm
new file mode 100644
index 0000000..36f9d3e
--- /dev/null
+++ b/base/ios/weak_nsobject.mm
@@ -0,0 +1,61 @@
+// Copyright 2013 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/ios/weak_nsobject.h"
+
+#include "base/mac/scoped_nsautorelease_pool.h"
+#include "base/mac/scoped_nsobject.h"
+
+namespace {
+// The key needed by objc_setAssociatedObject.
+char sentinelObserverKey_;
+}
+
+@interface CRBWeakNSProtocolSentinel ()
+// Container to notify on dealloc.
+@property(readonly, assign) scoped_refptr<base::WeakContainer> container;
+// Designed initializer.
+- (id)initWithContainer:(scoped_refptr<base::WeakContainer>)container;
+@end
+
+@implementation CRBWeakNSProtocolSentinel
+
+@synthesize container = container_;
+
++ (scoped_refptr<base::WeakContainer>)containerForObject:(id)object {
+ if (object == nil)
+ return nullptr;
+ // The autoreleasePool is needed here as the call to objc_getAssociatedObject
+ // returns an autoreleased object which is better released sooner than later.
+ base::mac::ScopedNSAutoreleasePool pool;
+ CRBWeakNSProtocolSentinel* sentinel =
+ objc_getAssociatedObject(object, &sentinelObserverKey_);
+ if (!sentinel) {
+ base::scoped_nsobject<CRBWeakNSProtocolSentinel> newSentinel(
+ [[CRBWeakNSProtocolSentinel alloc]
+ initWithContainer:new base::WeakContainer(object)]);
+ sentinel = newSentinel;
+ objc_setAssociatedObject(object, &sentinelObserverKey_, sentinel,
+ OBJC_ASSOCIATION_RETAIN);
+ // The retain count is 2. One retain is due to the alloc, the other to the
+ // association with the weak object.
+ DCHECK_EQ(2u, [sentinel retainCount]);
+ }
+ return [sentinel container];
+}
+
+- (id)initWithContainer:(scoped_refptr<base::WeakContainer>)container {
+ DCHECK(container.get());
+ self = [super init];
+ if (self)
+ container_ = container;
+ return self;
+}
+
+- (void)dealloc {
+ self.container->nullify();
+ [super dealloc];
+}
+
+@end
diff --git a/base/ios/weak_nsobject_unittest.mm b/base/ios/weak_nsobject_unittest.mm
new file mode 100644
index 0000000..9758aed
--- /dev/null
+++ b/base/ios/weak_nsobject_unittest.mm
@@ -0,0 +1,97 @@
+// Copyright 2013 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/basictypes.h"
+#include "base/ios/weak_nsobject.h"
+#include "base/mac/scoped_nsobject.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::WeakNSObject;
+
+namespace {
+
+TEST(WeakNSObjectTest, WeakNSObject) {
+ base::scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
+ WeakNSObject<NSObject> w1(p1);
+ EXPECT_TRUE(w1);
+ p1.reset();
+ EXPECT_FALSE(w1);
+}
+
+TEST(WeakNSObjectTest, MultipleWeakNSObject) {
+ base::scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
+ WeakNSObject<NSObject> w1(p1);
+ WeakNSObject<NSObject> w2(w1);
+ EXPECT_TRUE(w1);
+ EXPECT_TRUE(w2);
+ EXPECT_TRUE(w1.get() == w2.get());
+ p1.reset();
+ EXPECT_FALSE(w1);
+ EXPECT_FALSE(w2);
+}
+
+TEST(WeakNSObjectTest, WeakNSObjectDies) {
+ base::scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
+ {
+ WeakNSObject<NSObject> w1(p1);
+ EXPECT_TRUE(w1);
+ }
+}
+
+TEST(WeakNSObjectTest, WeakNSObjectReset) {
+ base::scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
+ WeakNSObject<NSObject> w1(p1);
+ EXPECT_TRUE(w1);
+ w1.reset();
+ EXPECT_FALSE(w1);
+ EXPECT_TRUE(p1);
+ EXPECT_TRUE([p1 description]);
+}
+
+TEST(WeakNSObjectTest, WeakNSObjectResetWithObject) {
+ base::scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
+ base::scoped_nsobject<NSObject> p2([[NSObject alloc] init]);
+ WeakNSObject<NSObject> w1(p1);
+ EXPECT_TRUE(w1);
+ w1.reset(p2);
+ EXPECT_TRUE(w1);
+ EXPECT_TRUE([p1 description]);
+ EXPECT_TRUE([p2 description]);
+}
+
+TEST(WeakNSObjectTest, WeakNSObjectEmpty) {
+ base::scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
+ WeakNSObject<NSObject> w1;
+ EXPECT_FALSE(w1);
+ w1.reset(p1);
+ EXPECT_TRUE(w1);
+ p1.reset();
+ EXPECT_FALSE(w1);
+}
+
+TEST(WeakNSObjectTest, WeakNSObjectCopy) {
+ base::scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
+ WeakNSObject<NSObject> w1(p1);
+ WeakNSObject<NSObject> w2(w1);
+ EXPECT_TRUE(w1);
+ EXPECT_TRUE(w2);
+ p1.reset();
+ EXPECT_FALSE(w1);
+ EXPECT_FALSE(w2);
+}
+
+TEST(WeakNSObjectTest, WeakNSObjectAssignment) {
+ base::scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
+ WeakNSObject<NSObject> w1(p1);
+ WeakNSObject<NSObject> w2;
+ EXPECT_FALSE(w2);
+ w2 = w1;
+ EXPECT_TRUE(w1);
+ EXPECT_TRUE(w2);
+ p1.reset();
+ EXPECT_FALSE(w1);
+ EXPECT_FALSE(w2);
+}
+
+} // namespace
diff --git a/base/mac/sdk_forward_declarations.h b/base/mac/sdk_forward_declarations.h
index fa6df4d..f606dab 100644
--- a/base/mac/sdk_forward_declarations.h
+++ b/base/mac/sdk_forward_declarations.h
@@ -334,6 +334,10 @@
@property (copy) NSDictionary* userInfo;
@property (copy) NSURL* webpageURL;
+- (instancetype)initWithActivityType:(NSString*)activityType;
+- (void)becomeCurrent;
+- (void)invalidate;
+
@end
BASE_EXPORT extern "C" NSString* const NSUserActivityTypeBrowsingWeb;
diff --git a/base/memory/discardable_shared_memory.cc b/base/memory/discardable_shared_memory.cc
index 6533048..851f1ad 100644
--- a/base/memory/discardable_shared_memory.cc
+++ b/base/memory/discardable_shared_memory.cc
@@ -224,6 +224,7 @@
}
void DiscardableSharedMemory::Close() {
+ shared_memory_.Unmap();
shared_memory_.Close();
}
diff --git a/base/memory/shared_memory.h b/base/memory/shared_memory.h
index 7254950..d76e01c 100644
--- a/base/memory/shared_memory.h
+++ b/base/memory/shared_memory.h
@@ -200,7 +200,8 @@
SharedMemoryId id() const { return inode_; }
#endif
- // Closes the open shared memory segment.
+ // Closes the open shared memory segment. The memory will remain mapped if
+ // it was previously mapped.
// It is safe to call Close repeatedly.
void Close();
diff --git a/base/memory/shared_memory_nacl.cc b/base/memory/shared_memory_nacl.cc
index 39625ee..8435b2b 100644
--- a/base/memory/shared_memory_nacl.cc
+++ b/base/memory/shared_memory_nacl.cc
@@ -46,6 +46,7 @@
}
SharedMemory::~SharedMemory() {
+ Unmap();
Close();
}
@@ -125,7 +126,6 @@
}
void SharedMemory::Close() {
- Unmap();
if (mapped_file_ > 0) {
if (close(mapped_file_) < 0)
DPLOG(ERROR) << "close";
@@ -159,8 +159,10 @@
new_handle->fd = new_fd;
new_handle->auto_close = true;
- if (close_self)
+ if (close_self) {
+ Unmap();
Close();
+ }
return true;
}
diff --git a/base/memory/shared_memory_posix.cc b/base/memory/shared_memory_posix.cc
index 0358e63..fd26ad1 100644
--- a/base/memory/shared_memory_posix.cc
+++ b/base/memory/shared_memory_posix.cc
@@ -80,6 +80,7 @@
}
SharedMemory::~SharedMemory() {
+ Unmap();
Close();
}
@@ -331,8 +332,6 @@
}
void SharedMemory::Close() {
- Unmap();
-
if (mapped_file_ > 0) {
if (close(mapped_file_) < 0)
PLOG(ERROR) << "close";
@@ -468,8 +467,10 @@
new_handle->fd = new_fd;
new_handle->auto_close = true;
- if (close_self)
+ if (close_self) {
+ Unmap();
Close();
+ }
return true;
}
diff --git a/base/memory/shared_memory_unittest.cc b/base/memory/shared_memory_unittest.cc
index 0b3fd7b..265179a 100644
--- a/base/memory/shared_memory_unittest.cc
+++ b/base/memory/shared_memory_unittest.cc
@@ -260,6 +260,29 @@
}
#endif
+// Check that memory is still mapped after its closed.
+TEST(SharedMemoryTest, CloseNoUnmap) {
+ const size_t kDataSize = 4096;
+
+ SharedMemory memory;
+ ASSERT_TRUE(memory.CreateAndMapAnonymous(kDataSize));
+ char* ptr = static_cast<char*>(memory.memory());
+ ASSERT_NE(ptr, static_cast<void*>(NULL));
+ memset(ptr, 'G', kDataSize);
+
+ memory.Close();
+
+ EXPECT_EQ(ptr, memory.memory());
+ EXPECT_EQ(SharedMemory::NULLHandle(), memory.handle());
+
+ for (size_t i = 0; i < kDataSize; i++) {
+ EXPECT_EQ('G', ptr[i]);
+ }
+
+ memory.Unmap();
+ EXPECT_EQ(nullptr, memory.memory());
+}
+
// Create a set of N threads to each open a shared memory segment and write to
// it. Verify that they are always reading/writing consistent data.
TEST(SharedMemoryTest, MultipleThreads) {
diff --git a/base/memory/shared_memory_win.cc b/base/memory/shared_memory_win.cc
index 5d2fa2a..20659ab 100644
--- a/base/memory/shared_memory_win.cc
+++ b/base/memory/shared_memory_win.cc
@@ -71,6 +71,7 @@
}
SharedMemory::~SharedMemory() {
+ Unmap();
Close();
if (lock_ != NULL)
CloseHandle(lock_);
@@ -249,11 +250,6 @@
void SharedMemory::Close() {
- if (memory_ != NULL) {
- UnmapViewOfFile(memory_);
- memory_ = NULL;
- }
-
if (mapped_file_ != NULL) {
CloseHandle(mapped_file_);
mapped_file_ = NULL;
diff --git a/base/message_loop/incoming_task_queue.cc b/base/message_loop/incoming_task_queue.cc
index 2ca32d6..9e5b013 100644
--- a/base/message_loop/incoming_task_queue.cc
+++ b/base/message_loop/incoming_task_queue.cc
@@ -6,16 +6,36 @@
#include "base/location.h"
#include "base/message_loop/message_loop.h"
+#include "base/metrics/histogram.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
namespace base {
namespace internal {
+namespace {
+
+// Returns true if MessagePump::ScheduleWork() must be called one
+// time for every task that is added to the MessageLoop incoming queue.
+bool AlwaysNotifyPump(MessageLoop::Type type) {
+#if defined(OS_ANDROID)
+ // The Android UI message loop needs to get notified each time a task is
+ // added
+ // to the incoming queue.
+ return type == MessageLoop::TYPE_UI || type == MessageLoop::TYPE_JAVA;
+#else
+ return false;
+#endif
+}
+
+} // namespace
+
IncomingTaskQueue::IncomingTaskQueue(MessageLoop* message_loop)
: high_res_task_count_(0),
message_loop_(message_loop),
- next_sequence_num_(0) {
+ next_sequence_num_(0),
+ message_loop_scheduled_(false),
+ always_schedule_work_(AlwaysNotifyPump(message_loop_->type())) {
}
bool IncomingTaskQueue::AddToIncomingQueue(
@@ -56,9 +76,14 @@
// Acquire all we can from the inter-thread queue with one lock acquisition.
AutoLock lock(incoming_queue_lock_);
- if (!incoming_queue_.empty())
+ if (incoming_queue_.empty()) {
+ // If the loop attempts to reload but there are no tasks in the incoming
+ // queue, that means it will go to sleep waiting for more work. If the
+ // incoming queue becomes nonempty we need to schedule it again.
+ message_loop_scheduled_ = false;
+ } else {
incoming_queue_.Swap(work_queue);
-
+ }
// Reset the count of high resolution tasks since our queue is now empty.
int high_res_tasks = high_res_task_count_;
high_res_task_count_ = 0;
@@ -109,8 +134,16 @@
incoming_queue_.push(*pending_task);
pending_task->task.Reset();
- // Wake up the pump.
- message_loop_->ScheduleWork(was_empty);
+ if (always_schedule_work_ || (!message_loop_scheduled_ && was_empty)) {
+ // Wake up the message loop.
+ message_loop_->ScheduleWork();
+ // After we've scheduled the message loop, we do not need to do so again
+ // until we know it has processed all of the work in our queue and is
+ // waiting for more work again. The message loop will always attempt to
+ // reload from the incoming queue before waiting again so we clear this flag
+ // in ReloadWorkQueue().
+ message_loop_scheduled_ = true;
+ }
return true;
}
diff --git a/base/message_loop/incoming_task_queue.h b/base/message_loop/incoming_task_queue.h
index 30f2603..72e1f30 100644
--- a/base/message_loop/incoming_task_queue.h
+++ b/base/message_loop/incoming_task_queue.h
@@ -84,6 +84,14 @@
// The next sequence number to use for delayed tasks.
int next_sequence_num_;
+ // True if our message loop has already been scheduled and does not need to be
+ // scheduled again until an empty reload occurs.
+ bool message_loop_scheduled_;
+
+ // True if we always need to call ScheduleWork when receiving a new task, even
+ // if the incoming queue was not empty.
+ const bool always_schedule_work_;
+
DISALLOW_COPY_AND_ASSIGN(IncomingTaskQueue);
};
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
index 2f4a03c..8180733 100644
--- a/base/message_loop/message_loop.cc
+++ b/base/message_loop/message_loop.cc
@@ -86,18 +86,6 @@
MessageLoop::MessagePumpFactory* message_pump_for_ui_factory_ = NULL;
-// Returns true if MessagePump::ScheduleWork() must be called one
-// time for every task that is added to the MessageLoop incoming queue.
-bool AlwaysNotifyPump(MessageLoop::Type type) {
-#if defined(OS_ANDROID)
- // The Android UI message loop needs to get notified each time a task is added
- // to the incoming queue.
- return type == MessageLoop::TYPE_UI || type == MessageLoop::TYPE_JAVA;
-#else
- return false;
-#endif
-}
-
#if defined(OS_IOS)
typedef MessagePumpIOSForIO MessagePumpForIO;
#elif defined(OS_NACL_SFI)
@@ -512,9 +500,8 @@
}
}
-void MessageLoop::ScheduleWork(bool was_empty) {
- if (was_empty || AlwaysNotifyPump(type_))
- pump_->ScheduleWork();
+void MessageLoop::ScheduleWork() {
+ pump_->ScheduleWork();
}
//------------------------------------------------------------------------------
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index 47df69a..32e826d 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -391,7 +391,7 @@
// Wakes up the message pump. Can be called on any thread. The caller is
// responsible for synchronizing ScheduleWork() calls.
- void ScheduleWork(bool was_empty);
+ void ScheduleWork();
// Returns the TaskAnnotator which is used to add debug information to posted
// tasks.
diff --git a/base/message_loop/message_pump_perftest.cc b/base/message_loop/message_pump_perftest.cc
index 9fca465..39ed5a8 100644
--- a/base/message_loop/message_pump_perftest.cc
+++ b/base/message_loop/message_pump_perftest.cc
@@ -39,7 +39,7 @@
uint64_t schedule_calls = 0u;
do {
for (size_t i = 0; i < kBatchSize; ++i) {
- target_message_loop()->ScheduleWork(true);
+ target_message_loop()->ScheduleWork();
schedule_calls++;
}
now = base::TimeTicks::HighResNow();
diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc
index ad89b7f..3f94c80 100644
--- a/base/message_loop/message_pump_win.cc
+++ b/base/message_loop/message_pump_win.cc
@@ -10,6 +10,7 @@
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/process/memory.h"
+#include "base/profiler/scoped_tracker.h"
#include "base/strings/stringprintf.h"
#include "base/win/wrapped_window_proc.h"
@@ -319,6 +320,11 @@
}
bool MessagePumpForUI::ProcessNextWindowsMessage() {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "440919 <<MessagePumpForUI::ProcessNextWindowsMessage>>"));
+
// If there are sent messages in the queue then PeekMessage internally
// dispatches the message and returns false. We return true in this
// case to ensure that the message loop peeks again instead of calling
diff --git a/base/port.h b/base/port.h
index 0a04d55..56c4d4e 100644
--- a/base/port.h
+++ b/base/port.h
@@ -26,18 +26,6 @@
#define GG_INT64_C(x) GG_LONGLONG(x)
#define GG_UINT64_C(x) GG_ULONGLONG(x)
-// It's possible for functions that use a va_list, such as StringPrintf, to
-// invalidate the data in it upon use. The fix is to make a copy of the
-// structure before using it and use that copy instead. va_copy is provided
-// for this purpose. MSVC does not provide va_copy, so define an
-// implementation here. It is not guaranteed that assignment is a copy, so the
-// StringUtil.VariableArgsFunc unit test tests this capability.
-#if defined(COMPILER_GCC)
-#define GG_VA_COPY(a, b) (va_copy(a, b))
-#elif defined(COMPILER_MSVC)
-#define GG_VA_COPY(a, b) (a = b)
-#endif
-
// Define an OS-neutral wrapper for shared library entry points
#if defined(OS_WIN)
#define API_CALL __stdcall
diff --git a/base/process/process.h b/base/process/process.h
index 50ccf8d..ad8f8ee 100644
--- a/base/process/process.h
+++ b/base/process/process.h
@@ -9,6 +9,7 @@
#include "base/basictypes.h"
#include "base/move.h"
#include "base/process/process_handle.h"
+#include "base/time/time.h"
#include "build/build_config.h"
#if defined(OS_WIN)
@@ -81,6 +82,13 @@
// NOTE: On POSIX |result_code| is ignored.
void Terminate(int result_code);
+ // Waits for the process to exit. Returns true on success.
+ // On POSIX, if the process has been signaled then |exit_code| is set to -1.
+ bool WaitForExit(int* exit_code);
+
+ // Same as WaitForExit() but only waits for up to |timeout|.
+ bool WaitForExitWithTimeout(TimeDelta timeout, int* exit_code);
+
// A process is backgrounded when it's priority is lower than normal.
// Return true if this process is backgrounded, false otherwise.
bool IsProcessBackgrounded() const;
diff --git a/base/process/process_posix.cc b/base/process/process_posix.cc
index 270438e..58852bc 100644
--- a/base/process/process_posix.cc
+++ b/base/process/process_posix.cc
@@ -89,6 +89,18 @@
KillProcess(process_, result_code, false);
}
+bool Process::WaitForExit(int* exit_code) {
+ // TODO(rvargas) crbug.com/417532: Remove this constant.
+ const int kNoTimeout = -1;
+ return WaitForExitWithTimeout(TimeDelta::FromMilliseconds(kNoTimeout),
+ exit_code);
+}
+
+bool Process::WaitForExitWithTimeout(TimeDelta timeout, int* exit_code) {
+ // TODO(rvargas) crbug.com/417532: Move the implementation here.
+ return base::WaitForExitCodeWithTimeout(Handle(), exit_code, timeout);
+}
+
#if !defined(OS_LINUX)
bool Process::IsProcessBackgrounded() const {
// See SetProcessBackgrounded().
diff --git a/base/process/process_unittest.cc b/base/process/process_unittest.cc
index a5ba834..5180f64 100644
--- a/base/process/process_unittest.cc
+++ b/base/process/process_unittest.cc
@@ -135,6 +135,34 @@
#endif
}
+MULTIPROCESS_TEST_MAIN(FastSleepyChildProcess) {
+ PlatformThread::Sleep(TestTimeouts::tiny_timeout() * 10);
+ return 0;
+}
+
+TEST_F(ProcessTest, WaitForExit) {
+ Process process(SpawnChild("FastSleepyChildProcess"));
+ ASSERT_TRUE(process.IsValid());
+
+ const int kDummyExitCode = 42;
+ int exit_code = kDummyExitCode;
+ EXPECT_TRUE(process.WaitForExit(&exit_code));
+ EXPECT_EQ(0, exit_code);
+}
+
+TEST_F(ProcessTest, WaitForExitWithTimeout) {
+ Process process(SpawnChild("SleepyChildProcess"));
+ ASSERT_TRUE(process.IsValid());
+
+ const int kDummyExitCode = 42;
+ int exit_code = kDummyExitCode;
+ TimeDelta timeout = TestTimeouts::tiny_timeout();
+ EXPECT_FALSE(process.WaitForExitWithTimeout(timeout, &exit_code));
+ EXPECT_EQ(kDummyExitCode, exit_code);
+
+ process.Terminate(kDummyExitCode);
+}
+
// Ensure that the priority of a process is restored correctly after
// backgrounding and restoring.
// Note: a platform may not be willing or able to lower the priority of
diff --git a/base/process/process_win.cc b/base/process/process_win.cc
index 3e0d79f..96556a9 100644
--- a/base/process/process_win.cc
+++ b/base/process/process_win.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/process/kill.h"
#include "base/win/windows_version.h"
namespace base {
@@ -110,6 +111,18 @@
terminate_process(Handle(), result_code);
}
+bool Process::WaitForExit(int* exit_code) {
+ return WaitForExitWithTimeout(TimeDelta::FromMilliseconds(INFINITE),
+ exit_code);
+}
+
+bool Process::WaitForExitWithTimeout(TimeDelta timeout, int* exit_code) {
+ // TODO(rvargas) crbug.com/417532: Move the implementation here.
+ if (timeout > TimeDelta::FromMilliseconds(INFINITE))
+ timeout = TimeDelta::FromMilliseconds(INFINITE);
+ return base::WaitForExitCodeWithTimeout(Handle(), exit_code, timeout);
+}
+
bool Process::IsProcessBackgrounded() const {
DCHECK(IsValid());
DWORD priority = GetPriority();
diff --git a/base/profiler/tracked_time.cc b/base/profiler/tracked_time.cc
index 7791c3a..0121038 100644
--- a/base/profiler/tracked_time.cc
+++ b/base/profiler/tracked_time.cc
@@ -46,7 +46,7 @@
TrackedTime::TrackedTime() : ms_(0) {}
TrackedTime::TrackedTime(int32 ms) : ms_(ms) {}
TrackedTime::TrackedTime(const base::TimeTicks& time)
- : ms_((time - base::TimeTicks()).InMilliseconds()) {
+ : ms_(static_cast<int32>((time - base::TimeTicks()).InMilliseconds())) {
}
// static
diff --git a/base/strings/string_util_unittest.cc b/base/strings/string_util_unittest.cc
index 923116d..d887c0b 100644
--- a/base/strings/string_util_unittest.cc
+++ b/base/strings/string_util_unittest.cc
@@ -669,39 +669,6 @@
EXPECT_EQ(15, HexDigitToInt('f'));
}
-// This checks where we can use the assignment operator for a va_list. We need
-// a way to do this since Visual C doesn't support va_copy, but assignment on
-// va_list is not guaranteed to be a copy. See StringAppendVT which uses this
-// capability.
-static void VariableArgsFunc(const char* format, ...) {
- va_list org;
- va_start(org, format);
-
- va_list dup;
- GG_VA_COPY(dup, org);
- int i1 = va_arg(org, int);
- int j1 = va_arg(org, int);
- char* s1 = va_arg(org, char*);
- double d1 = va_arg(org, double);
- va_end(org);
-
- int i2 = va_arg(dup, int);
- int j2 = va_arg(dup, int);
- char* s2 = va_arg(dup, char*);
- double d2 = va_arg(dup, double);
-
- EXPECT_EQ(i1, i2);
- EXPECT_EQ(j1, j2);
- EXPECT_STREQ(s1, s2);
- EXPECT_EQ(d1, d2);
-
- va_end(dup);
-}
-
-TEST(StringUtilTest, VAList) {
- VariableArgsFunc("%d %d %s %lf", 45, 92, "This is interesting", 9.21);
-}
-
// Test for Tokenize
template <typename STR>
void TokenizeTest() {
diff --git a/base/strings/stringprintf.cc b/base/strings/stringprintf.cc
index 3d024fa..f3a57b3 100644
--- a/base/strings/stringprintf.cc
+++ b/base/strings/stringprintf.cc
@@ -48,7 +48,7 @@
typename StringType::value_type stack_buf[1024];
va_list ap_copy;
- GG_VA_COPY(ap_copy, ap);
+ va_copy(ap_copy, ap);
#if !defined(OS_WIN)
ScopedClearErrno clear_errno;
@@ -94,7 +94,7 @@
// NOTE: You can only use a va_list once. Since we're in a while loop, we
// need to make a new copy each time so we don't use up the original.
- GG_VA_COPY(ap_copy, ap);
+ va_copy(ap_copy, ap);
result = vsnprintfT(&mem_buf[0], mem_length, format, ap_copy);
va_end(ap_copy);
diff --git a/base/strings/sys_string_conversions_posix.cc b/base/strings/sys_string_conversions_posix.cc
index 1e926bb..3b18456 100644
--- a/base/strings/sys_string_conversions_posix.cc
+++ b/base/strings/sys_string_conversions_posix.cc
@@ -24,11 +24,10 @@
return out;
}
-#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
+#if defined(SYSTEM_NATIVE_UTF8) || defined(OS_ANDROID)
// TODO(port): Consider reverting the OS_ANDROID when we have wcrtomb()
// support and a better understanding of what calls these routines.
-// ChromeOS always runs in UTF-8 locale.
std::string SysWideToNativeMB(const std::wstring& wide) {
return WideToUTF8(wide);
}
diff --git a/base/supports_user_data.h b/base/supports_user_data.h
index 6d515d7..711ee7d 100644
--- a/base/supports_user_data.h
+++ b/base/supports_user_data.h
@@ -61,7 +61,7 @@
template <typename T>
class UserDataAdapter : public base::SupportsUserData::Data {
public:
- static T* Get(SupportsUserData* supports_user_data, const void* key) {
+ static T* Get(const SupportsUserData* supports_user_data, const void* key) {
UserDataAdapter* data =
static_cast<UserDataAdapter*>(supports_user_data->GetUserData(key));
return data ? static_cast<T*>(data->object_.get()) : NULL;
diff --git a/build/all.gyp b/build/all.gyp
index 149ac0a..5f06ae0 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -846,6 +846,7 @@
'../tools/android/android_tools.gyp:android_tools',
'../tools/android/android_tools.gyp:memconsumer',
'../tools/android/findbugs_plugin/findbugs_plugin.gyp:findbugs_plugin_test',
+ '../ui/android/ui_android.gyp:ui_android_unittests',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
'../ui/events/events.gyp:events_unittests',
'../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
@@ -874,6 +875,7 @@
'../sql/sql.gyp:sql_unittests_apk',
'../sync/sync.gyp:sync_unit_tests_apk',
'../tools/android/heap_profiler/heap_profiler.gyp:heap_profiler_unittests_apk',
+ '../ui/android/ui_android.gyp:ui_android_unittests_apk',
'../ui/base/ui_base_tests.gyp:ui_base_unittests_apk',
'../ui/events/events.gyp:events_unittests_apk',
'../ui/gfx/gfx_tests.gyp:gfx_unittests_apk',
@@ -883,7 +885,6 @@
['enable_webrtc==1 and "<(libpeer_target_type)"=="static_library"', {
'dependencies': [
'../components/devtools_bridge.gyp:devtools_bridge_tests_apk',
- '../components/devtools_bridge.gyp:libdevtools_bridge_browsertests',
],
}],
],
@@ -899,7 +900,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:libdevtools_bridge_browsertests',
'../content/content_shell_and_tests.gyp:content_browsertests_apk',
],
}, # target_name: android_builder_chromium_webrtc
diff --git a/build/android/buildbot/bb_device_status_check.py b/build/android/buildbot/bb_device_status_check.py
index a72a0c7..08bccc9 100755
--- a/build/android/buildbot/bb_device_status_check.py
+++ b/build/android/buildbot/bb_device_status_check.py
@@ -46,10 +46,10 @@
"""
device_adb = device_utils.DeviceUtils(serial)
- device_type = device_adb.GetProp('ro.build.product')
- device_build = device_adb.GetProp('ro.build.id')
- device_build_type = device_adb.GetProp('ro.build.type')
- device_product_name = device_adb.GetProp('ro.product.name')
+ device_type = device_adb.build_product
+ device_build = device_adb.build_id
+ device_build_type = device_adb.build_type
+ device_product_name = device_adb.product_name
try:
battery_info = device_adb.old_interface.GetBatteryInfo()
@@ -71,7 +71,7 @@
lambda x: x[-6:])
report = ['Device %s (%s)' % (serial, device_type),
' Build: %s (%s)' %
- (device_build, device_adb.GetProp('ro.build.fingerprint')),
+ (device_build, device_adb.build_fingerprint),
' Current Battery Service state: ',
'\n'.join([' %s: %s' % (k, v)
for k, v in battery_info.iteritems()]),
diff --git a/build/android/findbugs_filter/findbugs_known_bugs.txt b/build/android/findbugs_filter/findbugs_known_bugs.txt
index 6ad2b3a..cbc5e30 100644
--- a/build/android/findbugs_filter/findbugs_known_bugs.txt
+++ b/build/android/findbugs_filter/findbugs_known_bugs.txt
@@ -23,3 +23,10 @@
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 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
+M D UrF: Unread public/protected field: org.chromium.chrome.browser.tabmodel.document.DocumentTabModel$Entry.initialUrl At DocumentTabModel.java
+M D UrF: Unread public/protected field: org.chromium.chrome.browser.tabmodel.document.DocumentTabModel$Entry.isTabStateReady At DocumentTabModel.java
+M D UrF: Unread public/protected field: org.chromium.chrome.browser.tabmodel.document.DocumentTabModel$Entry.tabState At DocumentTabModel.java
+M D UuF: Unused public or protected field: org.chromium.chrome.browser.tabmodel.document.DocumentTabModel$Entry.canGoBack In DocumentTabModel.java
+M D UuF: Unused public or protected field: org.chromium.chrome.browser.tabmodel.document.DocumentTabModel$Entry.currentUrl In DocumentTabModel.java
+M D UuF: Unused public or protected field: org.chromium.chrome.browser.tabmodel.document.DocumentTabModel$Entry.isDirty In DocumentTabModel.java
+M D UuF: Unused public or protected field: org.chromium.chrome.browser.tabmodel.document.DocumentTabModel$Entry.placeholderTab In DocumentTabModel.java
diff --git a/build/android/pylib/base/environment_factory.py b/build/android/pylib/base/environment_factory.py
index c96d199..3ad39fc 100644
--- a/build/android/pylib/base/environment_factory.py
+++ b/build/android/pylib/base/environment_factory.py
@@ -2,10 +2,14 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+from pylib.remote.device import remote_device_environment
-def CreateEnvironment(_args, error_func):
+def CreateEnvironment(args, error_func):
# TODO(jbudorick) Add local device environment.
# TODO(jbudorick) Add local machine environment.
- error_func('No environments currently supported.')
+ if args.environment == 'remote_device':
+ return remote_device_environment.RemoteDeviceEnvironment(args,
+ error_func)
+ error_func('Unable to create %s environment.' % args.environment)
diff --git a/build/android/pylib/base/test_instance_factory.py b/build/android/pylib/base/test_instance_factory.py
index 5204b2e..af989ef 100644
--- a/build/android/pylib/base/test_instance_factory.py
+++ b/build/android/pylib/base/test_instance_factory.py
@@ -5,6 +5,8 @@
from pylib import constants
from pylib.gtest import gtest_test_instance
from pylib.utils import isolator
+from pylib.uirobot import uirobot_test_instance
+
def CreateTestInstance(args, error_func):
@@ -12,7 +14,8 @@
if args.command == 'gtest':
return gtest_test_instance.GtestTestInstance(
args, isolator.Isolator(constants.ISOLATE_DEPS_DIR))
+ if args.command == 'uirobot':
+ return uirobot_test_instance.UirobotTestInstance(args)
# TODO(jbudorick) Add instrumentation test instance.
error_func('Unable to create %s test instance.' % args.command)
-
diff --git a/build/android/pylib/base/test_run.py b/build/android/pylib/base/test_run.py
index 2c594fd..7380e78 100644
--- a/build/android/pylib/base/test_run.py
+++ b/build/android/pylib/base/test_run.py
@@ -24,7 +24,7 @@
def SetUp(self):
raise NotImplementedError
- def RunTest(self):
+ def RunTests(self):
raise NotImplementedError
def TearDown(self):
diff --git a/build/android/pylib/base/test_run_factory.py b/build/android/pylib/base/test_run_factory.py
index 6ccfb37..550b4cf 100644
--- a/build/android/pylib/base/test_run_factory.py
+++ b/build/android/pylib/base/test_run_factory.py
@@ -2,9 +2,17 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-def CreateTestRun(_args, _env, _test_instance, error_func):
+from pylib.remote.device import remote_device_gtest_run
+from pylib.remote.device import remote_device_uirobot_run
+def CreateTestRun(args, env, test_instance, error_func):
+ if args.environment == 'remote_device':
+ if test_instance.TestType() == 'gtest':
+ return remote_device_gtest_run.RemoteDeviceGtestRun(env, test_instance)
+ if test_instance.TestType() == 'uirobot':
+ return remote_device_uirobot_run.RemoteDeviceUirobotRun(
+ env, test_instance)
# TODO(jbudorick) Add local gtest test runs
# TODO(jbudorick) Add local instrumentation test runs.
- error_func('No test runs are currently supported.')
-
+ error_func('Unable to create %s test run in %s environment' % (
+ test_instance.TestType(), args.environment))
diff --git a/build/android/pylib/cmd_helper.py b/build/android/pylib/cmd_helper.py
index e3abab7..f881553 100644
--- a/build/android/pylib/cmd_helper.py
+++ b/build/android/pylib/cmd_helper.py
@@ -115,14 +115,20 @@
return output
-def _LogCommand(args, cwd=None):
- if not isinstance(args, basestring):
+def _ValidateAndLogCommand(args, cwd, shell):
+ if isinstance(args, basestring):
+ if not shell:
+ raise Exception('string args must be run with shell=True')
+ else:
+ if shell:
+ raise Exception('array args must be run with shell=False')
args = ' '.join(SingleQuote(c) for c in args)
if cwd is None:
cwd = ''
else:
cwd = ':' + cwd
logging.info('[host]%s> %s', cwd, args)
+ return args
def GetCmdStatusAndOutput(args, cwd=None, shell=False):
@@ -133,18 +139,13 @@
the string or the first item in the args sequence.
cwd: If not None, the subprocess's current directory will be changed to
|cwd| before it's executed.
- shell: Whether to execute args as a shell command.
+ shell: Whether to execute args as a shell command. Must be True if args
+ is a string and False if args is a sequence.
Returns:
The 2-tuple (exit code, output).
"""
- if isinstance(args, basestring):
- if not shell:
- raise Exception('string args must be run with shell=True')
- elif shell:
- raise Exception('array args must be run with shell=False')
-
- _LogCommand(args, cwd)
+ _ValidateAndLogCommand(args, cwd, shell)
pipe = Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
shell=shell, cwd=cwd)
stdout, stderr = pipe.communicate()
@@ -162,44 +163,16 @@
pass
-def GetCmdStatusAndOutputWithTimeout(args, timeout, cwd=None, shell=False,
- logfile=None):
- """Executes a subprocess with a timeout.
-
- Args:
- args: List of arguments to the program, the program to execute is the first
- element.
- timeout: the timeout in seconds or None to wait forever.
- cwd: If not None, the subprocess's current directory will be changed to
- |cwd| before it's executed.
- shell: Whether to execute args as a shell command.
- logfile: Optional file-like object that will receive output from the
- command as it is running.
-
- Returns:
- The 2-tuple (exit code, output).
- """
+def _IterProcessStdout(process, timeout=None, buffer_size=4096,
+ poll_interval=1):
assert fcntl, 'fcntl module is required'
- if isinstance(args, basestring):
- if not shell:
- raise Exception('string args must be run with shell=True')
- elif shell:
- raise Exception('array args must be run with shell=False')
-
- _LogCommand(args, cwd)
- process = Popen(args, cwd=cwd, shell=shell, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
try:
- end_time = (time.time() + timeout) if timeout else None
- poll_interval = 1
- buffer_size = 4096
- child_fd = process.stdout.fileno()
- output = StringIO.StringIO()
-
# Enable non-blocking reads from the child's stdout.
+ child_fd = process.stdout.fileno()
fl = fcntl.fcntl(child_fd, fcntl.F_GETFL)
fcntl.fcntl(child_fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
+ end_time = (time.time() + timeout) if timeout else None
while True:
if end_time and time.time() > end_time:
raise TimeoutError
@@ -208,9 +181,7 @@
data = os.read(child_fd, buffer_size)
if not data:
break
- if logfile:
- logfile.write(data)
- output.write(data)
+ yield data
if process.poll() is not None:
break
finally:
@@ -221,4 +192,70 @@
except OSError:
pass
process.wait()
+
+
+def GetCmdStatusAndOutputWithTimeout(args, timeout, cwd=None, shell=False,
+ logfile=None):
+ """Executes a subprocess with a timeout.
+
+ Args:
+ args: List of arguments to the program, the program to execute is the first
+ element.
+ timeout: the timeout in seconds or None to wait forever.
+ cwd: If not None, the subprocess's current directory will be changed to
+ |cwd| before it's executed.
+ shell: Whether to execute args as a shell command. Must be True if args
+ is a string and False if args is a sequence.
+ logfile: Optional file-like object that will receive output from the
+ command as it is running.
+
+ Returns:
+ The 2-tuple (exit code, output).
+ """
+ _ValidateAndLogCommand(args, cwd, shell)
+ output = StringIO.StringIO()
+ process = Popen(args, cwd=cwd, shell=shell, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ for data in _IterProcessStdout(process, timeout=timeout):
+ if logfile:
+ logfile.write(data)
+ output.write(data)
return process.returncode, output.getvalue()
+
+
+def IterCmdOutputLines(args, timeout=None, cwd=None, shell=False,
+ check_status=True):
+ """Executes a subprocess and continuously yields lines from its output.
+
+ Args:
+ args: List of arguments to the program, the program to execute is the first
+ element.
+ cwd: If not None, the subprocess's current directory will be changed to
+ |cwd| before it's executed.
+ shell: Whether to execute args as a shell command. Must be True if args
+ is a string and False if args is a sequence.
+ check_status: A boolean indicating whether to check the exit status of the
+ process after all output has been read.
+
+ Yields:
+ The output of the subprocess, line by line.
+
+ Raises:
+ CalledProcessError if check_status is True and the process exited with a
+ non-zero exit status.
+ """
+ cmd = _ValidateAndLogCommand(args, cwd, shell)
+ process = Popen(args, cwd=cwd, shell=shell, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ buffer_output = ''
+ for data in _IterProcessStdout(process, timeout=timeout):
+ buffer_output += data
+ has_incomplete_line = buffer_output[-1] not in '\r\n'
+ lines = buffer_output.splitlines()
+ buffer_output = lines.pop() if has_incomplete_line else ''
+ for line in lines:
+ yield line
+ if buffer_output:
+ yield buffer_output
+ if check_status and process.returncode:
+ raise subprocess.CalledProcessError(process.returncode, cmd)
diff --git a/build/android/pylib/cmd_helper_test.py b/build/android/pylib/cmd_helper_test.py
index 8b5680d..5155cea 100644
--- a/build/android/pylib/cmd_helper_test.py
+++ b/build/android/pylib/cmd_helper_test.py
@@ -5,11 +5,10 @@
"""Tests for the cmd_helper module."""
import unittest
+import subprocess
from pylib import cmd_helper
-# TODO(jbudorick) Make these tests run on the bots.
-
class CmdHelperSingleQuoteTest(unittest.TestCase):
@@ -51,3 +50,34 @@
cmd = 'TEST_VAR=world; echo %s' % cmd_helper.DoubleQuote(test_string)
self.assertEquals('hello world',
cmd_helper.GetCmdOutput(cmd, shell=True).rstrip())
+
+
+class CmdHelperIterCmdOutputLinesTest(unittest.TestCase):
+ """Test IterCmdOutputLines with some calls to the unix 'seq' command."""
+
+ def testIterCmdOutputLines_success(self):
+ for num, line in enumerate(
+ cmd_helper.IterCmdOutputLines(['seq', '10']), 1):
+ self.assertEquals(num, int(line))
+
+ def testIterCmdOutputLines_exitStatusFail(self):
+ with self.assertRaises(subprocess.CalledProcessError):
+ for num, line in enumerate(
+ cmd_helper.IterCmdOutputLines('seq 10 && false', shell=True), 1):
+ self.assertEquals(num, int(line))
+ # after reading all the output we get an exit status of 1
+
+ def testIterCmdOutputLines_exitStatusIgnored(self):
+ for num, line in enumerate(
+ cmd_helper.IterCmdOutputLines('seq 10 && false', shell=True,
+ check_status=False), 1):
+ self.assertEquals(num, int(line))
+
+ def testIterCmdOutputLines_exitStatusSkipped(self):
+ for num, line in enumerate(
+ cmd_helper.IterCmdOutputLines('seq 10 && false', shell=True), 1):
+ self.assertEquals(num, int(line))
+ # no exception will be raised because we don't attempt to read past
+ # the end of the output and, thus, the status never gets checked
+ if num == 10:
+ break
diff --git a/build/android/pylib/constants.py b/build/android/pylib/constants.py
index ac57969..50dc075 100644
--- a/build/android/pylib/constants.py
+++ b/build/android/pylib/constants.py
@@ -187,6 +187,7 @@
'pylib_py_unittests': {
'path': os.path.join(DIR_SOURCE_ROOT, 'build', 'android'),
'test_modules': [
+ 'pylib.cmd_helper_test',
'pylib.device.device_utils_test',
'pylib.results.json_results_test',
'pylib.utils.md5sum_test',
@@ -201,9 +202,9 @@
}
LOCAL_MACHINE_TESTS = ['junit', 'python']
-VALID_ENVIRONMENTS = ['local']
+VALID_ENVIRONMENTS = ['local', 'remote_device']
VALID_TEST_TYPES = ['gtest', 'instrumentation', 'junit', 'linker', 'monkey',
- 'perf', 'python', 'uiautomator']
+ 'perf', 'python', 'uiautomator', 'uirobot']
def GetBuildType():
diff --git a/build/android/pylib/content_settings.py b/build/android/pylib/content_settings.py
index f00553f..f039c96 100644
--- a/build/android/pylib/content_settings.py
+++ b/build/android/pylib/content_settings.py
@@ -14,13 +14,9 @@
def __init__(self, table, device):
super(ContentSettings, self).__init__()
- sdk_version_string = device.GetProp('ro.build.version.sdk')
- try:
- sdk_version = int(sdk_version_string)
- assert sdk_version >= constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN, (
- 'ContentSettings supported only on SDK 16 and later')
- except ValueError:
- assert False, ('Unknown SDK version %s' % sdk_version_string)
+ assert (device.build_version_sdk
+ >= constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN), (
+ 'ContentSettings supported only on SDK 16 and later')
self._table = table
self._device = device
diff --git a/build/android/pylib/device/adb_wrapper.py b/build/android/pylib/device/adb_wrapper.py
index 39fe706..4006a21 100644
--- a/build/android/pylib/device/adb_wrapper.py
+++ b/build/android/pylib/device/adb_wrapper.py
@@ -56,15 +56,22 @@
# pylint: disable=unused-argument
@classmethod
- @decorators.WithTimeoutAndRetries
- def _RunAdbCmd(cls, args, timeout=None, retries=None, device_serial=None,
- check_error=True):
+ def _BuildAdbCmd(cls, args, device_serial):
cmd = [constants.GetAdbPath()]
if device_serial is not None:
cmd.extend(['-s', device_serial])
cmd.extend(args)
+ return cmd
+ # pylint: enable=unused-argument
+
+ # pylint: disable=unused-argument
+ @classmethod
+ @decorators.WithTimeoutAndRetries
+ def _RunAdbCmd(cls, args, timeout=None, retries=None, device_serial=None,
+ check_error=True):
status, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
- cmd, timeout_retry.CurrentTimeoutThread().GetRemainingTime())
+ cls._BuildAdbCmd(args, device_serial),
+ timeout_retry.CurrentTimeoutThread().GetRemainingTime())
if status != 0:
raise device_errors.AdbCommandFailedError(
args, output, status, device_serial)
@@ -93,6 +100,19 @@
device_serial=self._device_serial,
check_error=check_error)
+ def _IterRunDeviceAdbCmd(self, args, timeout):
+ """Runs an adb command and returns an iterator over its output lines.
+
+ Args:
+ args: A list of arguments to adb.
+ timeout: Timeout in seconds.
+
+ Yields:
+ The output of the command line by line.
+ """
+ return cmd_helper.IterCmdOutputLines(
+ self._BuildAdbCmd(args, self._device_serial), timeout=timeout)
+
def __eq__(self, other):
"""Consider instances equal if they refer to the same device.
@@ -242,22 +262,20 @@
cmd, 'path does not specify an accessible directory in the device',
device_serial=self._device_serial)
- def Logcat(self, filter_spec=None, timeout=_DEFAULT_TIMEOUT,
- retries=_DEFAULT_RETRIES):
- """Get the logcat output.
+ def Logcat(self, filter_spec=None, timeout=None):
+ """Get an iterator over the logcat output.
Args:
filter_spec: (optional) Spec to filter the logcat.
timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
- Returns:
- logcat output as a string.
+ Yields:
+ logcat output line by line.
"""
cmd = ['logcat']
if filter_spec is not None:
cmd.append(filter_spec)
- return self._RunDeviceAdbCmd(cmd, timeout, retries, check_error=False)
+ return self._IterRunDeviceAdbCmd(cmd, timeout)
def Forward(self, local, remote, timeout=_DEFAULT_TIMEOUT,
retries=_DEFAULT_RETRIES):
diff --git a/build/android/pylib/device/device_utils.py b/build/android/pylib/device/device_utils.py
index 1624ccc..f461b28 100644
--- a/build/android/pylib/device/device_utils.py
+++ b/build/android/pylib/device/device_utils.py
@@ -34,6 +34,11 @@
_DEFAULT_TIMEOUT = 30
_DEFAULT_RETRIES = 3
+# A sentinel object for default values
+# TODO(jbudorick,perezju): revisit how default values are handled by
+# the timeout_retry decorators.
+DEFAULT = object()
+
@decorators.WithExplicitTimeoutAndRetries(
_DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
@@ -146,7 +151,7 @@
except device_errors.AdbCommandFailedError:
return False
- def NeedsSU(self, timeout=None, retries=None):
+ def NeedsSU(self, timeout=DEFAULT, retries=DEFAULT):
"""Checks whether 'su' is needed to access protected resources.
Args:
@@ -165,8 +170,10 @@
"""
if 'needs_su' not in self._cache:
try:
- self.RunShellCommand('su -c ls /root && ! ls /root', check_return=True,
- timeout=timeout, retries=retries)
+ self.RunShellCommand(
+ 'su -c ls /root && ! ls /root', check_return=True,
+ timeout=self._default_timeout if timeout is DEFAULT else timeout,
+ retries=self._default_retries if retries is DEFAULT else retries)
self._cache['needs_su'] = True
except device_errors.AdbCommandFailedError:
self._cache['needs_su'] = False
@@ -249,8 +256,14 @@
Returns:
Path to the apk on the device if it exists, None otherwise.
"""
+ # 'pm path' is liable to incorrectly exit with a nonzero number starting
+ # in Lollipop.
+ # TODO(jbudorick): Check if this is fixed as new Android versions are
+ # released to put an upper bound on this.
+ should_check_return = (self.build_version_sdk <
+ constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP)
output = self.RunShellCommand(['pm', 'path', package], single_line=True,
- check_return=True)
+ check_return=should_check_return)
if not output:
return None
if not output.startswith('package:'):
@@ -994,12 +1007,77 @@
"""
return self.old_interface.SetJavaAssertsEnabled(enabled)
+
+ @property
+ def build_description(self):
+ """Returns the build description of the system.
+
+ For example:
+ nakasi-user 4.4.4 KTU84P 1227136 release-keys
+ """
+ return self.GetProp('ro.build.description', cache=True)
+
+ @property
+ def build_fingerprint(self):
+ """Returns the build fingerprint of the system.
+
+ For example:
+ google/nakasi/grouper:4.4.4/KTU84P/1227136:user/release-keys
+ """
+ return self.GetProp('ro.build.fingerprint', cache=True)
+
+ @property
+ def build_id(self):
+ """Returns the build ID of the system (e.g. 'KTU84P')."""
+ return self.GetProp('ro.build.id', cache=True)
+
+ @property
+ def build_product(self):
+ """Returns the build product of the system (e.g. 'grouper')."""
+ return self.GetProp('ro.build.product', cache=True)
+
@property
def build_type(self):
- """Returns the build type of the system (e.g. userdebug)."""
+ """Returns the build type of the system (e.g. 'user')."""
return self.GetProp('ro.build.type', cache=True)
- def GetProp(self, property_name, cache=False, timeout=None, retries=None):
+ @property
+ def build_version_sdk(self):
+ """Returns the build version sdk of the system as a number (e.g. 19).
+
+ For version code numbers see:
+ http://developer.android.com/reference/android/os/Build.VERSION_CODES.html
+
+ For named constants see:
+ pylib.constants.ANDROID_SDK_VERSION_CODES
+
+ Raises:
+ CommandFailedError if the build version sdk is not a number.
+ """
+ value = self.GetProp('ro.build.version.sdk', cache=True)
+ try:
+ return int(value)
+ except ValueError:
+ raise device_errors.CommandFailedError(
+ 'Invalid build version sdk: %r' % value)
+
+ @property
+ def product_cpu_abi(self):
+ """Returns the product cpu abi of the device (e.g. 'armeabi-v7a')."""
+ return self.GetProp('ro.product.cpu.abi', cache=True)
+
+ @property
+ def product_model(self):
+ """Returns the name of the product model (e.g. 'Nexus 7')."""
+ return self.GetProp('ro.product.model', cache=True)
+
+ @property
+ def product_name(self):
+ """Returns the product name of the device (e.g. 'nakasi')."""
+ return self.GetProp('ro.product.name', cache=True)
+
+ def GetProp(self, property_name, cache=False, timeout=DEFAULT,
+ retries=DEFAULT):
"""Gets a property from the device.
Args:
@@ -1024,9 +1102,10 @@
else:
# timeout and retries are handled down at run shell, because we don't
# want to apply them in the other branch when reading from the cache
- value = self.RunShellCommand(['getprop', property_name],
- single_line=True, check_return=True,
- timeout=timeout, retries=retries)
+ value = self.RunShellCommand(
+ ['getprop', property_name], single_line=True, check_return=True,
+ timeout=self._default_timeout if timeout is DEFAULT else timeout,
+ retries=self._default_retries if retries is DEFAULT else retries)
if cache or cache_key in self._cache:
self._cache[cache_key] = value
return value
diff --git a/build/android/pylib/device/device_utils_test.py b/build/android/pylib/device/device_utils_test.py
index 2646bfb..16699ad 100755
--- a/build/android/pylib/device/device_utils_test.py
+++ b/build/android/pylib/device/device_utils_test.py
@@ -370,19 +370,25 @@
class DeviceUtilsGetApplicationPathTest(DeviceUtilsNewImplTest):
def testGetApplicationPath_exists(self):
- with self.assertCall(self.call.adb.Shell('pm path android'),
- 'package:/path/to/android.apk\n'):
+ with self.assertCalls(
+ (self.call.adb.Shell('getprop ro.build.version.sdk'), '19\n'),
+ (self.call.adb.Shell('pm path android'),
+ 'package:/path/to/android.apk\n')):
self.assertEquals('/path/to/android.apk',
self.device.GetApplicationPath('android'))
def testGetApplicationPath_notExists(self):
- with self.assertCall(self.call.adb.Shell('pm path not.installed.app'), ''):
+ with self.assertCalls(
+ (self.call.adb.Shell('getprop ro.build.version.sdk'), '19\n'),
+ (self.call.adb.Shell('pm path not.installed.app'), '')):
self.assertEquals(None,
self.device.GetApplicationPath('not.installed.app'))
def testGetApplicationPath_fails(self):
- with self.assertCall(self.call.adb.Shell('pm path android'),
- self.CommandError('ERROR. Is package manager running?\n')):
+ with self.assertCalls(
+ (self.call.adb.Shell('getprop ro.build.version.sdk'), '19\n'),
+ (self.call.adb.Shell('pm path android'),
+ self.CommandError('ERROR. Is package manager running?\n'))):
with self.assertRaises(device_errors.CommandFailedError):
self.device.GetApplicationPath('android')
diff --git a/build/android/pylib/device_settings.py b/build/android/pylib/device_settings.py
index 246c1d1..73ffa72 100644
--- a/build/android/pylib/device_settings.py
+++ b/build/android/pylib/device_settings.py
@@ -6,6 +6,7 @@
from pylib import constants
from pylib import content_settings
+from pylib.device import device_errors
_LOCK_SCREEN_SETTINGS_PATH = '/data/system/locksettings.db'
_ALTERNATE_LOCK_SCREEN_SETTINGS_PATH = (
@@ -29,17 +30,16 @@
settings to configure.
"""
try:
- sdk_version = int(device.GetProp('ro.build.version.sdk'))
- except ValueError:
- logging.error('Skipping content settings configuration, unknown sdk %s',
- device.GetProp('ro.build.version.sdk'))
+ sdk_version = device.build_version_sdk
+ except device_errors.CommandFailedError as exc:
+ logging.error('Skipping content settings configuration: %s', str(exc))
return
if sdk_version < constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN:
logging.error('Skipping content settings configuration due to outdated sdk')
return
- if device.GetProp('ro.build.type') == 'userdebug':
+ if device.build_type == 'userdebug':
for table, key_value in desired_settings:
settings = content_settings.ContentSettings(table, device)
for key, value in key_value:
@@ -68,7 +68,7 @@
Raises:
Exception if the setting was not properly set.
"""
- if device.GetProp('ro.build.type') != 'userdebug':
+ if device.build_type != 'userdebug':
logging.warning('Unable to disable lockscreen on user builds.')
return
diff --git a/build/android/pylib/gtest/filter/unit_tests_disabled b/build/android/pylib/gtest/filter/unit_tests_disabled
index 6e7be1a..93defbe 100644
--- a/build/android/pylib/gtest/filter/unit_tests_disabled
+++ b/build/android/pylib/gtest/filter/unit_tests_disabled
@@ -67,7 +67,6 @@
PermissionsUpdaterTest.*
ImageLoaderTest.*
ImageLoadingTrackerTest.*
-ScriptBadgeControllerTest.*
ExtensionSettingsFrontendTest.*
ExtensionSettingsSyncTest.*
ExtensionUpdaterTest.*
diff --git a/build/android/pylib/gtest/gtest_config.py b/build/android/pylib/gtest/gtest_config.py
index 20aaf68..cf72d65 100644
--- a/build/android/pylib/gtest/gtest_config.py
+++ b/build/android/pylib/gtest/gtest_config.py
@@ -35,6 +35,7 @@
'sandbox_linux_unittests',
'sql_unittests',
'sync_unit_tests',
+ 'ui_android_unittests',
'ui_base_unittests',
'ui_touch_selection_unittests',
'unit_tests',
diff --git a/build/android/pylib/gtest/gtest_test_instance.py b/build/android/pylib/gtest/gtest_test_instance.py
index 1e87693..f4623e4 100644
--- a/build/android/pylib/gtest/gtest_test_instance.py
+++ b/build/android/pylib/gtest/gtest_test_instance.py
@@ -42,9 +42,12 @@
def __init__(self, options, isolate_delegate):
super(GtestTestInstance, self).__init__()
+ # TODO(jbudorick): Support multiple test suites.
+ if len(options.suite_name) > 1:
+ raise ValueError('Platform mode currently supports only 1 gtest suite')
self._apk_path = os.path.join(
- constants.GetOutDirectory(), '%s_apk' % options.suite_name,
- '%s-debug.apk' % options.suite_name)
+ constants.GetOutDirectory(), '%s_apk' % options.suite_name[0],
+ '%s-debug.apk' % options.suite_name[0])
self._data_deps = []
self._gtest_filter = options.test_filter
if options.isolate_file_path:
diff --git a/build/android/pylib/instrumentation/test_jar.py b/build/android/pylib/instrumentation/test_jar.py
index 4473810..c3faef3 100644
--- a/build/android/pylib/instrumentation/test_jar.py
+++ b/build/android/pylib/instrumentation/test_jar.py
@@ -215,12 +215,10 @@
# Filter out any tests with SDK level requirements that don't match the set
# of attached devices.
- sdk_versions = [
- int(v) for v in
- device_utils.DeviceUtils.parallel().GetProp(
- 'ro.build.version.sdk').pGet(None)]
+ devices = device_utils.DeviceUtils.parallel()
+ min_sdk_version = min(devices.build_version_sdk.pGet(None))
tests = [t for t in tests
- if self._IsTestValidForSdkRange(t, min(sdk_versions))]
+ if self._IsTestValidForSdkRange(t, min_sdk_version)]
return tests
diff --git a/build/android/pylib/instrumentation/test_runner.py b/build/android/pylib/instrumentation/test_runner.py
index 92d80f97..fe444e9 100644
--- a/build/android/pylib/instrumentation/test_runner.py
+++ b/build/android/pylib/instrumentation/test_runner.py
@@ -299,8 +299,8 @@
if 'SmallTest' in annotations:
return 1 * 60
- logging.warn(("Test size not found in annotations for test '{0}', using " +
- "1 minute for timeout.").format(test))
+ logging.warn(("Test size not found in annotations for test '%s', using " +
+ "1 minute for timeout.") % test)
return 1 * 60
def _RunTest(self, test, timeout):
@@ -443,7 +443,7 @@
timeout = (self._GetIndividualTestTimeoutSecs(test) *
self._GetIndividualTestTimeoutScale(test) *
self.tool.GetTimeoutScale())
- if (self.device.GetProp('ro.build.version.sdk')
+ if (self.device.build_version_sdk
< constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN):
timeout *= 10
diff --git a/build/android/pylib/perf/perf_control.py b/build/android/pylib/perf/perf_control.py
index 0da1bcf..97fa4a7 100644
--- a/build/android/pylib/perf/perf_control.py
+++ b/build/android/pylib/perf/perf_control.py
@@ -36,7 +36,7 @@
atexit.register(logging.warning, message)
return
- product_model = self._device.old_interface.GetProductModel()
+ product_model = self._device.product_model
# TODO(epenner): Enable on all devices (http://crbug.com/383566)
if 'Nexus 4' == product_model:
self._ForceAllCpusOnline(True)
@@ -66,7 +66,7 @@
"""Sets the performance mode for the device to its default mode."""
if not self._device.old_interface.IsRootEnabled():
return
- product_model = self._device.old_interface.GetProductModel()
+ product_model = self._device.product_model
if 'Nexus 5' == product_model:
if self._AllCpusAreOnline():
self._SetScalingMaxFreq(2265600)
diff --git a/build/android/pylib/remote/__init__.py b/build/android/pylib/remote/__init__.py
new file mode 100644
index 0000000..4d6aabb
--- /dev/null
+++ b/build/android/pylib/remote/__init__.py
@@ -0,0 +1,3 @@
+# 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.
diff --git a/build/android/pylib/remote/device/__init__.py b/build/android/pylib/remote/device/__init__.py
new file mode 100644
index 0000000..4d6aabb
--- /dev/null
+++ b/build/android/pylib/remote/device/__init__.py
@@ -0,0 +1,3 @@
+# 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.
diff --git a/build/android/pylib/remote/device/remote_device_environment.py b/build/android/pylib/remote/device/remote_device_environment.py
new file mode 100644
index 0000000..871c0a8
--- /dev/null
+++ b/build/android/pylib/remote/device/remote_device_environment.py
@@ -0,0 +1,151 @@
+# 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.
+
+"""Environment setup and teardown for remote devices."""
+
+import os
+import sys
+
+from pylib import constants
+from pylib.base import environment
+from pylib.remote.device import remote_device_helper
+
+sys.path.append(os.path.join(
+ constants.DIR_SOURCE_ROOT, 'third_party', 'requests', 'src'))
+sys.path.append(os.path.join(
+ constants.DIR_SOURCE_ROOT, 'third_party', 'appurify-python', 'src'))
+import appurify.api
+
+
+class RemoteDeviceEnvironment(environment.Environment):
+ """An environment for running on remote devices."""
+
+ def __init__(self, args, error_func):
+ """Constructor.
+
+ Args:
+ args: Command line arguments.
+ error_func: error to show when using bad command line arguments.
+ """
+ super(RemoteDeviceEnvironment, self).__init__()
+
+ if args.api_key_file:
+ with open(args.api_key_file) as api_key_file:
+ self._api_key = api_key_file.read().strip()
+ elif args.api_key:
+ self._api_key = args.api_key
+ else:
+ error_func('Must set api key with --api-key or --api-key-file')
+
+ if args.api_secret_file:
+ with open(args.api_secret_file) as api_secret_file:
+ self._api_secret = api_secret_file.read().strip()
+ elif args.api_secret:
+ self._api_secret = args.api_secret
+ else:
+ error_func('Must set api secret with --api-secret or --api-secret-file')
+
+ if not args.api_protocol:
+ error_func('Must set api protocol with --api-protocol. Example: http')
+ self._api_protocol = args.api_protocol
+
+ if not args.api_address:
+ error_func('Must set api address with --api-address')
+ self._api_address = args.api_address
+
+ if not args.api_port:
+ error_func('Must set api port with --api-port.')
+ self._api_port = args.api_port
+
+ self._access_token = ''
+ self._results_path = args.results_path
+ self._remote_device = args.remote_device
+ self._remote_device_os = args.remote_device_os
+ self._runner_package = args.runner_package
+ self._runner_type = args.runner_type
+ self._device = ''
+ if not args.trigger and not args.collect:
+ self._trigger = True
+ self._collect = True
+ else:
+ self._trigger = args.trigger
+ self._collect = args.collect
+
+ def SetUp(self):
+ """Set up the test environment."""
+ os.environ['APPURIFY_API_PROTO'] = self._api_protocol
+ os.environ['APPURIFY_API_HOST'] = self._api_address
+ os.environ['APPURIFY_API_PORT'] = self._api_port
+ self._GetAccessToken()
+ if self._trigger:
+ self._device = self._SelectDevice()
+
+ def TearDown(self):
+ """Teardown the test environment."""
+ self._RevokeAccessToken()
+
+ def __enter__(self):
+ """Set up the test run when used as a context manager."""
+ self.SetUp()
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ """Tears down the test run when used as a context manager."""
+ self.TearDown()
+
+ def _GetAccessToken(self):
+ """Generates access token for remote device service."""
+ access_token_results = appurify.api.access_token_generate(
+ self._api_key, self._api_secret)
+ remote_device_helper.TestHttpResponse(access_token_results,
+ 'Unable to generate access token.')
+ self._access_token = access_token_results.json()['response']['access_token']
+
+ def _RevokeAccessToken(self):
+ """Destroys access token for remote device service."""
+ revoke_token_results = appurify.api.access_token_revoke(self._access_token)
+ remote_device_helper.TestHttpResponse(revoke_token_results,
+ 'Unable to revoke access token.')
+
+ def _SelectDevice(self):
+ """Select which device to use."""
+ dev_list_res = appurify.api.devices_list(self._access_token)
+ remote_device_helper.TestHttpResponse(dev_list_res,
+ 'Unable to generate access token.')
+ device_list = dev_list_res.json()['response']
+ for device in device_list:
+ if (device['name'] == self._remote_device
+ and device['os_version'] == self._remote_device_os):
+ return device['device_type_id']
+ raise remote_device_helper.RemoteDeviceError(
+ 'No device found: %s %s' % (self._remote_device,
+ self._remote_device_os))
+
+ @property
+ def device(self):
+ return self._device
+
+ @property
+ def token(self):
+ return self._access_token
+
+ @property
+ def results_path(self):
+ return self._results_path
+
+ @property
+ def runner_type(self):
+ return self._runner_type
+
+ @property
+ def runner_package(self):
+ return self._runner_package
+
+ @property
+ def trigger(self):
+ return self._trigger
+
+ @property
+ def collect(self):
+ return self._collect
diff --git a/build/android/pylib/remote/device/remote_device_gtest_run.py b/build/android/pylib/remote/device/remote_device_gtest_run.py
new file mode 100644
index 0000000..fa8d5f9
--- /dev/null
+++ b/build/android/pylib/remote/device/remote_device_gtest_run.py
@@ -0,0 +1,59 @@
+# 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.
+
+"""Run specific test on specific environment."""
+
+import logging
+import os
+import sys
+
+from pylib import constants
+from pylib.base import base_test_result
+from pylib.remote.device import remote_device_test_run
+from pylib.remote.device import remote_device_helper
+
+sys.path.append(os.path.join(
+ constants.DIR_SOURCE_ROOT, 'third_party', 'requests', 'src'))
+sys.path.append(os.path.join(
+ constants.DIR_SOURCE_ROOT, 'third_party', 'appurify-python', 'src'))
+import appurify.api
+import appurify.utils
+
+class RemoteDeviceGtestRun(remote_device_test_run.RemoteDeviceTestRun):
+ """Run gtests and uirobot tests on a remote device."""
+
+ DEFAULT_RUNNER_TYPE = 'robotium'
+ DEFAULT_RUNNER_PACKAGE = (
+ 'org.chromium.native_test.ChromiumNativeTestInstrumentationTestRunner')
+
+ def TestPackage(self):
+ pass
+
+ #override
+ def _TriggerSetUp(self):
+ """Set up the triggering of a test run."""
+ self._app_id = self._UploadAppToDevice(self._test_instance.apk)
+
+ if not self._env.runner_type:
+ runner_type = self.DEFAULT_RUNNER_TYPE
+ logging.info('Using default runner type: %s', self.DEFAULT_RUNNER_TYPE)
+ else:
+ runner_type = self._env.runner_type
+
+ if not self._env.runner_package:
+ runner_package = self.DEFAULT_RUNNER_PACKAGE
+ logging.info('Using default runner package: %s',
+ self.DEFAULT_RUNNER_TYPE)
+ else:
+ runner_package = self._env.runner_package
+
+ self._test_id = self._UploadTestToDevice(runner_type)
+ config_body = {'runner': runner_package}
+ self._SetTestConfig(runner_type, config_body)
+
+ #override
+ def _ParseTestResults(self):
+ # TODO(rnephew): Populate test results object.
+ results = base_test_result.TestRunResults()
+ return results
diff --git a/build/android/pylib/remote/device/remote_device_helper.py b/build/android/pylib/remote/device/remote_device_helper.py
new file mode 100644
index 0000000..a4cd488
--- /dev/null
+++ b/build/android/pylib/remote/device/remote_device_helper.py
@@ -0,0 +1,21 @@
+# 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.
+
+"""Common functions and Exceptions for remote_device_*"""
+
+
+class RemoteDeviceError(Exception):
+ """Exception to throw when problems occur with remote device service."""
+ pass
+
+
+def TestHttpResponse(response, error_msg):
+ """Checks the Http response from remote device service.
+
+ Args:
+ response: response dict from the remote device service.
+ error_msg: Error message to display if bad response is seen.
+ """
+ if response.status_code != 200:
+ raise RemoteDeviceError(error_msg)
diff --git a/build/android/pylib/remote/device/remote_device_test_run.py b/build/android/pylib/remote/device/remote_device_test_run.py
new file mode 100644
index 0000000..97e44b0
--- /dev/null
+++ b/build/android/pylib/remote/device/remote_device_test_run.py
@@ -0,0 +1,176 @@
+# 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.
+
+"""Run specific test on specific environment."""
+
+import logging
+import os
+import sys
+import tempfile
+import time
+
+from pylib import constants
+from pylib.base import test_run
+from pylib.remote.device import remote_device_helper
+
+sys.path.append(os.path.join(
+ constants.DIR_SOURCE_ROOT, 'third_party', 'requests', 'src'))
+sys.path.append(os.path.join(
+ constants.DIR_SOURCE_ROOT, 'third_party', 'appurify-python', 'src'))
+import appurify.api
+import appurify.utils
+
+class RemoteDeviceTestRun(test_run.TestRun):
+ """Run gtests and uirobot tests on a remote device."""
+
+ WAIT_TIME = 5
+ COMPLETE = 'complete'
+
+ def __init__(self, env, test_instance):
+ """Constructor.
+
+ Args:
+ env: Environment the tests will run in.
+ test_instance: The test that will be run.
+ """
+ super(RemoteDeviceTestRun, self).__init__(env, test_instance)
+ self._env = env
+ self._test_instance = test_instance
+ self._app_id = ''
+ self._test_id = ''
+ self._results = ''
+
+ def TestPackage(self):
+ pass
+
+ #override
+ def RunTests(self):
+ """Run the test."""
+ if self._env.trigger:
+ test_start_res = appurify.api.tests_run(
+ self._env.token, self._env.device, self._app_id, self._test_id)
+ remote_device_helper.TestHttpResponse(
+ test_start_res, 'Unable to run test.')
+ test_run_id = test_start_res.json()['response']['test_run_id']
+ if not self._env.collect:
+ assert isinstance(self._env.trigger, basestring), (
+ 'File for storing test_run_id must be a string.')
+ with open(self._env.trigger, 'w') as test_run_id_file:
+ test_run_id_file.write(test_run_id)
+
+ if self._env.collect:
+ if not self._env.trigger:
+ assert isinstance(self._env.trigger, basestring), (
+ 'File for storing test_run_id must be a string.')
+ with open(self._env.collect, 'r') as test_run_id_file:
+ test_run_id = test_run_id_file.read()
+ while self._GetTestStatus(test_run_id) != self.COMPLETE:
+ time.sleep(self.WAIT_TIME)
+ self._DownloadTestResults(self._env.results_path)
+ return self._ParseTestResults()
+
+ #override
+ def TearDown(self):
+ """Tear down the test run."""
+ pass
+
+ def __enter__(self):
+ """Set up the test run when used as a context manager."""
+ self.SetUp()
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ """Tear down the test run when used as a context manager."""
+ self.TearDown()
+
+ #override
+ def SetUp(self):
+ """Set up a test run."""
+ if self._env.trigger:
+ self._TriggerSetUp()
+
+ def _TriggerSetUp(self):
+ """Set up the triggering of a test run."""
+ raise NotImplementedError
+
+ def _ParseTestResults(self):
+ raise NotImplementedError
+
+ def _GetTestByName(self, test_name):
+ """Gets test_id for specific test.
+
+ Args:
+ test_name: Test to find the ID of.
+ """
+ test_list_res = appurify.api.tests_list(self._env.token)
+ remote_device_helper.TestHttpResponse(test_list_res,
+ 'Unable to get tests list.')
+ for test in test_list_res.json()['response']:
+ if test['test_type'] == test_name:
+ return test['test_id']
+ raise remote_device_helper.RemoteDeviceError(
+ 'No test found with name %s' % (test_name))
+
+ def _DownloadTestResults(self, results_path):
+ """Download the test results from remote device service.
+
+ Args:
+ results_path: path to download results to.
+ """
+ if results_path:
+ if not os.path.exists(os.path.basename(results_path)):
+ os.makedirs(os.path.basename(results_path))
+ appurify.utils.wget(self._results['results']['url'], results_path)
+
+ def _GetTestStatus(self, test_run_id):
+ """Checks the state of the test, and sets self._results
+
+ Args:
+ test_run_id: Id of test on on remote service.
+ """
+
+ test_check_res = appurify.api.tests_check_result(self._env.token,
+ test_run_id)
+ remote_device_helper.TestHttpResponse(test_check_res,
+ 'Unable to get test status.')
+ self._results = test_check_res.json()['response']
+ return self._results['status']
+
+ def _UploadAppToDevice(self, apk_path):
+ """Upload app to device."""
+ apk_name = os.path.basename(apk_path)
+ with open(apk_path, 'rb') as apk_src:
+ upload_results = appurify.api.apps_upload(self._env.token,
+ apk_src, 'raw', name=apk_name)
+ remote_device_helper.TestHttpResponse(
+ upload_results, 'Unable to upload %s.' %(apk_path))
+ return upload_results.json()['response']['app_id']
+
+ def _UploadTestToDevice(self, test_type):
+ """Upload test to device
+ Args:
+ test_type: Type of test that is being uploaded. Ex. uirobot, gtest..
+ """
+ with open(self._test_instance.apk, 'rb') as test_src:
+ upload_results = appurify.api.tests_upload(
+ self._env.token, test_src, 'raw', test_type, app_id=self._app_id)
+ remote_device_helper.TestHttpResponse(upload_results,
+ 'Unable to upload %s.' %(self._test_instance.apk))
+ return upload_results.json()['response']['test_id']
+
+ def _SetTestConfig(self, runner_type, body):
+ """Generates and uploads config file for test.
+ Args:
+ extras: Extra arguments to set in the config file.
+ """
+ with tempfile.TemporaryFile() as config:
+ config_data = ['[appurify]', '[%s]' % runner_type]
+ config_data.extend('%s=%s' % (k, v) for k, v in body.iteritems())
+ config.write(''.join('%s\n' % l for l in config_data))
+ config.flush()
+ config.seek(0)
+ config_response = appurify.api.config_upload(self._env.token,
+ config, self._test_id)
+ remote_device_helper.TestHttpResponse(config_response,
+ 'Unable to upload test config.')
diff --git a/build/android/pylib/remote/device/remote_device_uirobot_run.py b/build/android/pylib/remote/device/remote_device_uirobot_run.py
new file mode 100644
index 0000000..d2d6f36
--- /dev/null
+++ b/build/android/pylib/remote/device/remote_device_uirobot_run.py
@@ -0,0 +1,58 @@
+# 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.
+
+"""Run specific test on specific environment."""
+
+import logging
+import os
+import sys
+
+from pylib import constants
+from pylib.base import base_test_result
+from pylib.remote.device import remote_device_test_run
+from pylib.remote.device import remote_device_helper
+
+sys.path.append(os.path.join(
+ constants.DIR_SOURCE_ROOT, 'third_party', 'requests', 'src'))
+sys.path.append(os.path.join(
+ constants.DIR_SOURCE_ROOT, 'third_party', 'appurify-python', 'src'))
+import appurify.api
+import appurify.utils
+
+class RemoteDeviceUirobotRun(remote_device_test_run.RemoteDeviceTestRun):
+ """Run uirobot tests on a remote device."""
+
+ DEFAULT_RUNNER_TYPE = 'android_robot'
+
+ def __init__(self, env, test_instance):
+ """Constructor.
+
+ Args:
+ env: Environment the tests will run in.
+ test_instance: The test that will be run.
+ """
+ super(RemoteDeviceUirobotRun, self).__init__(env, test_instance)
+
+ def TestPackage(self):
+ pass
+
+ #override
+ def _TriggerSetUp(self):
+ """Set up the triggering of a test run."""
+ self._app_id = self._UploadAppToDevice(self._test_instance.apk_under_test)
+ if not self._env.runner_type:
+ runner_type = self.DEFAULT_RUNNER_TYPE
+ logging.info('Using default runner type: %s', self.DEFAULT_RUNNER_TYPE)
+ else:
+ runner_type = self._env.runner_type
+ self._test_id = self._GetTestByName(runner_type)
+ config_body = {'duration': self._test_instance.minutes}
+ self._SetTestConfig(runner_type, config_body)
+
+ #override
+ def _ParseTestResults(self):
+ # TODO(rnephew): Populate test results object.
+ results = remote_device_test_run.TestRunResults()
+ return results
+
diff --git a/build/android/pylib/uirobot/__init__.py b/build/android/pylib/uirobot/__init__.py
new file mode 100644
index 0000000..5cac026
--- /dev/null
+++ b/build/android/pylib/uirobot/__init__.py
@@ -0,0 +1,4 @@
+# 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.
+
diff --git a/build/android/pylib/uirobot/uirobot_test_instance.py b/build/android/pylib/uirobot/uirobot_test_instance.py
new file mode 100644
index 0000000..b129f89
--- /dev/null
+++ b/build/android/pylib/uirobot/uirobot_test_instance.py
@@ -0,0 +1,51 @@
+# 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.
+
+import os
+
+from pylib import constants
+from pylib.base import test_instance
+
+class UirobotTestInstance(test_instance.TestInstance):
+
+ def __init__(self, args):
+ """Constructor.
+
+ Args:
+ args: Command line arguments.
+ """
+ super(UirobotTestInstance, self).__init__()
+ self._apk_under_test = os.path.join(
+ constants.GetOutDirectory(), args.apk_under_test)
+ self._minutes = args.minutes
+
+ #override
+ def TestType(self):
+ """Returns type of test."""
+ return 'uirobot'
+
+ #override
+ def SetUp(self):
+ """Setup for test."""
+ pass
+
+ #override
+ def TearDown(self):
+ """Teardown for test."""
+ pass
+
+ @property
+ def apk_under_test(self):
+ """Returns the app to run the test on."""
+ return self._apk_under_test
+
+ @property
+ def suite(self):
+ """Returns the test suite, none for uirobot."""
+ return None
+
+ @property
+ def minutes(self):
+ """Returns the number of minutes to run the uirobot for."""
+ return self._minutes
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index 68827b9..657e7c2 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -119,6 +119,45 @@
os.environ['PATH'] = adb_dir + os.pathsep + os.environ['PATH']
+def AddRemoteDeviceOptions(parser):
+ group = parser.add_argument_group('Remote Device Options')
+
+ group.add_argument('--trigger', default='',
+ help=('Only triggers the test if set. Stores test_run_id '
+ 'in given file path. '))
+ group.add_argument('--collect', default='',
+ help=('Only collects the test results if set. '
+ 'Gets test_run_id from given file path.'))
+ group.add_argument('--remote-device', default='Nexus 5',
+ help=('Device type to run test on.'))
+ group.add_argument('--remote-device-os', default='4.4.2',
+ help=('OS to have on the device.'))
+ group.add_argument('--results-path', default='',
+ help=('File path to download results to.'))
+ group.add_argument('--api-protocol',
+ help=('HTTP protocol to use. (http or https)'))
+ group.add_argument('--api-address', help=('Address to send HTTP requests.'))
+ group.add_argument('--api-port', help=('Port to send HTTP requests to.'))
+ group.add_argument('--runner-type', default='',
+ help=('Type of test to run as.'))
+ group.add_argument('--runner-package', default='',
+ help=('Package name of test.'))
+ group.add_argument('--apk-under-test', default='apks/Chrome.apk',
+ help=('APK to run tests on.'))
+
+ api_secret_group = group.add_mutually_exclusive_group()
+ api_secret_group.add_argument('--api-secret', default='',
+ help=('API secret for remote devices.'))
+ api_secret_group.add_argument('--api-secret-file', default='',
+ help=('Path to file that contains API secret.'))
+
+ api_key_group = group.add_mutually_exclusive_group()
+ api_key_group.add_argument('--api-key', default='',
+ help=('API key for remote devices.'))
+ api_key_group.add_argument('--api-key-file', default='',
+ help=('Path to file that contains API key.'))
+
+
def AddDeviceOptions(parser):
"""Adds device options to |parser|."""
group = parser.add_argument_group(title='Device Options')
@@ -166,6 +205,7 @@
'path')
AddDeviceOptions(parser)
AddCommonOptions(parser)
+ AddRemoteDeviceOptions(parser)
def AddLinkerTestOptions(parser):
@@ -426,7 +466,6 @@
AddCommonOptions(parser)
AddDeviceOptions(parser)
-
def ProcessMonkeyTestOptions(args):
"""Processes all monkey test options.
@@ -452,6 +491,17 @@
args.seed,
args.extra_args)
+def AddUirobotTestOptions(parser):
+ """Adds uirobot test options to |option_parser|."""
+ group = parser.add_argument_group('Uirobot Test Options')
+
+ group.add_argument(
+ '--minutes', default=5, type=int,
+ help='Number of minutes to run uirobot test [default: %default].')
+
+ AddCommonOptions(parser)
+ AddDeviceOptions(parser)
+ AddRemoteDeviceOptions(parser)
def AddPerfTestOptions(parser):
"""Adds perf test options to |parser|."""
@@ -812,7 +862,7 @@
ProcessCommonOptions(args)
if args.enable_platform_mode:
- return RunTestsInPlatformMode(args, parser.error)
+ return RunTestsInPlatformMode(args, parser)
if command in constants.LOCAL_MACHINE_TESTS:
devices = []
@@ -845,7 +895,7 @@
_SUPPORTED_IN_PLATFORM_MODE = [
# TODO(jbudorick): Add support for more test types.
- 'gtest',
+ 'gtest', 'uirobot',
]
@@ -860,6 +910,9 @@
args, env, test, parser.error) as test_run:
results = test_run.RunTests()
+ if args.trigger:
+ return 0 # Not returning results, only triggering.
+
report_results.LogFull(
results=results,
test_type=test.TestType(),
@@ -871,7 +924,7 @@
json_results.GenerateJsonResultsFile(
results, args.json_results_file)
- return results
+ return 0 if results.DidRunPass() else 1
CommandConfigTuple = collections.namedtuple(
@@ -902,6 +955,9 @@
'linker': CommandConfigTuple(
AddLinkerTestOptions,
'Linker tests'),
+ 'uirobot': CommandConfigTuple(
+ AddUirobotTestOptions,
+ 'Uirobot test'),
}
diff --git a/build/android/tombstones.py b/build/android/tombstones.py
index fd060ad..a78d89f 100755
--- a/build/android/tombstones.py
+++ b/build/android/tombstones.py
@@ -173,7 +173,7 @@
device_now = _GetDeviceDateTime(device)
for tombstone_file, tombstone_time in tombstones:
ret += [{'serial': str(device),
- 'device_abi': device.GetProp('ro.product.cpu.abi'),
+ 'device_abi': device.product_cpu_abi,
'device_now': device_now,
'time': tombstone_time,
'file': tombstone_file,
diff --git a/build/common.gypi b/build/common.gypi
index c899e14..30239f1 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -619,7 +619,7 @@
# completion, but only actually requires them for layout tests. However,
# we need to maintain all the old behaviors while the plumbing is put in
# place on both sides of the repo boundary.
- 'enable_load_completion_hacks%': 1,
+ 'enable_load_completion_hacks%': 0,
# Automatically select platforms under ozone. Turn this off to
# build only explicitly selected platforms.
@@ -706,6 +706,13 @@
'use_dbus%': 0,
}],
+ # Libxkbcommon usage.
+ ['use_ozone==1 and embedded==0', {
+ 'use_xkbcommon%': 1,
+ }, {
+ 'use_xkbcommon%': 0,
+ }],
+
# We always use skia text rendering in Aura on Windows, since GDI
# doesn't agree with our BackingStore.
# TODO(beng): remove once skia text rendering is on by default.
@@ -1087,6 +1094,7 @@
'use_cairo%': '<(use_cairo)',
'use_ozone%': '<(use_ozone)',
'use_ozone_evdev%': '<(use_ozone_evdev)',
+ 'use_xkbcommon%': '<(use_xkbcommon)',
'use_clipboard_aurax11%': '<(use_clipboard_aurax11)',
'desktop_linux%': '<(desktop_linux)',
'use_x11%': '<(use_x11)',
@@ -2521,6 +2529,9 @@
# code generated by flex (used in angle) contains that keyword.
# http://crbug.com/255186
'-Wno-deprecated-register',
+
+ # TODO(hans): Get this cleaned up.
+ '-Wno-inconsistent-missing-override',
],
},
'includes': [ 'set_clang_warning_flags.gypi', ],
@@ -4185,6 +4196,13 @@
],
}],
],
+ 'conditions': [
+ ['OS=="mac"', {
+ 'cflags': [
+ '-mllvm -asan-globals=0', # http://crbug.com/352073
+ ],
+ }],
+ ],
}],
['ubsan==1', {
'target_conditions': [
@@ -4235,7 +4253,7 @@
'target_conditions': [
['_toolset=="target"', {
'cflags': [
- '-mllvm -asan-coverage=<(asan_coverage)',
+ '-fsanitize-coverage=<(asan_coverage)',
],
}],
],
@@ -4606,16 +4624,6 @@
# TODO(eugenis): find a way to reenable this.
'-mllvm -asan-globals=0',
],
- 'conditions': [
- ['target_arch=="arm"', {
- 'ldflags': [
- # TODO(hans): The ASan runtime is no longer automatically
- # added to the link line when using -nostdlib. Can we
- # stop adding -nostdlib? (crbug.com/423429)
- '<!(cd <(DEPTH) && pwd -P)/<(make_clang_dir)/lib/clang/3.6.0/lib/linux/libclang_rt.asan-arm-android.so',
- ],
- }],
- ],
}],
['android_webview_build==0', {
'defines': [
@@ -4900,6 +4908,7 @@
'xcode_settings': {
'OTHER_CFLAGS': [
'-fsanitize=address',
+ '-mllvm -asan-globals=0', # http://crbug.com/352073
'-gline-tables-only',
],
},
@@ -4908,7 +4917,7 @@
'target_conditions': [
['_toolset=="target"', {
'cflags': [
- '-mllvm -asan-coverage=<(asan_coverage)',
+ '-fsanitize-coverage=<(asan_coverage)',
],
}],
],
diff --git a/build/config/OWNERS b/build/config/OWNERS
index 9b79b9a..bd53091 100644
--- a/build/config/OWNERS
+++ b/build/config/OWNERS
@@ -1,2 +1,6 @@
-set noparent
brettw@chromium.org
+dpranke@chromium.org
+scottmg@chromium.org
+
+per-file BUILDCONFIG.gn=brettw@chromium.org
+per-file BUILDCONFIG.gn=set noparent
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 81269d6..c221ddd 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -762,6 +762,9 @@
# TODO(thakis): Remove, http://crbug.com/263960
"-Wno-reserved-user-defined-literal",
+
+ # TODO(hans): Get this cleaned up.
+ "-Wno-inconsistent-missing-override",
]
}
if (gcc_version >= 48) {
diff --git a/build/ios/grit_whitelist.txt b/build/ios/grit_whitelist.txt
index 0d9faa0..b8d3caa 100644
--- a/build/ios/grit_whitelist.txt
+++ b/build/ios/grit_whitelist.txt
@@ -464,8 +464,6 @@
IDS_FLAGS_COMPOSITING_FOR_FIXED_POSITION_DESCRIPTION
IDS_FLAGS_COMPOSITING_FOR_FIXED_POSITION_HIGH_DPI
IDS_FLAGS_COMPOSITING_FOR_FIXED_POSITION_NAME
-IDS_FLAGS_COMPOSITING_FOR_TRANSITION_DESCRIPTION
-IDS_FLAGS_COMPOSITING_FOR_TRANSITION_NAME
IDS_FLAGS_CONFLICTS_CHECK_DESCRIPTION
IDS_FLAGS_CONFLICTS_CHECK_NAME
IDS_FLAGS_DEBUG_PACKED_APP_DESCRIPTION
diff --git a/build/linux/system.gyp b/build/linux/system.gyp
index cd0288b..09ee713 100644
--- a/build/linux/system.gyp
+++ b/build/linux/system.gyp
@@ -465,6 +465,27 @@
},
],
}],
+ ['use_xkbcommon==1', {
+ 'targets': [
+ {
+ 'target_name': 'xkbcommon',
+ 'type': 'none',
+ 'direct_dependent_settings': {
+ 'cflags': [
+ '<!@(<(pkg-config) --cflags xkbcommon)'
+ ],
+ },
+ 'link_settings': {
+ 'ldflags': [
+ '<!@(<(pkg-config) --libs-only-L --libs-only-other xkbcommon)',
+ ],
+ 'libraries': [
+ '<!@(<(pkg-config) --libs-only-l xkbcommon)',
+ ],
+ },
+ },
+ ],
+ }],
['ozone_platform_gbm==1', {
'targets': [
{
diff --git a/build/sanitizers/sanitizer_options.cc b/build/sanitizers/sanitizer_options.cc
index 614a4a6..af78bf8 100644
--- a/build/sanitizers/sanitizer_options.cc
+++ b/build/sanitizers/sanitizer_options.cc
@@ -72,7 +72,7 @@
const char *kAsanDefaultOptions =
"strict_memcmp=0 replace_intrin=0 check_printf=1 use_sigaltstack=1 "
"strip_path_prefix=Release/../../ fast_unwind_on_fatal=1 "
- "detect_stack_use_after_return=1 ";
+ "detect_stack_use_after_return=1 detect_odr_violation=0 ";
static const char kNaClDefaultOptions[] = "handle_segv=0";
static const char kNaClFlag[] = "--type=nacl-loader";
#endif // OS_LINUX
diff --git a/build/toolchain/OWNERS b/build/toolchain/OWNERS
index 9b79b9a..c6cda3f 100644
--- a/build/toolchain/OWNERS
+++ b/build/toolchain/OWNERS
@@ -1,2 +1,3 @@
-set noparent
brettw@chromium.org
+dpranke@chromium.org
+scottmg@chromium.org
diff --git a/build/toolchain/win/setup_toolchain.py b/build/toolchain/win/setup_toolchain.py
index 6b7ea7a..e8826b0 100644
--- a/build/toolchain/win/setup_toolchain.py
+++ b/build/toolchain/win/setup_toolchain.py
@@ -67,7 +67,8 @@
# We only support x64-hosted tools.
# TODO(scottmg|dpranke): Non-depot_tools toolchain: need to get Visual
# Studio install location from registry.
- return [os.path.normpath(os.path.join(FIND_VS_IN_REG, 'VC/vcvarsall.bat')),
+ return [os.path.normpath(os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'],
+ 'VC/vcvarsall.bat')),
'amd64_x86' if target_arch == 'x86' else 'amd64']
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py
index fb7e142..5373f03 100644
--- a/build/vs_toolchain.py
+++ b/build/vs_toolchain.py
@@ -202,7 +202,7 @@
os.environ['WINDOWSSDKDIR'],
os.environ['GYP_MSVS_VERSION'],
os.environ.get('WDK_DIR', ''),
- ';'.join(runtime_dll_dirs))
+ ';'.join(runtime_dll_dirs or ['None']))
def main():
diff --git a/build/whitespace_file.txt b/build/whitespace_file.txt
index 526203f..192677e 100644
--- a/build/whitespace_file.txt
+++ b/build/whitespace_file.txt
@@ -145,3 +145,5 @@
Oh god the bots are red! I'm blind! Mmmm, cronuts.
If you stand on your head, you will get footprints in your hair.
+
+sigh
\ No newline at end of file
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 592fd6e..13e974d 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -581,6 +581,8 @@
"test/fake_tile_manager_client.h",
"test/fake_ui_resource_layer_tree_host_impl.cc",
"test/fake_ui_resource_layer_tree_host_impl.h",
+ "test/failure_output_surface.cc",
+ "test/failure_output_surface.h",
"test/geometry_test_utils.cc",
"test/geometry_test_utils.h",
"test/test_in_process_context_provider.cc",
diff --git a/cc/base/tiling_data.cc b/cc/base/tiling_data.cc
index 7b39878..95fd68b 100644
--- a/cc/base/tiling_data.cc
+++ b/cc/base/tiling_data.cc
@@ -293,40 +293,39 @@
max_texture_size_.height(), tiling_size_.height(), border_texels_);
}
-TilingData::BaseIterator::BaseIterator(const TilingData* tiling_data)
- : tiling_data_(tiling_data),
- index_x_(-1),
- index_y_(-1) {
+TilingData::BaseIterator::BaseIterator() : index_x_(-1), index_y_(-1) {
}
-TilingData::Iterator::Iterator() : BaseIterator(nullptr) { done(); }
+TilingData::Iterator::Iterator() {
+ done();
+}
TilingData::Iterator::Iterator(const TilingData* tiling_data,
const gfx::Rect& consider_rect,
bool include_borders)
- : BaseIterator(tiling_data), left_(-1), right_(-1), bottom_(-1) {
- if (tiling_data_->num_tiles_x() <= 0 || tiling_data_->num_tiles_y() <= 0) {
+ : left_(-1), right_(-1), bottom_(-1) {
+ if (tiling_data->num_tiles_x() <= 0 || tiling_data->num_tiles_y() <= 0) {
done();
return;
}
- gfx::Rect tiling_bounds_rect(tiling_data_->tiling_size());
+ gfx::Rect tiling_bounds_rect(tiling_data->tiling_size());
gfx::Rect rect(consider_rect);
rect.Intersect(tiling_bounds_rect);
gfx::Rect top_left_tile;
if (include_borders) {
- index_x_ = tiling_data_->FirstBorderTileXIndexFromSrcCoord(rect.x());
- index_y_ = tiling_data_->FirstBorderTileYIndexFromSrcCoord(rect.y());
- right_ = tiling_data_->LastBorderTileXIndexFromSrcCoord(rect.right() - 1);
- bottom_ = tiling_data_->LastBorderTileYIndexFromSrcCoord(rect.bottom() - 1);
- top_left_tile = tiling_data_->TileBoundsWithBorder(index_x_, index_y_);
+ index_x_ = tiling_data->FirstBorderTileXIndexFromSrcCoord(rect.x());
+ index_y_ = tiling_data->FirstBorderTileYIndexFromSrcCoord(rect.y());
+ right_ = tiling_data->LastBorderTileXIndexFromSrcCoord(rect.right() - 1);
+ bottom_ = tiling_data->LastBorderTileYIndexFromSrcCoord(rect.bottom() - 1);
+ top_left_tile = tiling_data->TileBoundsWithBorder(index_x_, index_y_);
} else {
- index_x_ = tiling_data_->TileXIndexFromSrcCoord(rect.x());
- index_y_ = tiling_data_->TileYIndexFromSrcCoord(rect.y());
- right_ = tiling_data_->TileXIndexFromSrcCoord(rect.right() - 1);
- bottom_ = tiling_data_->TileYIndexFromSrcCoord(rect.bottom() - 1);
- top_left_tile = tiling_data_->TileBounds(index_x_, index_y_);
+ index_x_ = tiling_data->TileXIndexFromSrcCoord(rect.x());
+ index_y_ = tiling_data->TileYIndexFromSrcCoord(rect.y());
+ right_ = tiling_data->TileXIndexFromSrcCoord(rect.right() - 1);
+ bottom_ = tiling_data->TileYIndexFromSrcCoord(rect.bottom() - 1);
+ top_left_tile = tiling_data->TileBounds(index_x_, index_y_);
}
left_ = index_x_;
@@ -355,8 +354,7 @@
const TilingData* tiling_data,
const gfx::Rect& consider_rect,
const gfx::Rect& ignore_rect)
- : BaseIterator(tiling_data),
- consider_left_(-1),
+ : consider_left_(-1),
consider_top_(-1),
consider_right_(-1),
consider_bottom_(-1),
@@ -364,12 +362,12 @@
ignore_top_(-1),
ignore_right_(-1),
ignore_bottom_(-1) {
- if (tiling_data_->num_tiles_x() <= 0 || tiling_data_->num_tiles_y() <= 0) {
+ if (tiling_data->num_tiles_x() <= 0 || tiling_data->num_tiles_y() <= 0) {
done();
return;
}
- gfx::Rect tiling_bounds_rect(tiling_data_->tiling_size());
+ gfx::Rect tiling_bounds_rect(tiling_data->tiling_size());
gfx::Rect consider(consider_rect);
gfx::Rect ignore(ignore_rect);
consider.Intersect(tiling_bounds_rect);
@@ -379,17 +377,16 @@
return;
}
- consider_left_ = tiling_data_->TileXIndexFromSrcCoord(consider.x());
- consider_top_ = tiling_data_->TileYIndexFromSrcCoord(consider.y());
- consider_right_ = tiling_data_->TileXIndexFromSrcCoord(consider.right() - 1);
- consider_bottom_ =
- tiling_data_->TileYIndexFromSrcCoord(consider.bottom() - 1);
+ consider_left_ = tiling_data->TileXIndexFromSrcCoord(consider.x());
+ consider_top_ = tiling_data->TileYIndexFromSrcCoord(consider.y());
+ consider_right_ = tiling_data->TileXIndexFromSrcCoord(consider.right() - 1);
+ consider_bottom_ = tiling_data->TileYIndexFromSrcCoord(consider.bottom() - 1);
if (!ignore.IsEmpty()) {
- ignore_left_ = tiling_data_->TileXIndexFromSrcCoord(ignore.x());
- ignore_top_ = tiling_data_->TileYIndexFromSrcCoord(ignore.y());
- ignore_right_ = tiling_data_->TileXIndexFromSrcCoord(ignore.right() - 1);
- ignore_bottom_ = tiling_data_->TileYIndexFromSrcCoord(ignore.bottom() - 1);
+ ignore_left_ = tiling_data->TileXIndexFromSrcCoord(ignore.x());
+ ignore_top_ = tiling_data->TileYIndexFromSrcCoord(ignore.y());
+ ignore_right_ = tiling_data->TileXIndexFromSrcCoord(ignore.right() - 1);
+ ignore_bottom_ = tiling_data->TileYIndexFromSrcCoord(ignore.bottom() - 1);
// Clamp ignore indices to consider indices.
ignore_left_ = std::max(ignore_left_, consider_left_);
@@ -440,8 +437,7 @@
return *this;
}
-TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator()
- : BaseIterator(nullptr) {
+TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() {
done();
}
@@ -450,8 +446,7 @@
const gfx::Rect& consider_rect,
const gfx::Rect& ignore_rect,
const gfx::Rect& center_rect)
- : BaseIterator(tiling_data),
- consider_left_(-1),
+ : consider_left_(-1),
consider_top_(-1),
consider_right_(-1),
consider_bottom_(-1),
@@ -465,12 +460,12 @@
current_step_(0),
horizontal_step_count_(0),
vertical_step_count_(0) {
- if (tiling_data_->num_tiles_x() <= 0 || tiling_data_->num_tiles_y() <= 0) {
+ if (tiling_data->num_tiles_x() <= 0 || tiling_data->num_tiles_y() <= 0) {
done();
return;
}
- gfx::Rect tiling_bounds_rect(tiling_data_->tiling_size());
+ gfx::Rect tiling_bounds_rect(tiling_data->tiling_size());
gfx::Rect consider(consider_rect);
gfx::Rect ignore(ignore_rect);
gfx::Rect center(center_rect);
@@ -481,17 +476,16 @@
return;
}
- consider_left_ = tiling_data_->TileXIndexFromSrcCoord(consider.x());
- consider_top_ = tiling_data_->TileYIndexFromSrcCoord(consider.y());
- consider_right_ = tiling_data_->TileXIndexFromSrcCoord(consider.right() - 1);
- consider_bottom_ =
- tiling_data_->TileYIndexFromSrcCoord(consider.bottom() - 1);
+ consider_left_ = tiling_data->TileXIndexFromSrcCoord(consider.x());
+ consider_top_ = tiling_data->TileYIndexFromSrcCoord(consider.y());
+ consider_right_ = tiling_data->TileXIndexFromSrcCoord(consider.right() - 1);
+ consider_bottom_ = tiling_data->TileYIndexFromSrcCoord(consider.bottom() - 1);
if (!ignore.IsEmpty()) {
- ignore_left_ = tiling_data_->TileXIndexFromSrcCoord(ignore.x());
- ignore_top_ = tiling_data_->TileYIndexFromSrcCoord(ignore.y());
- ignore_right_ = tiling_data_->TileXIndexFromSrcCoord(ignore.right() - 1);
- ignore_bottom_ = tiling_data_->TileYIndexFromSrcCoord(ignore.bottom() - 1);
+ ignore_left_ = tiling_data->TileXIndexFromSrcCoord(ignore.x());
+ ignore_top_ = tiling_data->TileYIndexFromSrcCoord(ignore.y());
+ ignore_right_ = tiling_data->TileXIndexFromSrcCoord(ignore.right() - 1);
+ ignore_bottom_ = tiling_data->TileYIndexFromSrcCoord(ignore.bottom() - 1);
// Clamp ignore indices to consider indices.
ignore_left_ = std::max(ignore_left_, consider_left_);
@@ -666,8 +660,7 @@
}
}
-TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator()
- : BaseIterator(nullptr) {
+TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() {
done();
}
@@ -676,8 +669,7 @@
const gfx::Rect& consider_rect,
const gfx::Rect& ignore_rect,
const gfx::Rect& center_rect)
- : BaseIterator(tiling_data),
- consider_left_(-1),
+ : consider_left_(-1),
consider_top_(-1),
consider_right_(-1),
consider_bottom_(-1),
@@ -695,12 +687,12 @@
current_step_(0),
horizontal_step_count_(0),
vertical_step_count_(0) {
- if (tiling_data_->num_tiles_x() <= 0 || tiling_data_->num_tiles_y() <= 0) {
+ if (tiling_data->num_tiles_x() <= 0 || tiling_data->num_tiles_y() <= 0) {
done();
return;
}
- gfx::Rect tiling_bounds_rect(tiling_data_->tiling_size());
+ gfx::Rect tiling_bounds_rect(tiling_data->tiling_size());
gfx::Rect consider(consider_rect);
gfx::Rect ignore(ignore_rect);
gfx::Rect center(center_rect);
@@ -711,17 +703,16 @@
return;
}
- consider_left_ = tiling_data_->TileXIndexFromSrcCoord(consider.x());
- consider_top_ = tiling_data_->TileYIndexFromSrcCoord(consider.y());
- consider_right_ = tiling_data_->TileXIndexFromSrcCoord(consider.right() - 1);
- consider_bottom_ =
- tiling_data_->TileYIndexFromSrcCoord(consider.bottom() - 1);
+ consider_left_ = tiling_data->TileXIndexFromSrcCoord(consider.x());
+ consider_top_ = tiling_data->TileYIndexFromSrcCoord(consider.y());
+ consider_right_ = tiling_data->TileXIndexFromSrcCoord(consider.right() - 1);
+ consider_bottom_ = tiling_data->TileYIndexFromSrcCoord(consider.bottom() - 1);
if (!ignore.IsEmpty()) {
- ignore_left_ = tiling_data_->TileXIndexFromSrcCoord(ignore.x());
- ignore_top_ = tiling_data_->TileYIndexFromSrcCoord(ignore.y());
- ignore_right_ = tiling_data_->TileXIndexFromSrcCoord(ignore.right() - 1);
- ignore_bottom_ = tiling_data_->TileYIndexFromSrcCoord(ignore.bottom() - 1);
+ ignore_left_ = tiling_data->TileXIndexFromSrcCoord(ignore.x());
+ ignore_top_ = tiling_data->TileYIndexFromSrcCoord(ignore.y());
+ ignore_right_ = tiling_data->TileXIndexFromSrcCoord(ignore.right() - 1);
+ ignore_bottom_ = tiling_data->TileYIndexFromSrcCoord(ignore.bottom() - 1);
// Clamp ignore indices to consider indices.
ignore_left_ = std::max(ignore_left_, consider_left_);
diff --git a/cc/base/tiling_data.h b/cc/base/tiling_data.h
index 5e8a4d6..45b763e 100644
--- a/cc/base/tiling_data.h
+++ b/cc/base/tiling_data.h
@@ -76,13 +76,12 @@
}
protected:
- explicit BaseIterator(const TilingData* tiling_data);
+ BaseIterator();
void done() {
index_x_ = -1;
index_y_ = -1;
}
- const TilingData* tiling_data_;
int index_x_;
int index_y_;
};
diff --git a/cc/blink/web_external_bitmap_impl.cc b/cc/blink/web_external_bitmap_impl.cc
index a101079..e2c67e4 100644
--- a/cc/blink/web_external_bitmap_impl.cc
+++ b/cc/blink/web_external_bitmap_impl.cc
@@ -4,18 +4,18 @@
#include "cc/blink/web_external_bitmap_impl.h"
-#include "base/memory/shared_memory.h"
+#include "cc/resources/shared_bitmap.h"
namespace cc_blink {
namespace {
-SharedMemoryAllocationFunction g_memory_allocator;
+SharedBitmapAllocationFunction g_memory_allocator;
} // namespace
-void SetSharedMemoryAllocationFunction(
- SharedMemoryAllocationFunction allocator) {
+void SetSharedBitmapAllocationFunction(
+ SharedBitmapAllocationFunction allocator) {
g_memory_allocator = allocator;
}
@@ -27,10 +27,7 @@
void WebExternalBitmapImpl::setSize(blink::WebSize size) {
if (size != size_) {
- size_t byte_size = size.width * size.height * 4;
- shared_memory_ = g_memory_allocator(byte_size);
- if (shared_memory_)
- shared_memory_->Map(byte_size);
+ shared_bitmap_ = g_memory_allocator(gfx::Size(size));
size_ = size;
}
}
@@ -40,7 +37,7 @@
}
uint8* WebExternalBitmapImpl::pixels() {
- return static_cast<uint8*>(shared_memory_->memory());
+ return shared_bitmap_->pixels();
}
} // namespace cc_blink
diff --git a/cc/blink/web_external_bitmap_impl.h b/cc/blink/web_external_bitmap_impl.h
index 2d2d8ce..6cada7d 100644
--- a/cc/blink/web_external_bitmap_impl.h
+++ b/cc/blink/web_external_bitmap_impl.h
@@ -10,17 +10,18 @@
#include "cc/blink/cc_blink_export.h"
#include "third_party/WebKit/public/platform/WebExternalBitmap.h"
-namespace base {
-class SharedMemory;
+namespace cc {
+class SharedBitmap;
}
namespace cc_blink {
-typedef scoped_ptr<base::SharedMemory>(*SharedMemoryAllocationFunction)(size_t);
+typedef scoped_ptr<cc::SharedBitmap>(*SharedBitmapAllocationFunction)(
+ const gfx::Size& size);
// Sets the function that this will use to allocate shared memory.
-CC_BLINK_EXPORT void SetSharedMemoryAllocationFunction(
- SharedMemoryAllocationFunction);
+CC_BLINK_EXPORT void SetSharedBitmapAllocationFunction(
+ SharedBitmapAllocationFunction);
class WebExternalBitmapImpl : public blink::WebExternalBitmap {
public:
@@ -32,10 +33,10 @@
void setSize(blink::WebSize size) override;
uint8* pixels() override;
- base::SharedMemory* shared_memory() { return shared_memory_.get(); }
+ cc::SharedBitmap* shared_bitmap() { return shared_bitmap_.get(); }
private:
- scoped_ptr<base::SharedMemory> shared_memory_;
+ scoped_ptr<cc::SharedBitmap> shared_bitmap_;
blink::WebSize size_;
DISALLOW_COPY_AND_ASSIGN(WebExternalBitmapImpl);
diff --git a/cc/blink/web_external_texture_layer_impl.cc b/cc/blink/web_external_texture_layer_impl.cc
index 30e0ce6..8d29aa1 100644
--- a/cc/blink/web_external_texture_layer_impl.cc
+++ b/cc/blink/web_external_texture_layer_impl.cc
@@ -84,7 +84,7 @@
gpu::Mailbox name;
name.SetName(client_mailbox.name);
if (bitmap) {
- *mailbox = cc::TextureMailbox(bitmap->shared_memory(), bitmap->size());
+ *mailbox = cc::TextureMailbox(bitmap->shared_bitmap(), bitmap->size());
} else {
*mailbox =
cc::TextureMailbox(name, GL_TEXTURE_2D, client_mailbox.syncPoint);
diff --git a/cc/blink/web_image_layer_impl.cc b/cc/blink/web_image_layer_impl.cc
index ee80ca6..afd551a 100644
--- a/cc/blink/web_image_layer_impl.cc
+++ b/cc/blink/web_image_layer_impl.cc
@@ -35,4 +35,11 @@
}
}
+void WebImageLayerImpl::setNearestNeighbor(bool nearest_neighbor) {
+ if (WebLayerImpl::UsingPictureLayer()) {
+ static_cast<cc::PictureImageLayer*>(layer_->layer())
+ ->SetNearestNeighbor(nearest_neighbor);
+ }
+}
+
} // namespace cc_blink
diff --git a/cc/blink/web_image_layer_impl.h b/cc/blink/web_image_layer_impl.h
index e0591aa..48c31ea 100644
--- a/cc/blink/web_image_layer_impl.h
+++ b/cc/blink/web_image_layer_impl.h
@@ -22,6 +22,7 @@
// blink::WebImageLayer implementation.
virtual blink::WebLayer* layer();
virtual void setImageBitmap(const SkBitmap& bitmap);
+ virtual void setNearestNeighbor(bool nearest_neighbor);
private:
scoped_ptr<WebLayerImpl> layer_;
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index c32fcba..cbea932 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -192,6 +192,8 @@
'test/fake_ui_resource_layer_tree_host_impl.h',
'test/fake_video_frame_provider.cc',
'test/fake_video_frame_provider.h',
+ 'test/failure_output_surface.cc',
+ 'test/failure_output_surface.h',
'test/geometry_test_utils.cc',
'test/geometry_test_utils.h',
'test/test_in_process_context_provider.cc',
diff --git a/cc/debug/rasterize_and_record_benchmark_impl.cc b/cc/debug/rasterize_and_record_benchmark_impl.cc
index c00d0b9..03267a8 100644
--- a/cc/debug/rasterize_and_record_benchmark_impl.cc
+++ b/cc/debug/rasterize_and_record_benchmark_impl.cc
@@ -15,6 +15,7 @@
#include "cc/resources/tile_task_worker_pool.h"
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_host_impl.h"
+#include "cc/trees/layer_tree_impl.h"
#include "ui/gfx/geometry/rect.h"
namespace cc {
@@ -121,18 +122,6 @@
return base_client_->GetMaxTilePriorityBin();
}
- size_t GetMaxTilesForInterestArea() const override {
- return base_client_->GetMaxTilesForInterestArea();
- }
-
- float GetSkewportTargetTimeInSeconds() const override {
- return base_client_->GetSkewportTargetTimeInSeconds();
- }
-
- int GetSkewportExtrapolationLimitInContentPixels() const override {
- return base_client_->GetSkewportExtrapolationLimitInContentPixels();
- }
-
WhichTree GetTree() const override { return base_client_->GetTree(); }
bool RequiresHighResToDraw() const override {
@@ -215,7 +204,15 @@
FixedInvalidationPictureLayerTilingClient client(
layer, gfx::Rect(layer->content_bounds()));
- auto tiling_set = PictureLayerTilingSet::Create(&client);
+
+ // In this benchmark, we will create a local tiling set and measure how long
+ // it takes to rasterize content. As such, the actual settings used here don't
+ // really matter.
+ const LayerTreeSettings& settings = layer->layer_tree_impl()->settings();
+ auto tiling_set = PictureLayerTilingSet::Create(
+ &client, settings.max_tiles_for_interest_area,
+ settings.skewport_target_time_in_seconds,
+ settings.skewport_extrapolation_limit_in_content_pixels);
PictureLayerTiling* tiling =
tiling_set->AddTiling(layer->contents_scale_x(), layer->bounds());
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 066d26c..6793d12 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -1268,8 +1268,6 @@
DCHECK(this != page_scale_layer);
DCHECK(scrollbar_clip_layer);
- DCHECK(this != layer_tree_impl()->InnerViewportScrollLayer() ||
- IsContainerForFixedPositionLayers());
gfx::RectF clip_rect(gfx::PointF(),
scrollbar_clip_layer->BoundsForScrolling());
diff --git a/cc/layers/picture_image_layer.cc b/cc/layers/picture_image_layer.cc
index 5d76618..cebc8b7 100644
--- a/cc/layers/picture_image_layer.cc
+++ b/cc/layers/picture_image_layer.cc
@@ -21,7 +21,7 @@
scoped_ptr<LayerImpl> PictureImageLayer::CreateLayerImpl(
LayerTreeImpl* tree_impl) {
- return PictureImageLayerImpl::Create(tree_impl, id());
+ return PictureImageLayerImpl::Create(tree_impl, id(), is_mask());
}
bool PictureImageLayer::HasDrawableContent() const {
diff --git a/cc/layers/picture_image_layer_impl.cc b/cc/layers/picture_image_layer_impl.cc
index a72ab01..cf09654 100644
--- a/cc/layers/picture_image_layer_impl.cc
+++ b/cc/layers/picture_image_layer_impl.cc
@@ -11,8 +11,10 @@
namespace cc {
-PictureImageLayerImpl::PictureImageLayerImpl(LayerTreeImpl* tree_impl, int id)
- : PictureLayerImpl(tree_impl, id) {
+PictureImageLayerImpl::PictureImageLayerImpl(LayerTreeImpl* tree_impl,
+ int id,
+ bool is_mask)
+ : PictureLayerImpl(tree_impl, id, is_mask) {
}
PictureImageLayerImpl::~PictureImageLayerImpl() {
@@ -24,7 +26,7 @@
scoped_ptr<LayerImpl> PictureImageLayerImpl::CreateLayerImpl(
LayerTreeImpl* tree_impl) {
- return PictureImageLayerImpl::Create(tree_impl, id());
+ return PictureImageLayerImpl::Create(tree_impl, id(), is_mask_);
}
void PictureImageLayerImpl::GetDebugBorderProperties(
diff --git a/cc/layers/picture_image_layer_impl.h b/cc/layers/picture_image_layer_impl.h
index 7a363a1..f478951 100644
--- a/cc/layers/picture_image_layer_impl.h
+++ b/cc/layers/picture_image_layer_impl.h
@@ -12,8 +12,9 @@
class CC_EXPORT PictureImageLayerImpl : public PictureLayerImpl {
public:
static scoped_ptr<PictureImageLayerImpl> Create(LayerTreeImpl* tree_impl,
- int id) {
- return make_scoped_ptr(new PictureImageLayerImpl(tree_impl, id));
+ int id,
+ bool is_mask) {
+ return make_scoped_ptr(new PictureImageLayerImpl(tree_impl, id, is_mask));
}
~PictureImageLayerImpl() override;
@@ -22,7 +23,7 @@
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
protected:
- PictureImageLayerImpl(LayerTreeImpl* tree_impl, int id);
+ PictureImageLayerImpl(LayerTreeImpl* tree_impl, int id, bool is_mask);
bool ShouldAdjustRasterScale() const override;
void RecalculateRasterScales() override;
diff --git a/cc/layers/picture_image_layer_impl_unittest.cc b/cc/layers/picture_image_layer_impl_unittest.cc
index 1c766ba..dbdcf6a 100644
--- a/cc/layers/picture_image_layer_impl_unittest.cc
+++ b/cc/layers/picture_image_layer_impl_unittest.cc
@@ -22,8 +22,7 @@
class TestablePictureImageLayerImpl : public PictureImageLayerImpl {
public:
TestablePictureImageLayerImpl(LayerTreeImpl* tree_impl, int id)
- : PictureImageLayerImpl(tree_impl, id) {
- }
+ : PictureImageLayerImpl(tree_impl, id, false) {}
using PictureLayerImpl::UpdateIdealScales;
using PictureLayerImpl::MaximumTilingContentsScale;
using PictureLayerImpl::DoPostCommitInitializationIfNeeded;
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc
index 55241d0..48f3f73 100644
--- a/cc/layers/picture_layer.cc
+++ b/cc/layers/picture_layer.cc
@@ -24,7 +24,8 @@
instrumentation_object_tracker_(id()),
update_source_frame_number_(-1),
can_use_lcd_text_for_update_(true),
- is_mask_(false) {
+ is_mask_(false),
+ nearest_neighbor_(false) {
}
PictureLayer::PictureLayer(ContentLayerClient* client,
@@ -37,12 +38,14 @@
}
scoped_ptr<LayerImpl> PictureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
- return PictureLayerImpl::Create(tree_impl, id());
+ return PictureLayerImpl::Create(tree_impl, id(), is_mask_);
}
void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) {
Layer::PushPropertiesTo(base_layer);
PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
+ // TODO(danakj): Make is_mask_ a constructor parameter for PictureLayer.
+ DCHECK_EQ(layer_impl->is_mask_, is_mask_);
int source_frame_number = layer_tree_host()->source_frame_number();
gfx::Size impl_bounds = layer_impl->bounds();
@@ -63,17 +66,16 @@
recording_source_->SetEmptyBounds();
}
- // Unlike other properties, invalidation must always be set on layer_impl.
- // See PictureLayerImpl::PushPropertiesTo for more details.
- layer_impl->invalidation_.Clear();
- layer_impl->invalidation_.Swap(&recording_invalidation_);
- layer_impl->set_is_mask(is_mask_);
+ layer_impl->SetNearestNeighbor(nearest_neighbor_);
+
scoped_refptr<RasterSource> raster_source =
recording_source_->CreateRasterSource();
raster_source->SetBackgoundColor(SafeOpaqueBackgroundColor());
raster_source->SetRequiresClear(!contents_opaque() &&
!client_->FillsBoundsCompletely());
- layer_impl->UpdateRasterSource(raster_source);
+ layer_impl->UpdateRasterSource(raster_source, &recording_invalidation_,
+ nullptr);
+ DCHECK(recording_invalidation_.IsEmpty());
}
void PictureLayer::SetLayerTreeHost(LayerTreeHost* host) {
@@ -206,6 +208,14 @@
UpdateDrawsContent(HasDrawableContent());
}
+void PictureLayer::SetNearestNeighbor(bool nearest_neighbor) {
+ if (nearest_neighbor_ == nearest_neighbor)
+ return;
+
+ nearest_neighbor_ = nearest_neighbor;
+ SetNeedsCommit();
+}
+
bool PictureLayer::HasDrawableContent() const {
return client_ && Layer::HasDrawableContent();
}
diff --git a/cc/layers/picture_layer.h b/cc/layers/picture_layer.h
index 01a37a3..648d1c9 100644
--- a/cc/layers/picture_layer.h
+++ b/cc/layers/picture_layer.h
@@ -23,6 +23,8 @@
void ClearClient();
+ void SetNearestNeighbor(bool nearest_neighbor);
+
// Layer interface.
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
void SetLayerTreeHost(LayerTreeHost* host) override;
@@ -50,9 +52,12 @@
~PictureLayer() override;
bool HasDrawableContent() const override;
- bool UpdateCanUseLCDText();
+
+ bool is_mask() const { return is_mask_; }
private:
+ bool UpdateCanUseLCDText();
+
ContentLayerClient* client_;
scoped_ptr<RecordingSource> recording_source_;
devtools_instrumentation::
@@ -66,6 +71,7 @@
int update_source_frame_number_;
bool can_use_lcd_text_for_update_;
bool is_mask_;
+ bool nearest_neighbor_;
DISALLOW_COPY_AND_ASSIGN(PictureLayer);
};
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 54cfac8..392450a 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -63,9 +63,13 @@
PictureLayerImpl::Pair::~Pair() {
}
-PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
+PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl,
+ int id,
+ bool is_mask)
: LayerImpl(tree_impl, id),
twin_layer_(nullptr),
+ tilings_(CreatePictureLayerTilingSet()),
+ // TODO(danakj): Can this be null to start?
raster_source_(PicturePileImpl::Create()),
ideal_page_scale_(0.f),
ideal_device_scale_(0.f),
@@ -81,7 +85,8 @@
needs_post_commit_initialization_(true),
should_update_tile_priorities_(false),
only_used_low_res_last_append_quads_(false),
- is_mask_(false) {
+ is_mask_(is_mask),
+ nearest_neighbor_(false) {
layer_tree_impl()->RegisterPictureLayerImpl(this);
}
@@ -95,8 +100,10 @@
TreePriority tree_priority) {
if (!tilings_)
return make_scoped_ptr(new TilingSetEvictionQueue());
- return make_scoped_ptr(
- new TilingSetEvictionQueue(tilings_.get(), tree_priority));
+ bool skip_shared_out_of_order_tiles =
+ GetPendingOrActiveTwinLayer() != nullptr;
+ return make_scoped_ptr(new TilingSetEvictionQueue(
+ tilings_.get(), tree_priority, skip_shared_out_of_order_tiles));
}
scoped_ptr<TilingSetRasterQueue> PictureLayerImpl::CreateRasterQueue(
@@ -113,7 +120,7 @@
scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl(
LayerTreeImpl* tree_impl) {
- return PictureLayerImpl::Create(tree_impl, id());
+ return PictureLayerImpl::Create(tree_impl, id(), is_mask_);
}
void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
@@ -121,6 +128,7 @@
// a descendant of an opacity 0 layer).
DoPostCommitInitializationIfNeeded();
PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
+ DCHECK_EQ(layer_impl->is_mask_, is_mask_);
LayerImpl::PushPropertiesTo(base_layer);
@@ -134,54 +142,39 @@
twin_layer_ = layer_impl;
layer_impl->twin_layer_ = this;
- layer_impl->set_is_mask(is_mask_);
- layer_impl->UpdateRasterSource(raster_source_);
+ layer_impl->SetNearestNeighbor(nearest_neighbor_);
+ // Solid color layers have no tilings.
DCHECK_IMPLIES(raster_source_->IsSolidColor(), tilings_->num_tilings() == 0);
- // Tilings would be expensive to push, so we swap.
- layer_impl->tilings_.swap(tilings_);
- layer_impl->tilings_->SetClient(layer_impl);
- if (tilings_)
- tilings_->SetClient(this);
+ // The pending tree should only have a high res (and possibly low res) tiling.
+ DCHECK_LE(tilings_->num_tilings(),
+ layer_tree_impl()->create_low_res_tiling() ? 2u : 1u);
- // Ensure that the recycle tree doesn't have any unshared tiles.
- if (tilings_ && raster_source_->IsSolidColor())
- tilings_->RemoveAllTilings();
+ layer_impl->UpdateRasterSource(raster_source_, &invalidation_,
+ tilings_.get());
+ DCHECK(invalidation_.IsEmpty());
- // Remove invalidated tiles from what will become a recycle tree.
- if (tilings_)
- tilings_->RemoveTilesInRegion(invalidation_);
+ // After syncing a solid color layer, the active layer has no tilings.
+ DCHECK_IMPLIES(raster_source_->IsSolidColor(),
+ layer_impl->tilings_->num_tilings() == 0);
layer_impl->raster_page_scale_ = raster_page_scale_;
layer_impl->raster_device_scale_ = raster_device_scale_;
layer_impl->raster_source_scale_ = raster_source_scale_;
layer_impl->raster_contents_scale_ = raster_contents_scale_;
layer_impl->low_res_raster_contents_scale_ = low_res_raster_contents_scale_;
- layer_impl->needs_post_commit_initialization_ = false;
- // The invalidation on this soon-to-be-recycled layer must be cleared to
- // mirror clearing the invalidation in PictureLayer's version of this function
- // in case push properties is skipped.
- layer_impl->invalidation_.Swap(&invalidation_);
- invalidation_.Clear();
+ layer_impl->SanityCheckTilingState();
+
+ layer_impl->needs_post_commit_initialization_ = false;
needs_post_commit_initialization_ = true;
// We always need to push properties.
// See http://crbug.com/303943
+ // TODO(danakj): Stop always pushing properties since we don't swap tilings.
needs_push_properties_ = true;
}
-void PictureLayerImpl::UpdateRasterSource(
- scoped_refptr<RasterSource> raster_source) {
- bool could_have_tilings = CanHaveTilings();
- raster_source_.swap(raster_source);
-
- // Need to call UpdateTiles again if CanHaveTilings changed.
- if (could_have_tilings != CanHaveTilings()) {
- layer_tree_impl()->set_needs_update_draw_properties();
- }
-}
-
void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
const Occlusion& occlusion_in_content_space,
AppendQuadsData* append_quads_data) {
@@ -251,8 +244,9 @@
PictureDrawQuad* quad =
render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
quad->SetNew(shared_quad_state, geometry_rect, opaque_rect,
- visible_geometry_rect, texture_rect, texture_size, RGBA_8888,
- quad_content_rect, max_contents_scale, raster_source_);
+ visible_geometry_rect, texture_rect, texture_size,
+ nearest_neighbor_, RGBA_8888, quad_content_rect,
+ max_contents_scale, raster_source_);
return;
}
@@ -364,7 +358,8 @@
draw_info.get_resource_id(),
texture_rect,
iter.texture_size(),
- draw_info.contents_swizzled());
+ draw_info.contents_swizzled(),
+ nearest_neighbor_);
has_draw_quad = true;
break;
}
@@ -386,8 +381,8 @@
render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
quad->SetNew(shared_quad_state, geometry_rect, opaque_rect,
visible_geometry_rect, texture_rect, iter.texture_size(),
- format, iter->content_rect(), iter->contents_scale(),
- raster_source_);
+ nearest_neighbor_, format, iter->content_rect(),
+ iter->contents_scale(), raster_source_);
has_draw_quad = true;
break;
}
@@ -485,8 +480,6 @@
UpdateIdealScales();
- DCHECK_IMPLIES(tilings_->num_tilings() == 0, raster_contents_scale_ == 0.f)
- << "A layer with no tilings shouldn't have valid raster scales";
if (!raster_contents_scale_ || ShouldAdjustRasterScale()) {
RecalculateRasterScales();
AddTilingsForRasterScale();
@@ -581,6 +574,44 @@
return twin_layer_;
}
+void PictureLayerImpl::UpdateRasterSource(
+ scoped_refptr<RasterSource> raster_source,
+ Region* new_invalidation,
+ const PictureLayerTilingSet* pending_set) {
+ // The bounds and the pile size may differ if the pile wasn't updated (ie.
+ // PictureLayer::Update didn't happen). In that case the pile will be empty.
+ DCHECK_IMPLIES(!raster_source->GetSize().IsEmpty(),
+ bounds() == raster_source->GetSize())
+ << " bounds " << bounds().ToString() << " pile "
+ << raster_source->GetSize().ToString();
+
+ bool could_have_tilings = CanHaveTilings();
+ raster_source_.swap(raster_source);
+
+ // The |new_invalidation| must be cleared before updating tilings since they
+ // access the invalidation through the PictureLayerTilingClient interface.
+ invalidation_.Clear();
+ invalidation_.Swap(new_invalidation);
+
+ bool can_have_tilings = CanHaveTilings();
+
+ // Need to call UpdateTiles again if CanHaveTilings changed.
+ if (could_have_tilings != can_have_tilings)
+ layer_tree_impl()->set_needs_update_draw_properties();
+
+ if (!can_have_tilings) {
+ RemoveAllTilings();
+ return;
+ }
+
+ // We could do this after doing UpdateTiles, which would avoid doing this for
+ // tilings that are going to disappear on the pending tree (if scale changed).
+ // But that would also be more complicated, so we just do it here for now.
+ tilings_->UpdateTilingsToCurrentRasterSource(
+ raster_source_.get(), pending_set, raster_source_->GetSize(),
+ invalidation_, MinimumContentsScale());
+}
+
void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) {
if (layer_tree_impl()->IsActiveTree()) {
gfx::RectF layer_damage_rect =
@@ -600,9 +631,10 @@
}
void PictureLayerImpl::ReleaseResources() {
+ // Recreate tilings with new settings, since some of those might change when
+ // we release resources. If tilings_ is null, then leave it as null.
if (tilings_)
- RemoveAllTilings();
-
+ tilings_ = CreatePictureLayerTilingSet();
ResetRasterScale();
// To avoid an edge case after lost context where the tree is up to date but
@@ -637,6 +669,8 @@
const Region* PictureLayerImpl::GetPendingInvalidation() {
if (layer_tree_impl()->IsPendingTree())
return &invalidation_;
+ if (layer_tree_impl()->IsRecycleTree())
+ return nullptr;
DCHECK(layer_tree_impl()->IsActiveTree());
if (PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer())
return &twin_layer->invalidation_;
@@ -648,9 +682,6 @@
PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer();
if (!twin_layer)
return nullptr;
- // TODO(danakj): Remove this when no longer swapping tilings.
- if (!twin_layer->tilings_)
- return nullptr;
return twin_layer->tilings_->FindTilingWithScale(tiling->contents_scale());
}
@@ -668,22 +699,6 @@
return TilePriority::NOW;
}
-size_t PictureLayerImpl::GetMaxTilesForInterestArea() const {
- return layer_tree_impl()->settings().max_tiles_for_interest_area;
-}
-
-float PictureLayerImpl::GetSkewportTargetTimeInSeconds() const {
- return layer_tree_impl()->use_gpu_rasterization()
- ? 0.f
- : layer_tree_impl()->settings().skewport_target_time_in_seconds;
-}
-
-int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const {
- return layer_tree_impl()
- ->settings()
- .skewport_extrapolation_limit_in_content_pixels;
-}
-
bool PictureLayerImpl::RequiresHighResToDraw() const {
return layer_tree_impl()->RequiresHighResToDraw();
}
@@ -765,69 +780,15 @@
return gfx::Size(tile_width, tile_height);
}
-void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
- DCHECK(!other->needs_post_commit_initialization_);
- DCHECK(other->tilings_);
-
- if (!DrawsContent()) {
- RemoveAllTilings();
- return;
- }
-
- raster_page_scale_ = other->raster_page_scale_;
- raster_device_scale_ = other->raster_device_scale_;
- raster_source_scale_ = other->raster_source_scale_;
- raster_contents_scale_ = other->raster_contents_scale_;
- low_res_raster_contents_scale_ = other->low_res_raster_contents_scale_;
-
- bool synced_high_res_tiling = false;
- if (CanHaveTilings()) {
- synced_high_res_tiling = tilings_->SyncTilings(
- *other->tilings_, raster_source_->GetSize(), invalidation_,
- MinimumContentsScale(), raster_source_.get());
- } else {
- RemoveAllTilings();
- }
-
- // If our MinimumContentsScale has changed to prevent the twin's high res
- // tiling from being synced, we should reset the raster scale and let it be
- // recalculated (1) again. This can happen if our bounds shrink to the point
- // where min contents scale grows.
- // (1) - TODO(vmpstr) Instead of hoping that this will be recalculated, we
- // should refactor this code a little bit and actually recalculate this.
- // However, this is a larger undertaking, so this will work for now.
- if (!synced_high_res_tiling)
- ResetRasterScale();
- else
- SanityCheckTilingState();
-}
-
-void PictureLayerImpl::SyncTiling(
- const PictureLayerTiling* tiling) {
- if (!tilings_)
- return;
- if (!CanHaveTilingWithScale(tiling->contents_scale()))
- return;
- tilings_->AddTiling(tiling->contents_scale(), raster_source_->GetSize());
-
- // If this tree needs update draw properties, then the tiling will
- // get updated prior to drawing or activation. If this tree does not
- // need update draw properties, then its transforms are up to date and
- // we can create tiles for this tiling immediately.
- if (!layer_tree_impl()->needs_update_draw_properties() &&
- should_update_tile_priorities_) {
- // TODO(danakj): Add a DCHECK() that we are not using occlusion tracking
- // when we stop using the pending tree in the browser compositor. If we want
- // to support occlusion tracking here, we need to dirty the draw properties
- // or save occlusion as a draw property.
- UpdateTilePriorities(Occlusion());
- }
-}
-
void PictureLayerImpl::GetContentsResourceId(
ResourceProvider::ResourceId* resource_id,
gfx::Size* resource_size) const {
- DCHECK_EQ(bounds().ToString(), raster_source_->GetSize().ToString());
+ // The bounds and the pile size may differ if the pile wasn't updated (ie.
+ // PictureLayer::Update didn't happen). In that case the pile will be empty.
+ DCHECK_IMPLIES(!raster_source_->GetSize().IsEmpty(),
+ bounds() == raster_source_->GetSize())
+ << " bounds " << bounds().ToString() << " pile "
+ << raster_source_->GetSize().ToString();
gfx::Rect content_rect(bounds());
PictureLayerTilingSet::CoverageIterator iter(
tilings_.get(), 1.f, content_rect, ideal_contents_scale_);
@@ -854,21 +815,18 @@
*resource_size = iter.texture_size();
}
+void PictureLayerImpl::SetNearestNeighbor(bool nearest_neighbor) {
+ if (nearest_neighbor_ == nearest_neighbor)
+ return;
+
+ nearest_neighbor_ = nearest_neighbor;
+ NoteLayerPropertyChanged();
+}
+
void PictureLayerImpl::DoPostCommitInitialization() {
+ // TODO(danakj): Remove this.
DCHECK(needs_post_commit_initialization_);
DCHECK(layer_tree_impl()->IsPendingTree());
-
- if (!tilings_)
- tilings_ = PictureLayerTilingSet::Create(this);
-
- PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer();
- if (twin_layer) {
- // If the twin has never been pushed to, do not sync from it.
- // This can happen if this function is called during activation.
- if (!twin_layer->needs_post_commit_initialization_)
- SyncFromActiveLayer(twin_layer);
- }
-
needs_post_commit_initialization_ = false;
}
@@ -881,9 +839,6 @@
DCHECK(raster_source_->HasRecordings());
- if (PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer())
- twin_layer->SyncTiling(tiling);
-
return tiling;
}
@@ -929,6 +884,12 @@
// Make sure we always have one high-res (even if high == low).
high_res->set_resolution(HIGH_RESOLUTION);
+ if (layer_tree_impl()->IsPendingTree()) {
+ // On the pending tree, drop any tilings that are non-ideal since we don't
+ // need them to activate anyway.
+ tilings_->RemoveNonIdealTilings();
+ }
+
SanityCheckTilingState();
}
@@ -1113,9 +1074,6 @@
layer_tree_impl()->create_low_res_tiling(), twin_set,
recycled_twin_set);
- if (twin_set && twin_set->num_tilings() == 0)
- twin->ResetRasterScale();
-
if (recycled_twin_set && recycled_twin_set->num_tilings() == 0)
recycled_twin->ResetRasterScale();
@@ -1158,6 +1116,8 @@
return false;
if (!raster_source_->HasRecordings())
return false;
+ // If the |raster_source_| has a recording it should have non-empty bounds.
+ DCHECK(!raster_source_->GetSize().IsEmpty());
return true;
}
@@ -1196,6 +1156,17 @@
return std::max(max_contents_scale, MinimumContentsScale());
}
+scoped_ptr<PictureLayerTilingSet>
+PictureLayerImpl::CreatePictureLayerTilingSet() {
+ const LayerTreeSettings& settings = layer_tree_impl()->settings();
+ return PictureLayerTilingSet::Create(
+ this, settings.max_tiles_for_interest_area,
+ layer_tree_impl()->use_gpu_rasterization()
+ ? 0.f
+ : settings.skewport_target_time_in_seconds,
+ settings.skewport_extrapolation_limit_in_content_pixels);
+}
+
void PictureLayerImpl::UpdateIdealScales() {
DCHECK(CanHaveTilings());
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h
index ddf928b..f17743d 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -39,8 +39,10 @@
PictureLayerImpl* pending;
};
- static scoped_ptr<PictureLayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
- return make_scoped_ptr(new PictureLayerImpl(tree_impl, id));
+ static scoped_ptr<PictureLayerImpl> Create(LayerTreeImpl* tree_impl,
+ int id,
+ bool is_mask) {
+ return make_scoped_ptr(new PictureLayerImpl(tree_impl, id, is_mask));
}
~PictureLayerImpl() override;
@@ -73,9 +75,6 @@
PictureLayerTiling* GetRecycledTwinTiling(
const PictureLayerTiling* tiling) override;
TilePriority::PriorityBin GetMaxTilePriorityBin() const override;
- size_t GetMaxTilesForInterestArea() const override;
- float GetSkewportTargetTimeInSeconds() const override;
- int GetSkewportExtrapolationLimitInContentPixels() const override;
WhichTree GetTree() const override;
bool RequiresHighResToDraw() const override;
@@ -85,7 +84,8 @@
// Mask-related functions.
void GetContentsResourceId(ResourceProvider::ResourceId* resource_id,
gfx::Size* resource_size) const override;
- void set_is_mask(bool is_mask) { is_mask_ = is_mask; }
+
+ void SetNearestNeighbor(bool nearest_neighbor);
size_t GPUMemoryUsageInBytes() const override;
@@ -108,10 +108,9 @@
friend class LayerRasterTileIterator;
using TileRequirementCheck = bool (PictureLayerTiling::*)(const Tile*) const;
- PictureLayerImpl(LayerTreeImpl* tree_impl, int id);
+ PictureLayerImpl(LayerTreeImpl* tree_impl, int id, bool is_mask);
PictureLayerTiling* AddTiling(float contents_scale);
void RemoveAllTilings();
- void SyncFromActiveLayer(const PictureLayerImpl* other);
void AddTilingsForRasterScale();
void UpdateTilePriorities(const Occlusion& occlusion_in_content_space);
virtual bool ShouldAdjustRasterScale() const;
@@ -122,7 +121,9 @@
void ResetRasterScale();
gfx::Rect GetViewportForTilePriorityInContentSpace() const;
PictureLayerImpl* GetRecycledTwinLayer() const;
- void UpdateRasterSource(scoped_refptr<RasterSource> raster_source);
+ void UpdateRasterSource(scoped_refptr<RasterSource> raster_source,
+ Region* new_invalidation,
+ const PictureLayerTilingSet* pending_set);
void DoPostCommitInitializationIfNeeded() {
if (needs_post_commit_initialization_)
@@ -146,6 +147,7 @@
virtual void UpdateIdealScales();
float MaximumTilingContentsScale() const;
+ scoped_ptr<PictureLayerTilingSet> CreatePictureLayerTilingSet();
PictureLayerImpl* twin_layer_;
@@ -171,7 +173,9 @@
// after a CalculateContentsScale/ManageTilings.
bool should_update_tile_priorities_;
bool only_used_low_res_last_append_quads_;
- bool is_mask_;
+ const bool is_mask_;
+
+ bool nearest_neighbor_;
// Any draw properties derived from |transform|, |viewport|, and |clip|
// parameters in LayerTreeHostImpl::SetExternalDrawConstraints are not valid
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 90a36f7..7c7c899 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -34,6 +34,18 @@
namespace cc {
namespace {
+#define EXPECT_BOTH_EQ(expression, x) \
+ do { \
+ EXPECT_EQ(x, pending_layer_->expression); \
+ EXPECT_EQ(x, active_layer_->expression); \
+ } while (false)
+
+#define EXPECT_BOTH_NE(expression, x) \
+ do { \
+ EXPECT_NE(x, pending_layer_->expression); \
+ EXPECT_NE(x, active_layer_->expression); \
+ } while (false)
+
class MockCanvas : public SkCanvas {
public:
explicit MockCanvas(int w, int h) : SkCanvas(w, h) {}
@@ -58,15 +70,21 @@
PictureLayerImplTest()
: proxy_(base::MessageLoopProxy::current()),
host_impl_(LowResTilingsSettings(), &proxy_, &shared_bitmap_manager_),
+ root_id_(6),
id_(7),
pending_layer_(nullptr),
old_pending_layer_(nullptr),
- active_layer_(nullptr) {}
+ active_layer_(nullptr) {
+ host_impl_.SetViewportSize(gfx::Size(10000, 10000));
+ }
explicit PictureLayerImplTest(const LayerTreeSettings& settings)
: proxy_(base::MessageLoopProxy::current()),
host_impl_(settings, &proxy_, &shared_bitmap_manager_),
- id_(7) {}
+ root_id_(6),
+ id_(7) {
+ host_impl_.SetViewportSize(gfx::Size(10000, 10000));
+ }
virtual ~PictureLayerImplTest() {
}
@@ -88,6 +106,18 @@
SetupTrees(pending_pile, active_pile);
}
+ void SetupDefaultTreesWithInvalidation(const gfx::Size& layer_bounds,
+ const Region& invalidation) {
+ gfx::Size tile_size(100, 100);
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+ SetupTreesWithInvalidation(pending_pile, active_pile, invalidation);
+ }
+
void ActivateTree() {
host_impl_.ActivateSyncTree();
CHECK(!host_impl_.pending_tree());
@@ -96,13 +126,22 @@
pending_layer_ = nullptr;
active_layer_ = static_cast<FakePictureLayerImpl*>(
host_impl_.active_tree()->LayerById(id_));
+
+ host_impl_.active_tree()->UpdateDrawProperties();
}
void SetupDefaultTreesWithFixedTileSize(const gfx::Size& layer_bounds,
- const gfx::Size& tile_size) {
- SetupDefaultTrees(layer_bounds);
- pending_layer_->set_fixed_tile_size(tile_size);
- active_layer_->set_fixed_tile_size(tile_size);
+ const gfx::Size& tile_size,
+ const Region& invalidation) {
+ gfx::Size pile_tile_size(100, 100);
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(pile_tile_size, layer_bounds);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(pile_tile_size, layer_bounds);
+
+ SetupTreesWithFixedTileSize(pending_pile, active_pile, tile_size,
+ invalidation);
}
void SetupTrees(
@@ -110,54 +149,80 @@
scoped_refptr<PicturePileImpl> active_pile) {
SetupPendingTree(active_pile);
ActivateTree();
- SetupPendingTree(pending_pile);
+ SetupPendingTreeInternal(pending_pile, gfx::Size(), Region());
}
- void CreateHighLowResAndSetAllTilesVisible() {
- // Active layer must get updated first so pending layer can share from it.
- active_layer_->CreateDefaultTilingsAndTiles();
- active_layer_->SetAllTilesVisible();
- pending_layer_->CreateDefaultTilingsAndTiles();
- pending_layer_->SetAllTilesVisible();
+ void SetupTreesWithInvalidation(scoped_refptr<PicturePileImpl> pending_pile,
+ scoped_refptr<PicturePileImpl> active_pile,
+ const Region& pending_invalidation) {
+ SetupPendingTreeInternal(active_pile, gfx::Size(), Region());
+ ActivateTree();
+ SetupPendingTreeInternal(pending_pile, gfx::Size(), pending_invalidation);
}
- void AddDefaultTilingsWithInvalidation(const Region& invalidation) {
- active_layer_->AddTiling(2.3f);
- active_layer_->AddTiling(1.0f);
- active_layer_->AddTiling(0.5f);
- for (size_t i = 0; i < active_layer_->tilings()->num_tilings(); ++i)
- active_layer_->tilings()->tiling_at(i)->CreateAllTilesForTesting();
- pending_layer_->set_invalidation(invalidation);
- for (size_t i = 0; i < pending_layer_->tilings()->num_tilings(); ++i)
- pending_layer_->tilings()->tiling_at(i)->CreateAllTilesForTesting();
+ void SetupTreesWithFixedTileSize(scoped_refptr<PicturePileImpl> pending_pile,
+ scoped_refptr<PicturePileImpl> active_pile,
+ const gfx::Size& tile_size,
+ const Region& pending_invalidation) {
+ SetupPendingTreeInternal(active_pile, tile_size, Region());
+ ActivateTree();
+ SetupPendingTreeInternal(pending_pile, tile_size, pending_invalidation);
}
void SetupPendingTree(scoped_refptr<RasterSource> raster_source) {
+ SetupPendingTreeInternal(raster_source, gfx::Size(), Region());
+ }
+
+ void SetupPendingTreeWithInvalidation(
+ scoped_refptr<RasterSource> raster_source,
+ const Region& invalidation) {
+ SetupPendingTreeInternal(raster_source, gfx::Size(), invalidation);
+ }
+
+ void SetupPendingTreeWithFixedTileSize(
+ scoped_refptr<RasterSource> raster_source,
+ const gfx::Size& tile_size,
+ const Region& invalidation) {
+ SetupPendingTreeInternal(raster_source, tile_size, invalidation);
+ }
+
+ void SetupPendingTreeInternal(scoped_refptr<RasterSource> raster_source,
+ const gfx::Size& tile_size,
+ const Region& invalidation) {
host_impl_.CreatePendingTree();
host_impl_.pending_tree()->PushPageScaleFromMainThread(1.f, 0.25f, 100.f);
LayerTreeImpl* pending_tree = host_impl_.pending_tree();
- // Steal from the recycled tree.
- scoped_ptr<LayerImpl> old_pending_root = pending_tree->DetachLayerTree();
- DCHECK_IMPLIES(old_pending_root, old_pending_root->id() == id_);
-
+ // Steal from the recycled tree if possible.
+ scoped_ptr<LayerImpl> pending_root = pending_tree->DetachLayerTree();
scoped_ptr<FakePictureLayerImpl> pending_layer;
- if (old_pending_root) {
- pending_layer.reset(
- static_cast<FakePictureLayerImpl*>(old_pending_root.release()));
- pending_layer->SetRasterSource(raster_source);
- } else {
- pending_layer = FakePictureLayerImpl::CreateWithRasterSource(
- pending_tree, id_, raster_source);
+ DCHECK_IMPLIES(pending_root, pending_root->id() == root_id_);
+ if (!pending_root) {
+ pending_root = LayerImpl::Create(pending_tree, root_id_);
+ pending_layer = FakePictureLayerImpl::Create(pending_tree, id_);
+ if (!tile_size.IsEmpty())
+ pending_layer->set_fixed_tile_size(tile_size);
pending_layer->SetDrawsContent(true);
+ } else {
+ pending_layer.reset(static_cast<FakePictureLayerImpl*>(
+ pending_root->RemoveChild(pending_root->children()[0]).release()));
+ if (!tile_size.IsEmpty())
+ pending_layer->set_fixed_tile_size(tile_size);
}
// The bounds() just mirror the pile size.
- pending_layer->SetBounds(pending_layer->raster_source()->GetSize());
- pending_tree->SetRootLayer(pending_layer.Pass());
+ pending_layer->SetBounds(raster_source->GetSize());
+ pending_layer->SetContentBounds(raster_source->GetSize());
+ pending_layer->SetRasterSourceOnPending(raster_source, invalidation);
+
+ pending_root->AddChild(pending_layer.Pass());
+ pending_tree->SetRootLayer(pending_root.Pass());
pending_layer_ = static_cast<FakePictureLayerImpl*>(
host_impl_.pending_tree()->LayerById(id_));
pending_layer_->DoPostCommitInitializationIfNeeded();
+
+ // Add tilings/tiles for the layer.
+ host_impl_.pending_tree()->UpdateDrawProperties();
}
void SetupDrawPropertiesAndUpdateTiles(FakePictureLayerImpl* layer,
@@ -213,6 +278,10 @@
void ResetTilingsAndRasterScales() {
pending_layer_->ReleaseResources();
active_layer_->ReleaseResources();
+ if (pending_layer_)
+ EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings());
+ if (active_layer_)
+ EXPECT_EQ(0u, active_layer_->tilings()->num_tilings());
}
void AssertAllTilesRequired(PictureLayerTiling* tiling) {
@@ -230,60 +299,12 @@
}
protected:
- void TestTileGridAlignmentCommon() {
- // Layer to span 4 raster tiles in x and in y
- ImplSidePaintingSettings settings;
- gfx::Size layer_size(
- settings.default_tile_size.width() * 7 / 2,
- settings.default_tile_size.height() * 7 / 2);
-
- scoped_refptr<FakePicturePileImpl> pending_pile =
- FakePicturePileImpl::CreateFilledPile(layer_size, layer_size);
- scoped_refptr<FakePicturePileImpl> active_pile =
- FakePicturePileImpl::CreateFilledPile(layer_size, layer_size);
-
- SetupTrees(pending_pile, active_pile);
-
- SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, false);
-
- // Add 1x1 rects at the centers of each tile, then re-record pile contents
- active_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting();
- std::vector<Tile*> tiles =
- active_layer_->tilings()->tiling_at(0)->AllTilesForTesting();
- EXPECT_EQ(16u, tiles.size());
- std::vector<SkRect> rects;
- std::vector<Tile*>::const_iterator tile_iter;
- for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) {
- gfx::Point tile_center = (*tile_iter)->content_rect().CenterPoint();
- gfx::Rect rect(tile_center.x(), tile_center.y(), 1, 1);
- active_pile->add_draw_rect(rect);
- rects.push_back(SkRect::MakeXYWH(rect.x(), rect.y(), 1, 1));
- }
- // Force re-record with newly injected content
- active_pile->RemoveRecordingAt(0, 0);
- active_pile->AddRecordingAt(0, 0);
-
- std::vector<SkRect>::const_iterator rect_iter = rects.begin();
- for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) {
- MockCanvas mock_canvas(1000, 1000);
- active_pile->PlaybackToSharedCanvas(&mock_canvas,
- (*tile_iter)->content_rect(), 1.0f);
-
- // This test verifies that when drawing the contents of a specific tile
- // at content scale 1.0, the playback canvas never receives content from
- // neighboring tiles which indicates that the tile grid embedded in
- // SkPicture is perfectly aligned with the compositor's tiles.
- EXPECT_EQ(1u, mock_canvas.rects_.size());
- EXPECT_EQ(*rect_iter, mock_canvas.rects_[0]);
- rect_iter++;
- }
- }
-
void TestQuadsForSolidColor(bool test_for_solid);
FakeImplProxy proxy_;
TestSharedBitmapManager shared_bitmap_manager_;
FakeLayerTreeHostImpl host_impl_;
+ int root_id_;
int id_;
FakePictureLayerImpl* pending_layer_;
FakePictureLayerImpl* old_pending_layer_;
@@ -293,14 +314,56 @@
DISALLOW_COPY_AND_ASSIGN(PictureLayerImplTest);
};
-TEST_F(PictureLayerImplTest, TileGridAlignment) {
- host_impl_.SetDeviceScaleFactor(1.f);
- TestTileGridAlignmentCommon();
-}
+class NoLowResPictureLayerImplTest : public PictureLayerImplTest {
+ public:
+ NoLowResPictureLayerImplTest()
+ : PictureLayerImplTest(NoLowResTilingsSettings()) {}
+};
-TEST_F(PictureLayerImplTest, TileGridAlignmentHiDPI) {
- host_impl_.SetDeviceScaleFactor(2.f);
- TestTileGridAlignmentCommon();
+TEST_F(PictureLayerImplTest, TileGridAlignment) {
+ // Layer to span 4 raster tiles in x and in y
+ ImplSidePaintingSettings settings;
+ gfx::Size layer_size(settings.default_tile_size.width() * 7 / 2,
+ settings.default_tile_size.height() * 7 / 2);
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(layer_size, layer_size);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(layer_size, layer_size);
+
+ SetupTrees(pending_pile, active_pile);
+
+ // Add 1x1 rects at the centers of each tile, then re-record pile contents
+ active_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting();
+ std::vector<Tile*> tiles =
+ active_layer_->tilings()->tiling_at(0)->AllTilesForTesting();
+ EXPECT_EQ(16u, tiles.size());
+ std::vector<SkRect> rects;
+ std::vector<Tile*>::const_iterator tile_iter;
+ for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) {
+ gfx::Point tile_center = (*tile_iter)->content_rect().CenterPoint();
+ gfx::Rect rect(tile_center.x(), tile_center.y(), 1, 1);
+ active_pile->add_draw_rect(rect);
+ rects.push_back(SkRect::MakeXYWH(rect.x(), rect.y(), 1, 1));
+ }
+ // Force re-raster with newly injected content
+ active_pile->RemoveRecordingAt(0, 0);
+ active_pile->AddRecordingAt(0, 0);
+
+ std::vector<SkRect>::const_iterator rect_iter = rects.begin();
+ for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) {
+ MockCanvas mock_canvas(1000, 1000);
+ active_pile->PlaybackToSharedCanvas(&mock_canvas,
+ (*tile_iter)->content_rect(), 1.0f);
+
+ // This test verifies that when drawing the contents of a specific tile
+ // at content scale 1.0, the playback canvas never receives content from
+ // neighboring tiles which indicates that the tile grid embedded in
+ // SkPicture is perfectly aligned with the compositor's tiles.
+ EXPECT_EQ(1u, mock_canvas.rects_.size());
+ EXPECT_EQ(*rect_iter, mock_canvas.rects_[0]);
+ rect_iter++;
+ }
}
TEST_F(PictureLayerImplTest, CloneNoInvalidation) {
@@ -312,10 +375,7 @@
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
-
- Region invalidation;
- AddDefaultTilingsWithInvalidation(invalidation);
+ SetupTreesWithInvalidation(pending_pile, active_pile, Region());
EXPECT_EQ(pending_layer_->tilings()->num_tilings(),
active_layer_->tilings()->num_tilings());
@@ -323,7 +383,7 @@
const PictureLayerTilingSet* tilings = pending_layer_->tilings();
EXPECT_GT(tilings->num_tilings(), 0u);
for (size_t i = 0; i < tilings->num_tilings(); ++i)
- VerifyAllTilesExistAndHavePile(tilings->tiling_at(i), active_pile.get());
+ VerifyAllTilesExistAndHavePile(tilings->tiling_at(i), pending_pile.get());
}
TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) {
@@ -339,10 +399,8 @@
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
+ SetupTreesWithInvalidation(pending_pile, active_pile, Region());
- Region invalidation;
- AddDefaultTilingsWithInvalidation(invalidation);
SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, false);
time_ticks += base::TimeDelta::FromMilliseconds(200);
@@ -436,10 +494,8 @@
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
+ SetupTreesWithInvalidation(pending_pile, active_pile, Region());
- Region invalidation;
- AddDefaultTilingsWithInvalidation(invalidation);
SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, false);
// UpdateTiles with valid viewport. Should update tile viewport.
@@ -516,11 +572,20 @@
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ scoped_refptr<FakePicturePileImpl> lost_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
+ SetupPendingTreeWithFixedTileSize(lost_pile, gfx::Size(50, 50), Region());
+ ActivateTree();
+ // Add a non-shared tiling on the active tree.
+ PictureLayerTiling* tiling = active_layer_->AddTiling(3.f);
+ tiling->CreateAllTilesForTesting();
+ // Then setup a new pending tree and activate it.
+ SetupTreesWithFixedTileSize(pending_pile, active_pile, gfx::Size(50, 50),
+ layer_invalidation);
- Region invalidation(layer_invalidation);
- AddDefaultTilingsWithInvalidation(invalidation);
+ EXPECT_EQ(2u, pending_layer_->num_tilings());
+ EXPECT_EQ(3u, active_layer_->num_tilings());
const PictureLayerTilingSet* tilings = pending_layer_->tilings();
EXPECT_GT(tilings->num_tilings(), 0u);
@@ -537,10 +602,30 @@
++iter) {
EXPECT_TRUE(*iter);
EXPECT_FALSE(iter.geometry_rect().IsEmpty());
+ EXPECT_EQ(pending_pile.get(), iter->raster_source());
+ }
+ }
+
+ tilings = active_layer_->tilings();
+ EXPECT_GT(tilings->num_tilings(), 0u);
+ for (size_t i = 0; i < tilings->num_tilings(); ++i) {
+ const PictureLayerTiling* tiling = tilings->tiling_at(i);
+ gfx::Rect content_invalidation =
+ gfx::ScaleToEnclosingRect(layer_invalidation, tiling->contents_scale());
+ for (PictureLayerTiling::CoverageIterator iter(
+ tiling,
+ tiling->contents_scale(),
+ gfx::Rect(tiling->tiling_size()));
+ iter;
+ ++iter) {
+ EXPECT_TRUE(*iter);
+ EXPECT_FALSE(iter.geometry_rect().IsEmpty());
if (iter.geometry_rect().Intersects(content_invalidation))
- EXPECT_EQ(pending_pile.get(), iter->raster_source());
- else
EXPECT_EQ(active_pile.get(), iter->raster_source());
+ else if (!active_layer_->GetPendingOrActiveTwinTiling(tiling))
+ EXPECT_EQ(active_pile.get(), iter->raster_source());
+ else
+ EXPECT_EQ(pending_pile.get(), iter->raster_source());
}
}
}
@@ -554,10 +639,8 @@
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
-
- Region invalidation((gfx::Rect(layer_bounds)));
- AddDefaultTilingsWithInvalidation(invalidation);
+ SetupTreesWithInvalidation(pending_pile, active_pile,
+ gfx::Rect(layer_bounds));
EXPECT_EQ(pending_layer_->tilings()->num_tilings(),
active_layer_->tilings()->num_tilings());
@@ -568,125 +651,6 @@
VerifyAllTilesExistAndHavePile(tilings->tiling_at(i), pending_pile.get());
}
-TEST_F(PictureLayerImplTest, NoInvalidationBoundsChange) {
- gfx::Size tile_size(90, 80);
- gfx::Size active_layer_bounds(300, 500);
- gfx::Size pending_layer_bounds(400, 800);
-
- scoped_refptr<FakePicturePileImpl> pending_pile =
- FakePicturePileImpl::CreateFilledPile(tile_size,
- pending_layer_bounds);
- scoped_refptr<FakePicturePileImpl> active_pile =
- FakePicturePileImpl::CreateFilledPile(tile_size, active_layer_bounds);
-
- SetupTrees(pending_pile, active_pile);
- pending_layer_->set_fixed_tile_size(gfx::Size(100, 100));
-
- Region invalidation;
- AddDefaultTilingsWithInvalidation(invalidation);
-
- const PictureLayerTilingSet* tilings = pending_layer_->tilings();
- EXPECT_GT(tilings->num_tilings(), 0u);
- for (size_t i = 0; i < tilings->num_tilings(); ++i) {
- const PictureLayerTiling* tiling = tilings->tiling_at(i);
- gfx::Rect active_content_bounds = gfx::ScaleToEnclosingRect(
- gfx::Rect(active_layer_bounds),
- tiling->contents_scale());
- for (PictureLayerTiling::CoverageIterator iter(
- tiling,
- tiling->contents_scale(),
- gfx::Rect(tiling->tiling_size()));
- iter;
- ++iter) {
- EXPECT_TRUE(*iter);
- EXPECT_FALSE(iter.geometry_rect().IsEmpty());
- std::vector<Tile*> active_tiles =
- active_layer_->tilings()->tiling_at(i)->AllTilesForTesting();
- std::vector<Tile*> pending_tiles = tiling->AllTilesForTesting();
- if (iter.geometry_rect().right() >= active_content_bounds.width() ||
- iter.geometry_rect().bottom() >= active_content_bounds.height() ||
- active_tiles[0]->content_rect().size() !=
- pending_tiles[0]->content_rect().size()) {
- EXPECT_EQ(pending_pile.get(), iter->raster_source());
- } else {
- EXPECT_EQ(active_pile.get(), iter->raster_source());
- }
- }
- }
-}
-
-TEST_F(PictureLayerImplTest, AddTilesFromNewRecording) {
- gfx::Size tile_size(400, 400);
- gfx::Size layer_bounds(1300, 1900);
-
- scoped_refptr<FakePicturePileImpl> pending_pile =
- FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
- scoped_refptr<FakePicturePileImpl> active_pile =
- FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
-
- // Fill in some of active pile, but more of pending pile.
- int hole_count = 0;
- for (int x = 0; x < active_pile->tiling().num_tiles_x(); ++x) {
- for (int y = 0; y < active_pile->tiling().num_tiles_y(); ++y) {
- if ((x + y) % 2) {
- pending_pile->AddRecordingAt(x, y);
- active_pile->AddRecordingAt(x, y);
- } else {
- hole_count++;
- if (hole_count % 2)
- pending_pile->AddRecordingAt(x, y);
- }
- }
- }
-
- SetupTrees(pending_pile, active_pile);
- Region invalidation;
- AddDefaultTilingsWithInvalidation(invalidation);
-
- const PictureLayerTilingSet* tilings = pending_layer_->tilings();
- EXPECT_GT(tilings->num_tilings(), 0u);
- for (size_t i = 0; i < tilings->num_tilings(); ++i) {
- const PictureLayerTiling* tiling = tilings->tiling_at(i);
-
- for (PictureLayerTiling::CoverageIterator iter(
- tiling,
- tiling->contents_scale(),
- gfx::Rect(tiling->tiling_size()));
- iter;
- ++iter) {
- EXPECT_FALSE(iter.full_tile_geometry_rect().IsEmpty());
- // Ensure there is a recording for this tile.
- bool in_pending = pending_pile->CoversRect(iter.full_tile_geometry_rect(),
- tiling->contents_scale());
- bool in_active = active_pile->CoversRect(iter.full_tile_geometry_rect(),
- tiling->contents_scale());
-
- if (in_pending && !in_active)
- EXPECT_EQ(pending_pile.get(), iter->raster_source());
- else if (in_active)
- EXPECT_EQ(active_pile.get(), iter->raster_source());
- else
- EXPECT_FALSE(*iter);
- }
- }
-}
-
-TEST_F(PictureLayerImplTest, ManageTilingsWithNoRecording) {
- gfx::Size tile_size(400, 400);
- gfx::Size layer_bounds(1300, 1900);
-
- scoped_refptr<FakePicturePileImpl> pending_pile =
- FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
- scoped_refptr<FakePicturePileImpl> active_pile =
- FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
-
- SetupTrees(pending_pile, active_pile);
-
- SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
-
- EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings());
-}
-
TEST_F(PictureLayerImplTest, ManageTilingsCreatesTilings) {
gfx::Size tile_size(400, 400);
gfx::Size layer_bounds(1300, 1900);
@@ -697,11 +661,83 @@
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupTrees(pending_pile, active_pile);
- EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings());
float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
EXPECT_LT(low_res_factor, 1.f);
+ active_layer_->ReleaseResources();
+ EXPECT_EQ(0u, active_layer_->tilings()->num_tilings());
+
+ SetupDrawPropertiesAndUpdateTiles(active_layer_,
+ 6.f, // ideal contents scale
+ 3.f, // device scale
+ 2.f, // page scale
+ 1.f, // maximum animation scale
+ false);
+ ASSERT_EQ(2u, active_layer_->tilings()->num_tilings());
+ EXPECT_FLOAT_EQ(6.f,
+ active_layer_->tilings()->tiling_at(0)->contents_scale());
+ EXPECT_FLOAT_EQ(6.f * low_res_factor,
+ active_layer_->tilings()->tiling_at(1)->contents_scale());
+
+ // If we change the page scale factor, then we should get new tilings.
+ SetupDrawPropertiesAndUpdateTiles(active_layer_,
+ 6.6f, // ideal contents scale
+ 3.f, // device scale
+ 2.2f, // page scale
+ 1.f, // maximum animation scale
+ false);
+ ASSERT_EQ(4u, active_layer_->tilings()->num_tilings());
+ EXPECT_FLOAT_EQ(6.6f,
+ active_layer_->tilings()->tiling_at(0)->contents_scale());
+ EXPECT_FLOAT_EQ(6.6f * low_res_factor,
+ active_layer_->tilings()->tiling_at(2)->contents_scale());
+
+ // If we change the device scale factor, then we should get new tilings.
+ SetupDrawPropertiesAndUpdateTiles(active_layer_,
+ 7.26f, // ideal contents scale
+ 3.3f, // device scale
+ 2.2f, // page scale
+ 1.f, // maximum animation scale
+ false);
+ ASSERT_EQ(6u, active_layer_->tilings()->num_tilings());
+ EXPECT_FLOAT_EQ(7.26f,
+ active_layer_->tilings()->tiling_at(0)->contents_scale());
+ EXPECT_FLOAT_EQ(7.26f * low_res_factor,
+ active_layer_->tilings()->tiling_at(3)->contents_scale());
+
+ // If we change the device scale factor, but end up at the same total scale
+ // factor somehow, then we don't get new tilings.
+ SetupDrawPropertiesAndUpdateTiles(active_layer_,
+ 7.26f, // ideal contents scale
+ 2.2f, // device scale
+ 3.3f, // page scale
+ 1.f, // maximum animation scale
+ false);
+ ASSERT_EQ(6u, active_layer_->tilings()->num_tilings());
+ EXPECT_FLOAT_EQ(7.26f,
+ active_layer_->tilings()->tiling_at(0)->contents_scale());
+ EXPECT_FLOAT_EQ(7.26f * low_res_factor,
+ active_layer_->tilings()->tiling_at(3)->contents_scale());
+}
+
+TEST_F(PictureLayerImplTest, PendingLayerOnlyHasHighAndLowResTiling) {
+ gfx::Size tile_size(400, 400);
+ gfx::Size layer_bounds(1300, 1900);
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+ SetupTrees(pending_pile, active_pile);
+
+ float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
+ EXPECT_LT(low_res_factor, 1.f);
+
+ pending_layer_->ReleaseResources();
+ EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings());
+
SetupDrawPropertiesAndUpdateTiles(pending_layer_,
6.f, // ideal contents scale
3.f, // device scale
@@ -721,11 +757,11 @@
2.2f, // page scale
1.f, // maximum animation scale
false);
- ASSERT_EQ(4u, pending_layer_->tilings()->num_tilings());
+ ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings());
EXPECT_FLOAT_EQ(6.6f,
pending_layer_->tilings()->tiling_at(0)->contents_scale());
EXPECT_FLOAT_EQ(6.6f * low_res_factor,
- pending_layer_->tilings()->tiling_at(2)->contents_scale());
+ pending_layer_->tilings()->tiling_at(1)->contents_scale());
// If we change the device scale factor, then we should get new tilings.
SetupDrawPropertiesAndUpdateTiles(pending_layer_,
@@ -734,11 +770,11 @@
2.2f, // page scale
1.f, // maximum animation scale
false);
- ASSERT_EQ(6u, pending_layer_->tilings()->num_tilings());
+ ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings());
EXPECT_FLOAT_EQ(7.26f,
pending_layer_->tilings()->tiling_at(0)->contents_scale());
EXPECT_FLOAT_EQ(7.26f * low_res_factor,
- pending_layer_->tilings()->tiling_at(3)->contents_scale());
+ pending_layer_->tilings()->tiling_at(1)->contents_scale());
// If we change the device scale factor, but end up at the same total scale
// factor somehow, then we don't get new tilings.
@@ -748,11 +784,11 @@
3.3f, // page scale
1.f, // maximum animation scale
false);
- ASSERT_EQ(6u, pending_layer_->tilings()->num_tilings());
+ ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings());
EXPECT_FLOAT_EQ(7.26f,
pending_layer_->tilings()->tiling_at(0)->contents_scale());
EXPECT_FLOAT_EQ(7.26f * low_res_factor,
- pending_layer_->tilings()->tiling_at(3)->contents_scale());
+ pending_layer_->tilings()->tiling_at(1)->contents_scale());
}
TEST_F(PictureLayerImplTest, CreateTilingsEvenIfTwinHasNone) {
@@ -767,63 +803,22 @@
scoped_refptr<FakePicturePileImpl> valid_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
- EXPECT_LT(low_res_factor, 1.f);
-
- float high_res_scale = 1.3f;
- float low_res_scale = high_res_scale * low_res_factor;
- float device_scale = 1.7f;
- float page_scale = 3.2f;
- float maximum_animation_scale = 1.f;
-
SetupPendingTree(valid_pile);
- SetupDrawPropertiesAndUpdateTiles(pending_layer_,
- high_res_scale,
- device_scale,
- page_scale,
- maximum_animation_scale,
- false);
ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings());
- EXPECT_FLOAT_EQ(high_res_scale,
- pending_layer_->HighResTiling()->contents_scale());
- EXPECT_FLOAT_EQ(low_res_scale,
- pending_layer_->LowResTiling()->contents_scale());
ActivateTree();
SetupPendingTree(empty_pile);
EXPECT_FALSE(pending_layer_->CanHaveTilings());
- SetupDrawPropertiesAndUpdateTiles(pending_layer_,
- high_res_scale,
- device_scale,
- page_scale,
- maximum_animation_scale,
- false);
ASSERT_EQ(2u, active_layer_->tilings()->num_tilings());
ASSERT_EQ(0u, pending_layer_->tilings()->num_tilings());
ActivateTree();
EXPECT_FALSE(active_layer_->CanHaveTilings());
- SetupDrawPropertiesAndUpdateTiles(active_layer_,
- high_res_scale,
- device_scale,
- page_scale,
- maximum_animation_scale,
- false);
ASSERT_EQ(0u, active_layer_->tilings()->num_tilings());
SetupPendingTree(valid_pile);
- SetupDrawPropertiesAndUpdateTiles(pending_layer_,
- high_res_scale,
- device_scale,
- page_scale,
- maximum_animation_scale,
- false);
ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings());
ASSERT_EQ(0u, active_layer_->tilings()->num_tilings());
- EXPECT_FLOAT_EQ(high_res_scale,
- pending_layer_->HighResTiling()->contents_scale());
- EXPECT_FLOAT_EQ(low_res_scale,
- pending_layer_->LowResTiling()->contents_scale());
}
TEST_F(PictureLayerImplTest, ZoomOutCrash) {
@@ -837,8 +832,10 @@
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupTrees(pending_pile, active_pile);
+ ResetTilingsAndRasterScales();
EXPECT_EQ(0u, active_layer_->tilings()->num_tilings());
SetContentsScaleOnBothLayers(32.0f, 1.0f, 32.0f, 1.0f, false);
+ EXPECT_EQ(32.f, active_layer_->HighResTiling()->contents_scale());
host_impl_.PinchGestureBegin();
SetContentsScaleOnBothLayers(1.0f, 1.0f, 1.0f, 1.0f, false);
SetContentsScaleOnBothLayers(1.0f, 1.0f, 1.0f, 1.0f, false);
@@ -849,6 +846,8 @@
gfx::Size tile_size(400, 400);
gfx::Size layer_bounds(1300, 1900);
+ float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
+
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
scoped_refptr<FakePicturePileImpl> active_pile =
@@ -856,21 +855,20 @@
// Set up the high and low res tilings before pinch zoom.
SetupTrees(pending_pile, active_pile);
- EXPECT_EQ(0u, active_layer_->tilings()->num_tilings());
- SetContentsScaleOnBothLayers(2.0f, 1.0f, 1.0f, 1.0f, false);
- float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
- EXPECT_EQ(2u, active_layer_->tilings()->num_tilings());
- EXPECT_FLOAT_EQ(2.0f,
- active_layer_->tilings()->tiling_at(0)->contents_scale());
- EXPECT_FLOAT_EQ(2.0f * low_res_factor,
- active_layer_->tilings()->tiling_at(1)->contents_scale());
+ ResetTilingsAndRasterScales();
+
+ SetContentsScaleOnBothLayers(2.f, 1.0f, 2.f, 1.0f, false);
+ EXPECT_BOTH_EQ(num_tilings(), 2u);
+ EXPECT_BOTH_EQ(tilings()->tiling_at(0)->contents_scale(), 2.f);
+ EXPECT_BOTH_EQ(tilings()->tiling_at(1)->contents_scale(),
+ 2.f * low_res_factor);
// Start a pinch gesture.
host_impl_.PinchGestureBegin();
// Zoom out by a small amount. We should create a tiling at half
// the scale (2/kMaxScaleRatioDuringPinch).
- SetContentsScaleOnBothLayers(1.8f, 1.0f, 0.9f, 1.0f, false);
+ SetContentsScaleOnBothLayers(1.8f, 1.0f, 1.8f, 1.0f, false);
EXPECT_EQ(3u, active_layer_->tilings()->num_tilings());
EXPECT_FLOAT_EQ(2.0f,
active_layer_->tilings()->tiling_at(0)->contents_scale());
@@ -887,7 +885,7 @@
// Zoom in a lot now. Since we increase by increments of
// kMaxScaleRatioDuringPinch, this will create a new tiling at 4.0.
- SetContentsScaleOnBothLayers(3.8f, 1.0f, 2.1f, 1.f, false);
+ SetContentsScaleOnBothLayers(3.8f, 1.0f, 3.8f, 1.f, false);
EXPECT_EQ(4u, active_layer_->tilings()->num_tilings());
EXPECT_FLOAT_EQ(4.0f,
active_layer_->tilings()->tiling_at(0)->contents_scale());
@@ -902,9 +900,12 @@
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- // Set up the high and low res tilings before pinch zoom.
SetupTrees(pending_pile, active_pile);
+
+ ResetTilingsAndRasterScales();
EXPECT_EQ(0u, active_layer_->tilings()->num_tilings());
+
+ // Set up the high and low res tilings before pinch zoom.
SetContentsScaleOnBothLayers(0.24f, 1.0f, 0.24f, 1.0f, false);
EXPECT_EQ(2u, active_layer_->tilings()->num_tilings());
EXPECT_FLOAT_EQ(0.24f,
@@ -955,31 +956,28 @@
std::vector<PictureLayerTiling*> used_tilings;
- SetupTrees(pending_pile, active_pile);
- EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings());
-
float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
EXPECT_LT(low_res_factor, 1.f);
- float device_scale = 1.7f;
- float page_scale = 3.2f;
float scale = 1.f;
+ float page_scale = 1.f;
- SetContentsScaleOnBothLayers(scale, device_scale, page_scale, 1.f, false);
- ASSERT_EQ(2u, active_layer_->tilings()->num_tilings());
+ SetupTrees(pending_pile, active_pile);
+ EXPECT_EQ(2u, active_layer_->tilings()->num_tilings());
+ EXPECT_EQ(1.f, active_layer_->HighResTiling()->contents_scale());
// We only have ideal tilings, so they aren't removed.
used_tilings.clear();
active_layer_->CleanUpTilingsOnActiveLayer(used_tilings);
- ASSERT_EQ(2u, active_layer_->tilings()->num_tilings());
+ EXPECT_EQ(2u, active_layer_->tilings()->num_tilings());
host_impl_.PinchGestureBegin();
// Changing the ideal but not creating new tilings.
- scale *= 1.5f;
- page_scale *= 1.5f;
- SetContentsScaleOnBothLayers(scale, device_scale, page_scale, 1.f, false);
- ASSERT_EQ(2u, active_layer_->tilings()->num_tilings());
+ scale = 1.5f;
+ page_scale = 1.5f;
+ SetContentsScaleOnBothLayers(scale, 1.f, page_scale, 1.f, false);
+ EXPECT_EQ(2u, active_layer_->tilings()->num_tilings());
// The tilings are still our target scale, so they aren't removed.
used_tilings.clear();
@@ -989,9 +987,9 @@
host_impl_.PinchGestureEnd();
// Create a 1.2 scale tiling. Now we have 1.0 and 1.2 tilings. Ideal = 1.2.
- scale /= 4.f;
- page_scale /= 4.f;
- SetContentsScaleOnBothLayers(1.2f, device_scale, page_scale, 1.f, false);
+ scale = 1.2f;
+ page_scale = 1.2f;
+ SetContentsScaleOnBothLayers(1.2f, 1.f, page_scale, 1.f, false);
ASSERT_EQ(4u, active_layer_->tilings()->num_tilings());
EXPECT_FLOAT_EQ(
1.f,
@@ -1008,7 +1006,7 @@
ASSERT_EQ(4u, active_layer_->tilings()->num_tilings());
// Now move the ideal scale to 0.5. Our target stays 1.2.
- SetContentsScaleOnBothLayers(0.5f, device_scale, page_scale, 1.f, false);
+ SetContentsScaleOnBothLayers(0.5f, 1.f, page_scale, 1.f, false);
// The high resolution tiling is between target and ideal, so is not
// removed. The low res tiling for the old ideal=1.0 scale is removed.
@@ -1017,7 +1015,7 @@
ASSERT_EQ(3u, active_layer_->tilings()->num_tilings());
// Now move the ideal scale to 1.0. Our target stays 1.2.
- SetContentsScaleOnBothLayers(1.f, device_scale, page_scale, 1.f, false);
+ SetContentsScaleOnBothLayers(1.f, 1.f, page_scale, 1.f, false);
// All the tilings are between are target and the ideal, so they are not
// removed.
@@ -1026,8 +1024,8 @@
ASSERT_EQ(3u, active_layer_->tilings()->num_tilings());
// Now move the ideal scale to 1.1 on the active layer. Our target stays 1.2.
- SetupDrawPropertiesAndUpdateTiles(
- active_layer_, 1.1f, device_scale, page_scale, 1.f, false);
+ SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.1f, 1.f, page_scale, 1.f,
+ false);
// Because the pending layer's ideal scale is still 1.0, our tilings fall
// in the range [1.0,1.2] and are kept.
@@ -1037,8 +1035,8 @@
// Move the ideal scale on the pending layer to 1.1 as well. Our target stays
// 1.2 still.
- SetupDrawPropertiesAndUpdateTiles(
- pending_layer_, 1.1f, device_scale, page_scale, 1.f, false);
+ SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.1f, 1.f, page_scale, 1.f,
+ false);
// Our 1.0 tiling now falls outside the range between our ideal scale and our
// target raster scale. But it is in our used tilings set, so nothing is
@@ -1055,26 +1053,13 @@
ASSERT_EQ(2u, active_layer_->tilings()->num_tilings());
}
-#define EXPECT_BOTH_EQ(expression, x) \
- do { \
- EXPECT_EQ(x, pending_layer_->expression); \
- EXPECT_EQ(x, active_layer_->expression); \
- } while (false)
-
-#define EXPECT_BOTH_NE(expression, x) \
- do { \
- EXPECT_NE(x, pending_layer_->expression); \
- EXPECT_NE(x, active_layer_->expression); \
- } while (false)
-
TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) {
// Make sure this layer covers multiple tiles, since otherwise low
// res won't get created because it is too small.
gfx::Size tile_size(host_impl_.settings().default_tile_size);
- SetupDefaultTrees(gfx::Size(tile_size.width() + 1, tile_size.height() + 1));
// Avoid max untiled layer size heuristics via fixed tile size.
- pending_layer_->set_fixed_tile_size(tile_size);
- active_layer_->set_fixed_tile_size(tile_size);
+ gfx::Size layer_bounds(tile_size.width() + 1, tile_size.height() + 1);
+ SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region());
float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
float contents_scale = 1.f;
@@ -1083,6 +1068,8 @@
float maximum_animation_scale = 1.f;
bool animating_transform = true;
+ ResetTilingsAndRasterScales();
+
// Animating, so don't create low res even if there isn't one already.
SetContentsScaleOnBothLayers(contents_scale,
device_scale,
@@ -1104,7 +1091,8 @@
EXPECT_BOTH_EQ(num_tilings(), 2u);
// Page scale animation, new high res, but no low res. We still have
- // a tiling at the previous scale, it's just not marked as low res.
+ // a tiling at the previous scale, it's just not marked as low res on the
+ // active layer. The pending layer drops non-ideal tilings.
contents_scale = 2.f;
page_scale = 2.f;
maximum_animation_scale = 2.f;
@@ -1117,7 +1105,8 @@
EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f);
EXPECT_FALSE(active_layer_->LowResTiling());
EXPECT_FALSE(pending_layer_->LowResTiling());
- EXPECT_BOTH_EQ(num_tilings(), 3u);
+ EXPECT_EQ(3u, active_layer_->num_tilings());
+ EXPECT_EQ(1u, pending_layer_->num_tilings());
// Stop animating, new low res gets created for final page scale.
animating_transform = false;
@@ -1128,7 +1117,8 @@
animating_transform);
EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f);
EXPECT_BOTH_EQ(LowResTiling()->contents_scale(), 2.f * low_res_factor);
- EXPECT_BOTH_EQ(num_tilings(), 4u);
+ EXPECT_EQ(4u, active_layer_->num_tilings());
+ EXPECT_EQ(2u, pending_layer_->num_tilings());
}
TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) {
@@ -1185,120 +1175,187 @@
contents_scale * low_res_factor);
EXPECT_BOTH_EQ(num_tilings(), 2u);
- ResetTilingsAndRasterScales();
-
// Mask layers dont create low res since they always fit on one tile.
- pending_layer_->set_is_mask(true);
- active_layer_->set_is_mask(true);
- SetContentsScaleOnBothLayers(contents_scale,
- device_scale,
- page_scale,
- maximum_animation_scale,
- animating_transform);
- EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), contents_scale);
- EXPECT_BOTH_EQ(num_tilings(), 1u);
+ scoped_ptr<FakePictureLayerImpl> mask =
+ FakePictureLayerImpl::CreateMaskWithRasterSource(
+ host_impl_.pending_tree(), 3, pending_pile);
+ mask->SetBounds(layer_bounds);
+ mask->SetContentBounds(layer_bounds);
+ mask->SetDrawsContent(true);
+
+ SetupDrawPropertiesAndUpdateTiles(mask.get(), contents_scale, device_scale,
+ page_scale, maximum_animation_scale,
+ animating_transform);
+ EXPECT_EQ(mask->HighResTiling()->contents_scale(), contents_scale);
+ EXPECT_EQ(mask->num_tilings(), 1u);
}
TEST_F(PictureLayerImplTest, HugeMasksDontGetTiles) {
+ base::TimeTicks time_ticks;
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+
gfx::Size tile_size(100, 100);
+ gfx::Size layer_bounds(1000, 1000);
scoped_refptr<FakePicturePileImpl> valid_pile =
- FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(1000, 1000));
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupPendingTree(valid_pile);
- pending_layer_->set_is_mask(true);
- SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
- EXPECT_EQ(1.f, pending_layer_->HighResTiling()->contents_scale());
- EXPECT_EQ(1u, pending_layer_->num_tilings());
+ scoped_ptr<FakePictureLayerImpl> mask_ptr =
+ FakePictureLayerImpl::CreateMaskWithRasterSource(
+ host_impl_.pending_tree(), 3, valid_pile);
+ mask_ptr->SetBounds(layer_bounds);
+ mask_ptr->SetContentBounds(layer_bounds);
+ mask_ptr->SetDrawsContent(true);
+ pending_layer_->SetMaskLayer(mask_ptr.Pass());
- pending_layer_->HighResTiling()->CreateAllTilesForTesting();
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.pending_tree()->UpdateDrawProperties();
+
+ FakePictureLayerImpl* pending_mask =
+ static_cast<FakePictureLayerImpl*>(pending_layer_->mask_layer());
+
+ EXPECT_EQ(1.f, pending_mask->HighResTiling()->contents_scale());
+ EXPECT_EQ(1u, pending_mask->num_tilings());
+
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(
- pending_layer_->HighResTiling()->AllTilesForTesting());
+ pending_mask->HighResTiling()->AllTilesForTesting());
ActivateTree();
+ FakePictureLayerImpl* active_mask =
+ static_cast<FakePictureLayerImpl*>(active_layer_->mask_layer());
+
// Mask layers have a tiling with a single tile in it.
- EXPECT_EQ(1u, active_layer_->HighResTiling()->AllTilesForTesting().size());
+ EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size());
// The mask resource exists.
ResourceProvider::ResourceId mask_resource_id;
gfx::Size mask_texture_size;
- active_layer_->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
+ active_mask->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
+ EXPECT_NE(0u, mask_resource_id);
+ EXPECT_EQ(mask_texture_size, active_mask->bounds());
+
+ // Drop resources and recreate them, still the same.
+ pending_mask->ReleaseResources();
+ active_mask->ReleaseResources();
+ SetupDrawPropertiesAndUpdateTiles(active_mask, 1.f, 1.f, 1.f, 1.f, false);
+ active_mask->HighResTiling()->CreateAllTilesForTesting();
+ EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size());
EXPECT_NE(0u, mask_resource_id);
EXPECT_EQ(mask_texture_size, active_layer_->bounds());
// Drop resources and recreate them, still the same.
- old_pending_layer_->ReleaseResources();
- active_layer_->ReleaseResources();
- SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, false);
- active_layer_->HighResTiling()->CreateAllTilesForTesting();
- EXPECT_EQ(1u, active_layer_->HighResTiling()->AllTilesForTesting().size());
+ pending_mask->ReleaseResources();
+ active_mask->ReleaseResources();
+ SetupDrawPropertiesAndUpdateTiles(active_mask, 1.f, 1.f, 1.f, 1.f, false);
+ active_mask->HighResTiling()->CreateAllTilesForTesting();
+ EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size());
EXPECT_NE(0u, mask_resource_id);
- EXPECT_EQ(mask_texture_size, active_layer_->bounds());
+ EXPECT_EQ(mask_texture_size, active_mask->bounds());
// Resize larger than the max texture size.
int max_texture_size = host_impl_.GetRendererCapabilities().max_texture_size;
+ gfx::Size huge_bounds(max_texture_size + 1, 10);
scoped_refptr<FakePicturePileImpl> huge_pile =
- FakePicturePileImpl::CreateFilledPile(
- tile_size, gfx::Size(max_texture_size + 1, 10));
+ FakePicturePileImpl::CreateFilledPile(tile_size, huge_bounds);
+
SetupPendingTree(huge_pile);
- pending_layer_->set_is_mask(true);
+ pending_mask->SetBounds(huge_bounds);
+ pending_mask->SetContentBounds(huge_bounds);
+ pending_mask->SetRasterSourceOnPending(huge_pile, Region());
- SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
- EXPECT_EQ(1.f, pending_layer_->HighResTiling()->contents_scale());
- EXPECT_EQ(1u, pending_layer_->num_tilings());
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.pending_tree()->UpdateDrawProperties();
- pending_layer_->HighResTiling()->CreateAllTilesForTesting();
+ EXPECT_EQ(1.f, pending_mask->HighResTiling()->contents_scale());
+ EXPECT_EQ(1u, pending_mask->num_tilings());
+
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(
- pending_layer_->HighResTiling()->AllTilesForTesting());
+ pending_mask->HighResTiling()->AllTilesForTesting());
ActivateTree();
// Mask layers have a tiling, but there should be no tiles in it.
- EXPECT_EQ(0u, active_layer_->HighResTiling()->AllTilesForTesting().size());
+ EXPECT_EQ(0u, active_mask->HighResTiling()->AllTilesForTesting().size());
// The mask resource is empty.
active_layer_->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
EXPECT_EQ(0u, mask_resource_id);
// Drop resources and recreate them, still the same.
- old_pending_layer_->ReleaseResources();
- active_layer_->ReleaseResources();
- SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, false);
- active_layer_->HighResTiling()->CreateAllTilesForTesting();
- EXPECT_EQ(0u, active_layer_->HighResTiling()->AllTilesForTesting().size());
+ pending_mask->ReleaseResources();
+ active_mask->ReleaseResources();
+ SetupDrawPropertiesAndUpdateTiles(active_mask, 1.f, 1.f, 1.f, 1.f, false);
+ active_mask->HighResTiling()->CreateAllTilesForTesting();
+ EXPECT_EQ(0u, active_mask->HighResTiling()->AllTilesForTesting().size());
+ active_mask->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
+ EXPECT_EQ(0u, mask_resource_id);
+
+ // Do another activate, the same holds.
+ SetupPendingTree(huge_pile);
+ ActivateTree();
+ EXPECT_EQ(0u, active_mask->HighResTiling()->AllTilesForTesting().size());
active_layer_->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
EXPECT_EQ(0u, mask_resource_id);
}
TEST_F(PictureLayerImplTest, ScaledMaskLayer) {
+ base::TimeTicks time_ticks;
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+
gfx::Size tile_size(100, 100);
+ gfx::Size layer_bounds(1000, 1000);
+
+ host_impl_.SetDeviceScaleFactor(1.3f);
scoped_refptr<FakePicturePileImpl> valid_pile =
- FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(1000, 1000));
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupPendingTree(valid_pile);
- pending_layer_->set_is_mask(true);
- float ideal_contents_scale = 1.3f;
- SetupDrawPropertiesAndUpdateTiles(
- pending_layer_, ideal_contents_scale, 1.f, 1.f, 1.f, false);
- EXPECT_EQ(ideal_contents_scale,
- pending_layer_->HighResTiling()->contents_scale());
- EXPECT_EQ(1u, pending_layer_->num_tilings());
+ scoped_ptr<FakePictureLayerImpl> mask_ptr =
+ FakePictureLayerImpl::CreateMaskWithRasterSource(
+ host_impl_.pending_tree(), 3, valid_pile);
+ mask_ptr->SetBounds(layer_bounds);
+ mask_ptr->SetContentBounds(layer_bounds);
+ mask_ptr->SetDrawsContent(true);
+ pending_layer_->SetMaskLayer(mask_ptr.Pass());
- pending_layer_->HighResTiling()->CreateAllTilesForTesting();
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.pending_tree()->UpdateDrawProperties();
+
+ FakePictureLayerImpl* pending_mask =
+ static_cast<FakePictureLayerImpl*>(pending_layer_->mask_layer());
+
+ // Masks are scaled, and do not have a low res tiling.
+ EXPECT_EQ(1.3f, pending_mask->HighResTiling()->contents_scale());
+ EXPECT_EQ(1u, pending_mask->num_tilings());
+
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(
- pending_layer_->HighResTiling()->AllTilesForTesting());
+ pending_mask->HighResTiling()->AllTilesForTesting());
ActivateTree();
+ FakePictureLayerImpl* active_mask =
+ static_cast<FakePictureLayerImpl*>(active_layer_->mask_layer());
+
// Mask layers have a tiling with a single tile in it.
- EXPECT_EQ(1u, active_layer_->HighResTiling()->AllTilesForTesting().size());
+ EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size());
// The mask resource exists.
ResourceProvider::ResourceId mask_resource_id;
gfx::Size mask_texture_size;
- active_layer_->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
+ active_mask->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
EXPECT_NE(0u, mask_resource_id);
- gfx::Size expected_mask_texture_size = gfx::ToCeiledSize(
- gfx::ScaleSize(active_layer_->bounds(), ideal_contents_scale));
+ gfx::Size expected_mask_texture_size =
+ gfx::ToCeiledSize(gfx::ScaleSize(active_mask->bounds(), 1.3f));
EXPECT_EQ(mask_texture_size, expected_mask_texture_size);
}
@@ -1312,14 +1369,6 @@
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupTrees(pending_pile, active_pile);
- EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings());
-
- SetupDrawPropertiesAndUpdateTiles(pending_layer_,
- 1.3f, // ideal contents scale
- 2.7f, // device scale
- 3.2f, // page scale
- 1.f, // maximum animation scale
- false);
EXPECT_EQ(2u, pending_layer_->tilings()->num_tilings());
// All tilings should be removed when losing output surface.
@@ -1330,10 +1379,10 @@
// This should create new tilings.
SetupDrawPropertiesAndUpdateTiles(pending_layer_,
- 1.3f, // ideal contents scale
- 2.7f, // device scale
- 3.2f, // page scale
- 1.f, // maximum animation scale
+ 1.f, // ideal contents scale
+ 1.f, // device scale
+ 1.f, // page scale
+ 1.f, // maximum animation scale
false);
EXPECT_EQ(2u, pending_layer_->tilings()->num_tilings());
}
@@ -1349,10 +1398,7 @@
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupTrees(pending_pile, active_pile);
- EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings());
-
- SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
- ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings());
+ EXPECT_GE(pending_layer_->tilings()->num_tilings(), 1u);
pending_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting();
@@ -1364,7 +1410,7 @@
EXPECT_EQ(gfx::Size(256, 256).ToString(),
tile->content_rect().size().ToString());
- pending_layer_->ReleaseResources();
+ ResetTilingsAndRasterScales();
// Change the max texture size on the output surface context.
scoped_ptr<TestWebGraphicsContext3D> context =
@@ -1396,10 +1442,7 @@
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupTrees(pending_pile, active_pile);
- EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings());
-
- SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
- ASSERT_LE(1u, pending_layer_->tilings()->num_tilings());
+ EXPECT_GE(pending_layer_->tilings()->num_tilings(), 1u);
pending_layer_->tilings()->tiling_at(0)->CreateAllTilesForTesting();
@@ -1411,7 +1454,7 @@
PictureLayerTiling* high_res_tiling = pending_layer_->tilings()->tiling_at(0);
EXPECT_EQ(1u, high_res_tiling->AllTilesForTesting().size());
- pending_layer_->ReleaseResources();
+ ResetTilingsAndRasterScales();
// Change the max texture size on the output surface context.
scoped_ptr<TestWebGraphicsContext3D> context =
@@ -1448,15 +1491,12 @@
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
+ gfx::Rect layer_invalidation(150, 200, 30, 180);
+ SetupTreesWithInvalidation(pending_pile, active_pile, layer_invalidation);
active_layer_->draw_properties().visible_content_rect =
gfx::Rect(layer_bounds);
- gfx::Rect layer_invalidation(150, 200, 30, 180);
- Region invalidation(layer_invalidation);
- AddDefaultTilingsWithInvalidation(invalidation);
-
AppendQuadsData data;
active_layer_->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, nullptr);
active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
@@ -1514,33 +1554,20 @@
pending_pile->set_is_solid_color(false);
active_pile->set_is_solid_color(true);
SetupTrees(pending_pile, active_pile);
- // Solid color layer should not have tilings.
- ASSERT_FALSE(active_layer_->CanHaveTilings());
-
- // Update properties with solid color pile should not allow tilings at any
- // scale.
- host_impl_.active_tree()->UpdateDrawProperties();
+ // Solid color pile should not allow tilings at any scale.
EXPECT_FALSE(active_layer_->CanHaveTilings());
EXPECT_EQ(0.f, active_layer_->ideal_contents_scale());
- // Push non-solid-color pending pile makes active layer can have tilings.
- active_layer_->UpdateRasterSource(pending_pile);
- ASSERT_TRUE(active_layer_->CanHaveTilings());
-
- // Update properties with non-solid color pile should allow tilings.
- host_impl_.active_tree()->UpdateDrawProperties();
+ // Activate non-solid-color pending pile makes active layer can have tilings.
+ ActivateTree();
EXPECT_TRUE(active_layer_->CanHaveTilings());
EXPECT_GT(active_layer_->ideal_contents_scale(), 0.f);
}
-TEST_F(PictureLayerImplTest, MarkRequiredOffscreenTiles) {
+TEST_F(NoLowResPictureLayerImplTest, MarkRequiredOffscreenTiles) {
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(200, 200);
- scoped_refptr<FakePicturePileImpl> pending_pile =
- FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupPendingTree(pending_pile);
-
gfx::Transform transform;
gfx::Transform transform_for_tile_priority;
bool resourceless_software_draw = false;
@@ -1552,10 +1579,11 @@
transform,
resourceless_software_draw);
- pending_layer_->set_fixed_tile_size(tile_size);
- ASSERT_TRUE(pending_layer_->CanHaveTilings());
- PictureLayerTiling* tiling = pending_layer_->AddTiling(1.f);
- host_impl_.pending_tree()->UpdateDrawProperties();
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, Region());
+
+ EXPECT_EQ(1u, pending_layer_->num_tilings());
EXPECT_EQ(viewport, pending_layer_->visible_rect_for_tile_priority());
base::TimeTicks time_ticks;
@@ -1563,13 +1591,13 @@
host_impl_.SetCurrentBeginFrameArgs(
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
pending_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
- EXPECT_EQ(HIGH_RESOLUTION, tiling->resolution());
int num_visible = 0;
int num_offscreen = 0;
- for (PictureLayerTiling::TilingRasterTileIterator iter(tiling); iter;
- ++iter) {
+ for (PictureLayerTiling::TilingRasterTileIterator iter(
+ pending_layer_->HighResTiling());
+ iter; ++iter) {
const Tile* tile = *iter;
DCHECK(tile);
if (tile->priority(PENDING_TREE).distance_to_visible == 0.f) {
@@ -1585,7 +1613,8 @@
EXPECT_GT(num_offscreen, 0);
}
-TEST_F(PictureLayerImplTest, TileOutsideOfViewportForTilePriorityNotRequired) {
+TEST_F(NoLowResPictureLayerImplTest,
+ TileOutsideOfViewportForTilePriorityNotRequired) {
base::TimeTicks time_ticks;
time_ticks += base::TimeDelta::FromMilliseconds(1);
host_impl_.SetCurrentBeginFrameArgs(
@@ -1600,12 +1629,10 @@
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
+ SetupTreesWithFixedTileSize(pending_pile, active_pile, tile_size, Region());
- active_layer_->set_fixed_tile_size(tile_size);
- pending_layer_->set_fixed_tile_size(tile_size);
- ASSERT_TRUE(pending_layer_->CanHaveTilings());
- PictureLayerTiling* tiling = pending_layer_->AddTiling(1.f);
+ ASSERT_EQ(1u, pending_layer_->num_tilings());
+ ASSERT_EQ(1.f, pending_layer_->HighResTiling()->contents_scale());
// Set external viewport for tile priority.
gfx::Rect viewport = gfx::Rect(layer_bounds);
@@ -1618,6 +1645,9 @@
external_viewport_for_tile_priority,
transform_for_tile_priority,
resourceless_software_draw);
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
host_impl_.pending_tree()->UpdateDrawProperties();
// Set visible content rect that is different from
@@ -1637,9 +1667,8 @@
int num_inside = 0;
int num_outside = 0;
for (PictureLayerTiling::CoverageIterator iter(
- tiling, pending_layer_->contents_scale_x(), gfx::Rect(layer_bounds));
- iter;
- ++iter) {
+ pending_layer_->HighResTiling(), 1.f, gfx::Rect(layer_bounds));
+ iter; ++iter) {
if (!*iter)
continue;
Tile* tile = *iter;
@@ -1683,16 +1712,13 @@
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(200, 200);
- host_impl_.SetViewportSize(layer_bounds);
-
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupPendingTree(pending_pile);
+
+ SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, Region());
ActivateTree();
// All high res tiles have resources.
- active_layer_->set_fixed_tile_size(tile_size);
- host_impl_.active_tree()->UpdateDrawProperties();
std::vector<Tile*> tiles =
active_layer_->tilings()->tiling_at(0)->AllTilesForTesting();
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
@@ -1719,16 +1745,11 @@
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(200, 200);
- host_impl_.SetViewportSize(layer_bounds);
-
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupPendingTree(pending_pile);
+ SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, Region());
ActivateTree();
- active_layer_->set_fixed_tile_size(tile_size);
- host_impl_.active_tree()->UpdateDrawProperties();
-
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
AppendQuadsData data;
active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
@@ -1750,15 +1771,11 @@
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(200, 200);
- host_impl_.SetViewportSize(layer_bounds);
-
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupPendingTree(pending_pile);
+ SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, Region());
ActivateTree();
- active_layer_->set_fixed_tile_size(tile_size);
- host_impl_.active_tree()->UpdateDrawProperties();
std::vector<Tile*> low_tiles =
active_layer_->tilings()->tiling_at(1)->AllTilesForTesting();
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(low_tiles);
@@ -1784,16 +1801,12 @@
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(200, 200);
- host_impl_.SetViewportSize(layer_bounds);
-
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupPendingTree(pending_pile);
+ SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, Region());
ActivateTree();
// All high res tiles have resources except one.
- active_layer_->set_fixed_tile_size(tile_size);
- host_impl_.active_tree()->UpdateDrawProperties();
std::vector<Tile*> high_tiles =
active_layer_->tilings()->tiling_at(0)->AllTilesForTesting();
high_tiles.erase(high_tiles.begin());
@@ -1826,20 +1839,16 @@
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(200, 200);
+ gfx::Size viewport_size(400, 400);
- host_impl_.SetViewportSize(layer_bounds);
+ host_impl_.SetViewportSize(viewport_size);
+ host_impl_.SetDeviceScaleFactor(2.f);
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
-
- active_layer_->set_fixed_tile_size(tile_size);
-
- active_layer_->draw_properties().visible_content_rect =
- gfx::Rect(layer_bounds);
- SetupDrawPropertiesAndUpdateTiles(active_layer_, 2.f, 1.f, 1.f, 1.f, false);
+ SetupTreesWithFixedTileSize(pending_pile, active_pile, tile_size, Region());
// One ideal tile exists, this will get used when drawing.
std::vector<Tile*> ideal_tiles;
@@ -1891,14 +1900,9 @@
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
- host_impl_.SetViewportSize(layer_bounds);
-
- SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
-
// No tiles shared.
- pending_layer_->set_invalidation(gfx::Rect(layer_bounds));
-
- CreateHighLowResAndSetAllTilesVisible();
+ SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size,
+ gfx::Rect(layer_bounds));
active_layer_->SetAllTilesReady();
@@ -1915,12 +1919,8 @@
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
- host_impl_.SetViewportSize(layer_bounds);
-
- SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
-
// All tiles shared (no invalidation).
- CreateHighLowResAndSetAllTilesVisible();
+ SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region());
// Verify active tree not ready.
Tile* some_active_tile =
@@ -1942,11 +1942,7 @@
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
- host_impl_.SetViewportSize(layer_bounds);
-
- SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
-
- CreateHighLowResAndSetAllTilesVisible();
+ SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region());
Tile* some_active_tile =
active_layer_->HighResTiling()->AllTilesForTesting()[0];
@@ -1964,9 +1960,8 @@
TEST_F(PictureLayerImplTest, DisallowRequiredForActivation) {
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
- SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
- CreateHighLowResAndSetAllTilesVisible();
+ SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region());
Tile* some_active_tile =
active_layer_->HighResTiling()->AllTilesForTesting()[0];
@@ -1986,6 +1981,7 @@
TEST_F(PictureLayerImplTest, NothingRequiredIfActiveMissingTiles) {
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
+
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
// This pile will create tilings, but has no recordings so will not create any
@@ -1995,11 +1991,8 @@
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateEmptyPileThatThinksItHasRecordings(
tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
- pending_layer_->set_fixed_tile_size(tile_size);
- active_layer_->set_fixed_tile_size(tile_size);
- CreateHighLowResAndSetAllTilesVisible();
+ SetupTreesWithFixedTileSize(pending_pile, active_pile, tile_size, Region());
// Active layer has tilings, but no tiles due to missing recordings.
EXPECT_TRUE(active_layer_->CanHaveTilings());
@@ -2019,17 +2012,11 @@
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
- host_impl_.SetViewportSize(layer_bounds);
-
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
- pending_layer_->set_fixed_tile_size(tile_size);
- active_layer_->set_fixed_tile_size(tile_size);
-
- CreateHighLowResAndSetAllTilesVisible();
+ SetupTreesWithFixedTileSize(pending_pile, active_pile, tile_size, Region());
// Active layer can't have tiles.
EXPECT_FALSE(active_layer_->CanHaveTilings());
@@ -2046,21 +2033,16 @@
}
TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveHasDifferentBounds) {
- gfx::Size layer_bounds(200, 200);
- gfx::Size tile_size(100, 100);
- SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
-
gfx::Size pending_layer_bounds(400, 400);
- pending_layer_->SetBounds(pending_layer_bounds);
+ gfx::Size active_layer_bounds(200, 200);
+ gfx::Size tile_size(100, 100);
- CreateHighLowResAndSetAllTilesVisible();
- // TODO(vmpstr): This is confusing. Rework the test to create different bounds
- // on different trees instead of fudging tilings.
- pending_layer_->HighResTiling()->ComputeTilePriorityRects(
- gfx::Rect(pending_layer_bounds), 1.f, 1.f, Occlusion());
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, pending_layer_bounds);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, active_layer_bounds);
- pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
- active_layer_->SetAllTilesReady();
+ SetupTreesWithFixedTileSize(pending_pile, active_pile, tile_size, Region());
// Since the active layer has different bounds, the pending layer needs all
// high res tiles in order to activate.
@@ -2108,9 +2090,15 @@
}
TEST_F(PictureLayerImplTest, ShareTilesOnNextFrame) {
- SetupDefaultTrees(gfx::Size(1500, 1500));
+ gfx::Size layer_bounds(1500, 1500);
+ gfx::Size tile_size(100, 100);
- PictureLayerTiling* tiling = pending_layer_->AddTiling(1.f);
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+ SetupPendingTree(pending_pile);
+
+ PictureLayerTiling* tiling = pending_layer_->HighResTiling();
gfx::Rect first_invalidate = tiling->TilingDataForTesting().TileBounds(0, 0);
first_invalidate.Inset(tiling->TilingDataForTesting().border_texels(),
tiling->TilingDataForTesting().border_texels());
@@ -2118,22 +2106,20 @@
second_invalidate.Inset(tiling->TilingDataForTesting().border_texels(),
tiling->TilingDataForTesting().border_texels());
+ ActivateTree();
+
// Make a pending tree with an invalidated raster tile 0,0.
- tiling->CreateAllTilesForTesting();
- pending_layer_->set_invalidation(first_invalidate);
+ SetupPendingTreeWithInvalidation(pending_pile, first_invalidate);
// Activate and make a pending tree with an invalidated raster tile 1,1.
ActivateTree();
- host_impl_.CreatePendingTree();
- pending_layer_ = static_cast<FakePictureLayerImpl*>(
- host_impl_.pending_tree()->root_layer());
- pending_layer_->set_invalidation(second_invalidate);
+ SetupPendingTreeWithInvalidation(pending_pile, second_invalidate);
PictureLayerTiling* pending_tiling = pending_layer_->tilings()->tiling_at(0);
PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(0);
- pending_tiling->CreateAllTilesForTesting();
+ // pending_tiling->CreateAllTilesForTesting();
// Tile 0,0 should be shared, but tile 1,1 should not be.
EXPECT_EQ(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
@@ -2162,180 +2148,138 @@
EXPECT_FALSE(pending_tiling->TileAt(1, 1)->is_shared());
}
-TEST_F(PictureLayerImplTest, ShareTilesOnSync) {
+TEST_F(PictureLayerImplTest, ShareTilesWithNoInvalidation) {
SetupDefaultTrees(gfx::Size(1500, 1500));
- AddDefaultTilingsWithInvalidation(gfx::Rect());
- host_impl_.ActivateSyncTree();
- host_impl_.CreatePendingTree();
- active_layer_ = static_cast<FakePictureLayerImpl*>(
- host_impl_.active_tree()->LayerById(id_));
+ EXPECT_GE(active_layer_->num_tilings(), 1u);
+ EXPECT_GE(pending_layer_->num_tilings(), 1u);
- // Force the active tree to sync to the pending tree "post-commit".
- pending_layer_->DoPostCommitInitializationIfNeeded();
+ // No invalidation, so all tiles are shared.
+ PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(0);
+ PictureLayerTiling* pending_tiling = pending_layer_->tilings()->tiling_at(0);
+ ASSERT_TRUE(active_tiling);
+ ASSERT_TRUE(pending_tiling);
- // Both invalidations should drop tiles from the pending tree.
- EXPECT_EQ(3u, active_layer_->num_tilings());
- EXPECT_EQ(3u, pending_layer_->num_tilings());
- for (size_t i = 0; i < active_layer_->num_tilings(); ++i) {
- PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(i);
- PictureLayerTiling* pending_tiling =
- pending_layer_->tilings()->tiling_at(i);
+ EXPECT_TRUE(active_tiling->TileAt(0, 0));
+ EXPECT_TRUE(active_tiling->TileAt(1, 0));
+ EXPECT_TRUE(active_tiling->TileAt(0, 1));
+ EXPECT_TRUE(active_tiling->TileAt(1, 1));
- ASSERT_TRUE(active_tiling);
- ASSERT_TRUE(pending_tiling);
+ EXPECT_TRUE(pending_tiling->TileAt(0, 0));
+ EXPECT_TRUE(pending_tiling->TileAt(1, 0));
+ EXPECT_TRUE(pending_tiling->TileAt(0, 1));
+ EXPECT_TRUE(pending_tiling->TileAt(1, 1));
- EXPECT_TRUE(active_tiling->TileAt(0, 0));
- EXPECT_TRUE(active_tiling->TileAt(1, 0));
- EXPECT_TRUE(active_tiling->TileAt(0, 1));
- EXPECT_TRUE(active_tiling->TileAt(1, 1));
-
- EXPECT_TRUE(pending_tiling->TileAt(0, 0));
- EXPECT_TRUE(pending_tiling->TileAt(1, 0));
- EXPECT_TRUE(pending_tiling->TileAt(0, 1));
- EXPECT_TRUE(pending_tiling->TileAt(1, 1));
-
- EXPECT_EQ(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
- EXPECT_TRUE(active_tiling->TileAt(0, 0)->is_shared());
- EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0));
- EXPECT_TRUE(active_tiling->TileAt(1, 0)->is_shared());
- EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1));
- EXPECT_TRUE(active_tiling->TileAt(0, 1)->is_shared());
- EXPECT_EQ(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1));
- EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared());
- }
+ EXPECT_EQ(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
+ EXPECT_TRUE(active_tiling->TileAt(0, 0)->is_shared());
+ EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0));
+ EXPECT_TRUE(active_tiling->TileAt(1, 0)->is_shared());
+ EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1));
+ EXPECT_TRUE(active_tiling->TileAt(0, 1)->is_shared());
+ EXPECT_EQ(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1));
+ EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared());
}
-TEST_F(PictureLayerImplTest, ShareInvalidActiveTreeTilesOnSync) {
- SetupDefaultTrees(gfx::Size(1500, 1500));
- AddDefaultTilingsWithInvalidation(gfx::Rect(0, 0, 1, 1));
+TEST_F(PictureLayerImplTest, ShareInvalidActiveTreeTiles) {
+ gfx::Size tile_size(100, 100);
+ gfx::Size layer_bounds(1500, 1500);
- // This activates the 0,0,1,1 invalidation.
- host_impl_.ActivateSyncTree();
- host_impl_.CreatePendingTree();
- active_layer_ = static_cast<FakePictureLayerImpl*>(
- host_impl_.active_tree()->LayerById(id_));
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ SetupTreesWithInvalidation(pending_pile, active_pile, gfx::Rect(1, 1));
+ // Activate the invalidation.
+ ActivateTree();
+ // Make another pending tree without any invalidation in it.
+ scoped_refptr<FakePicturePileImpl> pending_pile2 =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ SetupPendingTree(pending_pile2);
- // Force the active tree to sync to the pending tree "post-commit".
- pending_layer_->DoPostCommitInitializationIfNeeded();
+ EXPECT_GE(active_layer_->num_tilings(), 1u);
+ EXPECT_GE(pending_layer_->num_tilings(), 1u);
// The active tree invalidation was handled by the active tiles, so they
// can be shared with the pending tree.
- EXPECT_EQ(3u, active_layer_->num_tilings());
- EXPECT_EQ(3u, pending_layer_->num_tilings());
- for (size_t i = 0; i < active_layer_->num_tilings(); ++i) {
- PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(i);
- PictureLayerTiling* pending_tiling =
- pending_layer_->tilings()->tiling_at(i);
+ PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(0);
+ PictureLayerTiling* pending_tiling = pending_layer_->tilings()->tiling_at(0);
+ ASSERT_TRUE(active_tiling);
+ ASSERT_TRUE(pending_tiling);
- ASSERT_TRUE(active_tiling);
- ASSERT_TRUE(pending_tiling);
+ EXPECT_TRUE(active_tiling->TileAt(0, 0));
+ EXPECT_TRUE(active_tiling->TileAt(1, 0));
+ EXPECT_TRUE(active_tiling->TileAt(0, 1));
+ EXPECT_TRUE(active_tiling->TileAt(1, 1));
- EXPECT_TRUE(active_tiling->TileAt(0, 0));
- EXPECT_TRUE(active_tiling->TileAt(1, 0));
- EXPECT_TRUE(active_tiling->TileAt(0, 1));
- EXPECT_TRUE(active_tiling->TileAt(1, 1));
+ EXPECT_TRUE(pending_tiling->TileAt(0, 0));
+ EXPECT_TRUE(pending_tiling->TileAt(1, 0));
+ EXPECT_TRUE(pending_tiling->TileAt(0, 1));
+ EXPECT_TRUE(pending_tiling->TileAt(1, 1));
- EXPECT_TRUE(pending_tiling->TileAt(0, 0));
- EXPECT_TRUE(pending_tiling->TileAt(1, 0));
- EXPECT_TRUE(pending_tiling->TileAt(0, 1));
- EXPECT_TRUE(pending_tiling->TileAt(1, 1));
-
- EXPECT_EQ(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
- EXPECT_TRUE(active_tiling->TileAt(0, 0)->is_shared());
- EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0));
- EXPECT_TRUE(active_tiling->TileAt(1, 0)->is_shared());
- EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1));
- EXPECT_TRUE(active_tiling->TileAt(0, 1)->is_shared());
- EXPECT_EQ(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1));
- EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared());
- }
+ EXPECT_EQ(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
+ EXPECT_TRUE(active_tiling->TileAt(0, 0)->is_shared());
+ EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0));
+ EXPECT_TRUE(active_tiling->TileAt(1, 0)->is_shared());
+ EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1));
+ EXPECT_TRUE(active_tiling->TileAt(0, 1)->is_shared());
+ EXPECT_EQ(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1));
+ EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared());
}
-TEST_F(PictureLayerImplTest, RemoveInvalidPendingTreeTilesOnSync) {
- SetupDefaultTrees(gfx::Size(1500, 1500));
- AddDefaultTilingsWithInvalidation(gfx::Rect());
+TEST_F(PictureLayerImplTest, RecreateInvalidPendingTreeTiles) {
+ // Set some invalidation on the pending tree. We should replace raster tiles
+ // that touch this.
+ SetupDefaultTreesWithInvalidation(gfx::Size(1500, 1500), gfx::Rect(1, 1));
- host_impl_.ActivateSyncTree();
- host_impl_.CreatePendingTree();
- active_layer_ = static_cast<FakePictureLayerImpl*>(
- host_impl_.active_tree()->LayerById(id_));
-
- // Set some invalidation on the pending tree "during commit". We should
- // replace raster tiles that touch this.
- pending_layer_->set_invalidation(gfx::Rect(1, 1));
-
- // Force the active tree to sync to the pending tree "post-commit".
- pending_layer_->DoPostCommitInitializationIfNeeded();
+ EXPECT_GE(active_layer_->num_tilings(), 1u);
+ EXPECT_GE(pending_layer_->num_tilings(), 1u);
// The pending tree invalidation means tiles can not be shared with the
// active tree.
- EXPECT_EQ(3u, active_layer_->num_tilings());
- EXPECT_EQ(3u, pending_layer_->num_tilings());
- for (size_t i = 0; i < active_layer_->num_tilings(); ++i) {
- PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(i);
- PictureLayerTiling* pending_tiling =
- pending_layer_->tilings()->tiling_at(i);
+ PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(0);
+ PictureLayerTiling* pending_tiling = pending_layer_->tilings()->tiling_at(0);
+ ASSERT_TRUE(active_tiling);
+ ASSERT_TRUE(pending_tiling);
- ASSERT_TRUE(active_tiling);
- ASSERT_TRUE(pending_tiling);
+ EXPECT_TRUE(active_tiling->TileAt(0, 0));
+ EXPECT_TRUE(active_tiling->TileAt(1, 0));
+ EXPECT_TRUE(active_tiling->TileAt(0, 1));
+ EXPECT_TRUE(active_tiling->TileAt(1, 1));
- EXPECT_TRUE(active_tiling->TileAt(0, 0));
- EXPECT_TRUE(active_tiling->TileAt(1, 0));
- EXPECT_TRUE(active_tiling->TileAt(0, 1));
- EXPECT_TRUE(active_tiling->TileAt(1, 1));
+ EXPECT_TRUE(pending_tiling->TileAt(0, 0));
+ EXPECT_TRUE(pending_tiling->TileAt(1, 0));
+ EXPECT_TRUE(pending_tiling->TileAt(0, 1));
+ EXPECT_TRUE(pending_tiling->TileAt(1, 1));
- EXPECT_TRUE(pending_tiling->TileAt(0, 0));
- EXPECT_TRUE(pending_tiling->TileAt(1, 0));
- EXPECT_TRUE(pending_tiling->TileAt(0, 1));
- EXPECT_TRUE(pending_tiling->TileAt(1, 1));
-
- EXPECT_NE(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
- EXPECT_FALSE(active_tiling->TileAt(0, 0)->is_shared());
- EXPECT_FALSE(pending_tiling->TileAt(0, 0)->is_shared());
- EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0));
- EXPECT_TRUE(active_tiling->TileAt(1, 0)->is_shared());
- EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1));
- EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared());
- EXPECT_EQ(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1));
- EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared());
- }
-}
-
-TEST_F(PictureLayerImplTest, SyncTilingAfterReleaseResource) {
- SetupDefaultTrees(gfx::Size(10, 10));
- host_impl_.active_tree()->UpdateDrawProperties();
- EXPECT_FALSE(host_impl_.active_tree()->needs_update_draw_properties());
-
- // Contrived unit test of a real crash. A layer is transparent during a
- // context loss, and later becomes opaque, causing active layer SyncTiling to
- // be called.
- float new_scale = 1.f;
- active_layer_->ReleaseResources();
- pending_layer_->ReleaseResources();
- EXPECT_FALSE(active_layer_->tilings()->FindTilingWithScale(new_scale));
- pending_layer_->AddTiling(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
- // ReleaseResources has set needs update draw properties so that the
- // new tiling gets the appropriate resolution set in ManageTilings.
- EXPECT_TRUE(host_impl_.active_tree()->needs_update_draw_properties());
- host_impl_.active_tree()->UpdateDrawProperties();
- PictureLayerTiling* high_res =
- active_layer_->tilings()->FindTilingWithScale(new_scale);
- ASSERT_TRUE(!!high_res);
- EXPECT_EQ(HIGH_RESOLUTION, high_res->resolution());
+ EXPECT_NE(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
+ EXPECT_FALSE(active_tiling->TileAt(0, 0)->is_shared());
+ EXPECT_FALSE(pending_tiling->TileAt(0, 0)->is_shared());
+ EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0));
+ EXPECT_TRUE(active_tiling->TileAt(1, 0)->is_shared());
+ EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1));
+ EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared());
+ EXPECT_EQ(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1));
+ EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared());
}
TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) {
- SetupDefaultTrees(gfx::Size(10, 10));
+ base::TimeTicks time_ticks;
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
- const float kScale = 1.f;
- pending_layer_->AddTiling(kScale);
- EXPECT_TRUE(pending_layer_->tilings()->FindTilingWithScale(kScale));
- EXPECT_TRUE(active_layer_->tilings()->FindTilingWithScale(kScale));
+ gfx::Size tile_size(100, 100);
+ gfx::Size layer_bounds(10, 10);
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+ SetupTrees(pending_pile, active_pile);
+
+ EXPECT_TRUE(pending_layer_->tilings()->FindTilingWithScale(1.f));
+ EXPECT_TRUE(active_layer_->tilings()->FindTilingWithScale(1.f));
// Gpu rasterization is disabled by default.
EXPECT_FALSE(host_impl_.use_gpu_rasterization());
@@ -2346,9 +2290,17 @@
// 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()->FindTilingWithScale(kScale));
- EXPECT_TRUE(active_layer_->tilings()->FindTilingWithScale(kScale));
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.pending_tree()->UpdateDrawProperties();
+ EXPECT_TRUE(pending_layer_->tilings()->FindTilingWithScale(1.f));
+
+ ActivateTree();
+ EXPECT_TRUE(active_layer_->tilings()->FindTilingWithScale(1.f));
+
+ SetupPendingTree(pending_pile);
+ EXPECT_TRUE(pending_layer_->tilings()->FindTilingWithScale(1.f));
// Toggling the gpu rasterization clears all tilings on both trees.
EXPECT_TRUE(host_impl_.use_gpu_rasterization());
@@ -2360,50 +2312,49 @@
TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) {
gfx::Size tile_size(100, 100);
- scoped_refptr<FakePicturePileImpl> active_pile =
- FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(10, 10));
- SetupPendingTree(active_pile);
- ActivateTree();
- host_impl_.active_tree()->UpdateDrawProperties();
- EXPECT_FALSE(host_impl_.active_tree()->needs_update_draw_properties());
+ // Put 0.5 as high res.
+ host_impl_.SetDeviceScaleFactor(0.5f);
- SetupDrawPropertiesAndUpdateTiles(
- active_layer_, 0.5f, 0.5f, 0.5f, 0.5f, false);
- active_layer_->tilings()->RemoveAllTilings();
- PictureLayerTiling* tiling = active_layer_->AddTiling(0.5f);
- active_layer_->AddTiling(1.5f);
- active_layer_->AddTiling(0.25f);
- tiling->set_resolution(HIGH_RESOLUTION);
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(10, 10));
+ SetupPendingTree(pending_pile);
// Sanity checks.
- ASSERT_EQ(3u, active_layer_->tilings()->num_tilings());
- ASSERT_EQ(tiling, active_layer_->tilings()->FindTilingWithScale(0.5f));
+ EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings());
+ EXPECT_TRUE(pending_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
- // commit initialization, since this is what would happen during commit. In
- // other words we want the pending layer to sync from the active layer.
- scoped_refptr<FakePicturePileImpl> pending_pile =
+ ActivateTree();
+
+ // Now, set the bounds to be 1x1, so that minimum contents scale becomes 1.
+ pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(1, 1));
SetupPendingTree(pending_pile);
- // Update the draw properties: sync from active tree should happen here.
- host_impl_.pending_tree()->UpdateDrawProperties();
- EXPECT_FALSE(pending_layer_->needs_post_commit_initialization());
-
// Another sanity check.
- ASSERT_EQ(1.f, pending_layer_->MinimumContentsScale());
+ EXPECT_EQ(1.f, pending_layer_->MinimumContentsScale());
- // Now we should've synced 1.5f tiling, since that's the only one that doesn't
- // violate minimum contents scale. At the same time, we should've created a
- // new high res tiling at scale 1.0f.
+ // Since the MinContentsScale is 1, the 0.5 tiling should be replaced by a 1.0
+ // tiling.
+ SetupDrawPropertiesAndUpdateTiles(pending_layer_, 0.5f, 1.f, 1.f, 1.f, false);
+
+ EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings());
+ PictureLayerTiling* tiling =
+ pending_layer_->tilings()->FindTilingWithScale(1.0f);
+ ASSERT_TRUE(tiling);
+ EXPECT_EQ(HIGH_RESOLUTION, tiling->resolution());
+}
+
+TEST_F(PictureLayerImplTest, LowResTilingWithoutGpuRasterization) {
+ gfx::Size default_tile_size(host_impl_.settings().default_tile_size);
+ gfx::Size layer_bounds(default_tile_size.width() * 4,
+ default_tile_size.height() * 4);
+
+ host_impl_.SetUseGpuRasterization(false);
+
+ SetupDefaultTrees(layer_bounds);
+ EXPECT_FALSE(host_impl_.use_gpu_rasterization());
+ // Should have a low-res and a high-res tiling.
EXPECT_EQ(2u, pending_layer_->tilings()->num_tilings());
- ASSERT_TRUE(pending_layer_->tilings()->FindTilingWithScale(1.0f));
- EXPECT_EQ(HIGH_RESOLUTION,
- pending_layer_->tilings()->FindTilingWithScale(1.0f)->resolution());
- ASSERT_TRUE(pending_layer_->tilings()->FindTilingWithScale(1.5f));
- EXPECT_EQ(NON_IDEAL_RESOLUTION,
- pending_layer_->tilings()->FindTilingWithScale(1.5f)->resolution());
}
TEST_F(PictureLayerImplTest, NoLowResTilingWithGpuRasterization) {
@@ -2411,21 +2362,12 @@
gfx::Size layer_bounds(default_tile_size.width() * 4,
default_tile_size.height() * 4);
- SetupDefaultTrees(layer_bounds);
- EXPECT_FALSE(host_impl_.use_gpu_rasterization());
- EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings());
- SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
- // Should have a low-res and a high-res tiling.
- ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings());
-
- ResetTilingsAndRasterScales();
-
host_impl_.SetUseGpuRasterization(true);
- EXPECT_TRUE(host_impl_.use_gpu_rasterization());
- SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
+ SetupDefaultTrees(layer_bounds);
+ EXPECT_TRUE(host_impl_.use_gpu_rasterization());
// Should only have the high-res tiling.
- ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings());
+ EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings());
}
TEST_F(PictureLayerImplTest, NoTilingIfDoesNotDrawContent) {
@@ -2450,31 +2392,38 @@
TEST_F(PictureLayerImplTest, FirstTilingDuringPinch) {
SetupDefaultTrees(gfx::Size(10, 10));
+
+ // We start with a tiling at scale 1.
+ EXPECT_EQ(1.f, pending_layer_->HighResTiling()->contents_scale());
+
+ // When we scale up by 2.3, we get a new tiling that is a power of 2, in this
+ // case 4.
host_impl_.PinchGestureBegin();
float high_res_scale = 2.3f;
SetContentsScaleOnBothLayers(high_res_scale, 1.f, 1.f, 1.f, false);
-
- ASSERT_GE(pending_layer_->num_tilings(), 0u);
- EXPECT_FLOAT_EQ(high_res_scale,
- pending_layer_->HighResTiling()->contents_scale());
-}
-
-TEST_F(PictureLayerImplTest, FirstTilingTooSmall) {
- SetupDefaultTrees(gfx::Size(10, 10));
- host_impl_.PinchGestureBegin();
- float high_res_scale = 0.0001f;
- EXPECT_GT(pending_layer_->MinimumContentsScale(), high_res_scale);
-
- SetContentsScaleOnBothLayers(high_res_scale, 1.f, 1.f, 1.f, false);
-
- ASSERT_GE(pending_layer_->num_tilings(), 0u);
- EXPECT_FLOAT_EQ(pending_layer_->MinimumContentsScale(),
- pending_layer_->HighResTiling()->contents_scale());
+ EXPECT_EQ(4.f, pending_layer_->HighResTiling()->contents_scale());
}
TEST_F(PictureLayerImplTest, PinchingTooSmall) {
SetupDefaultTrees(gfx::Size(10, 10));
+ // We start with a tiling at scale 1.
+ EXPECT_EQ(1.f, pending_layer_->HighResTiling()->contents_scale());
+
+ host_impl_.PinchGestureBegin();
+ float high_res_scale = 0.0001f;
+ EXPECT_LT(high_res_scale, pending_layer_->MinimumContentsScale());
+
+ SetContentsScaleOnBothLayers(high_res_scale, 1.f, high_res_scale, 1.f, false);
+ EXPECT_FLOAT_EQ(pending_layer_->MinimumContentsScale(),
+ pending_layer_->HighResTiling()->contents_scale());
+}
+
+TEST_F(PictureLayerImplTest, PinchingTooSmallWithContentsScale) {
+ SetupDefaultTrees(gfx::Size(10, 10));
+
+ ResetTilingsAndRasterScales();
+
float contents_scale = 0.15f;
SetContentsScaleOnBothLayers(contents_scale, 1.f, 1.f, 1.f, false);
@@ -2542,22 +2491,18 @@
}
TEST_F(PictureLayerImplTest, HighResTilingDuringAnimationForCpuRasterization) {
- gfx::Size layer_bounds(100, 100);
gfx::Size viewport_size(1000, 1000);
- SetupDefaultTrees(layer_bounds);
host_impl_.SetViewportSize(viewport_size);
+ gfx::Size layer_bounds(100, 100);
+ SetupDefaultTrees(layer_bounds);
+
float contents_scale = 1.f;
- float device_scale = 1.3f;
- float page_scale = 1.4f;
+ float device_scale = 1.f;
+ float page_scale = 1.f;
float maximum_animation_scale = 1.f;
bool animating_transform = false;
- SetContentsScaleOnBothLayers(contents_scale,
- device_scale,
- page_scale,
- maximum_animation_scale,
- animating_transform);
EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f);
// Since we're CPU-rasterizing, starting an animation should cause tiling
@@ -2781,6 +2726,8 @@
host_impl_.SetCurrentBeginFrameArgs(
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.SetViewportSize(gfx::Size(500, 500));
+
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
@@ -2788,24 +2735,10 @@
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupPendingTree(pending_pile);
+ EXPECT_EQ(2u, pending_layer_->num_tilings());
- ASSERT_TRUE(pending_layer_->CanHaveTilings());
-
- float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
-
- // No tilings.
scoped_ptr<TilingSetRasterQueue> queue =
pending_layer_->CreateRasterQueue(false);
- EXPECT_TRUE(queue->IsEmpty());
-
- pending_layer_->AddTiling(low_res_factor);
- pending_layer_->AddTiling(0.3f);
- pending_layer_->AddTiling(0.7f);
- PictureLayerTiling* high_res_tiling = pending_layer_->AddTiling(1.0f);
- pending_layer_->AddTiling(2.0f);
-
- host_impl_.SetViewportSize(gfx::Size(500, 500));
- host_impl_.pending_tree()->UpdateDrawProperties();
std::set<Tile*> unique_tiles;
bool reached_prepaint = false;
@@ -2883,7 +2816,8 @@
gfx::Rect(0, 0, 500, 500);
pending_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
- std::vector<Tile*> high_res_tiles = high_res_tiling->AllTilesForTesting();
+ std::vector<Tile*> high_res_tiles =
+ pending_layer_->HighResTiling()->AllTilesForTesting();
for (std::vector<Tile*>::iterator tile_it = high_res_tiles.begin();
tile_it != high_res_tiles.end();
++tile_it) {
@@ -2916,33 +2850,23 @@
TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) {
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
+ float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
+
+ host_impl_.SetViewportSize(gfx::Size(500, 500));
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ // TODO(vmpstr): Add a test with tilings other than high/low res on the active
+ // tree.
SetupPendingTree(pending_pile);
-
- ASSERT_TRUE(pending_layer_->CanHaveTilings());
-
- float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
-
- std::vector<PictureLayerTiling*> tilings;
- tilings.push_back(pending_layer_->AddTiling(low_res_factor));
- tilings.push_back(pending_layer_->AddTiling(0.3f));
- tilings.push_back(pending_layer_->AddTiling(0.7f));
- tilings.push_back(pending_layer_->AddTiling(1.0f));
- tilings.push_back(pending_layer_->AddTiling(2.0f));
-
- host_impl_.SetViewportSize(gfx::Size(500, 500));
- host_impl_.pending_tree()->UpdateDrawProperties();
+ EXPECT_EQ(2u, pending_layer_->num_tilings());
std::vector<Tile*> all_tiles;
- for (std::vector<PictureLayerTiling*>::iterator tiling_iterator =
- tilings.begin();
- tiling_iterator != tilings.end();
- ++tiling_iterator) {
- std::vector<Tile*> tiles = (*tiling_iterator)->AllTilesForTesting();
- std::copy(tiles.begin(), tiles.end(), std::back_inserter(all_tiles));
+ for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
+ PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
+ std::vector<Tile*> tiles = tiling->AllTilesForTesting();
+ all_tiles.insert(all_tiles.end(), tiles.begin(), tiles.end());
}
std::set<Tile*> all_tiles_set(all_tiles.begin(), all_tiles.end());
@@ -2950,8 +2874,8 @@
bool mark_required = false;
size_t number_of_marked_tiles = 0u;
size_t number_of_unmarked_tiles = 0u;
- for (size_t i = 0; i < tilings.size(); ++i) {
- PictureLayerTiling* tiling = tilings.at(i);
+ for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
+ PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
for (PictureLayerTiling::CoverageIterator iter(
tiling,
pending_layer_->contents_scale_x(),
@@ -2969,8 +2893,8 @@
}
// Sanity checks.
- EXPECT_EQ(91u, all_tiles.size());
- EXPECT_EQ(91u, all_tiles_set.size());
+ EXPECT_EQ(17u, all_tiles.size());
+ EXPECT_EQ(17u, all_tiles_set.size());
EXPECT_GT(number_of_marked_tiles, 1u);
EXPECT_GT(number_of_unmarked_tiles, 1u);
@@ -2982,10 +2906,12 @@
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles);
std::set<Tile*> unique_tiles;
- float expected_scales[] = {2.0f, 0.3f, 0.7f, low_res_factor, 1.0f};
+ float expected_scales[] = {low_res_factor, 1.f};
size_t scale_index = 0;
bool reached_visible = false;
Tile* last_tile = nullptr;
+ size_t distance_decreasing = 0;
+ size_t distance_increasing = 0;
queue = pending_layer_->CreateEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES);
while (!queue->IsEmpty()) {
Tile* tile = queue->Top();
@@ -3013,24 +2939,28 @@
EXPECT_FLOAT_EQ(tile->contents_scale(), expected_scales[scale_index]);
unique_tiles.insert(tile);
- // If the tile is the same rough bin as last tile (same activation, bin, and
- // scale), then distance should be decreasing.
if (tile->required_for_activation() ==
last_tile->required_for_activation() &&
priority.priority_bin ==
last_tile->priority(PENDING_TREE).priority_bin &&
std::abs(tile->contents_scale() - last_tile->contents_scale()) <
std::numeric_limits<float>::epsilon()) {
- EXPECT_LE(priority.distance_to_visible,
- last_tile->priority(PENDING_TREE).distance_to_visible);
+ if (priority.distance_to_visible <=
+ last_tile->priority(PENDING_TREE).distance_to_visible)
+ ++distance_decreasing;
+ else
+ ++distance_increasing;
}
last_tile = tile;
queue->Pop();
}
+ // 4 high res tiles are inside the viewport, the rest are evicted.
EXPECT_TRUE(reached_visible);
- EXPECT_EQ(65u, unique_tiles.size());
+ EXPECT_EQ(12u, unique_tiles.size());
+ EXPECT_EQ(1u, distance_increasing);
+ EXPECT_EQ(11u, distance_decreasing);
scale_index = 0;
bool reached_required = false;
@@ -3069,16 +2999,12 @@
gfx::Size viewport_size(1000, 1000);
LayerTestCommon::LayerImplTest impl;
+ host_impl_.SetViewportSize(viewport_size);
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(layer_bounds, layer_bounds);
- SetupPendingTree(pending_pile);
- pending_layer_->SetBounds(layer_bounds);
+ SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, Region());
ActivateTree();
- active_layer_->set_fixed_tile_size(tile_size);
-
- host_impl_.SetViewportSize(viewport_size);
- host_impl_.active_tree()->UpdateDrawProperties();
std::vector<Tile*> tiles =
active_layer_->HighResTiling()->AllTilesForTesting();
@@ -3121,6 +3047,8 @@
gfx::Size tile_size(host_impl_.settings().default_tile_size);
SetupDefaultTrees(tile_size);
+ ResetTilingsAndRasterScales();
+
float contents_scale = 2.f;
float device_scale = 1.f;
float page_scale = 1.f;
@@ -3161,15 +3089,9 @@
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
- host_impl_.SetViewportSize(layer_bounds);
-
- SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
-
// Make sure some tiles are not shared.
- pending_layer_->set_invalidation(gfx::Rect(gfx::Point(50, 50), tile_size));
-
- CreateHighLowResAndSetAllTilesVisible();
- active_layer_->SetAllTilesReady();
+ gfx::Rect invalidation(gfx::Point(50, 50), tile_size);
+ SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation);
// All pending layer tiles required are not ready.
EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
@@ -3190,15 +3112,9 @@
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
- host_impl_.SetViewportSize(layer_bounds);
-
- SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
-
// Make sure some tiles are not shared.
- pending_layer_->set_invalidation(gfx::Rect(gfx::Point(50, 50), tile_size));
-
- CreateHighLowResAndSetAllTilesVisible();
- active_layer_->SetAllTilesReady();
+ gfx::Rect invalidation(gfx::Point(50, 50), tile_size);
+ SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation);
// All pending layer tiles required are not ready.
EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
@@ -3215,14 +3131,9 @@
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
- host_impl_.SetViewportSize(layer_bounds);
-
- SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
-
// Make sure some tiles are not shared.
- pending_layer_->set_invalidation(gfx::Rect(gfx::Point(50, 50), tile_size));
-
- CreateHighLowResAndSetAllTilesVisible();
+ gfx::Rect invalidation(gfx::Point(50, 50), tile_size);
+ SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation);
// Initialize all high-res tiles in the active layer.
active_layer_->SetAllTilesReadyInTiling(active_layer_->HighResTiling());
@@ -3241,14 +3152,9 @@
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
- host_impl_.SetViewportSize(layer_bounds);
-
- SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
-
// Make sure some tiles are not shared.
- pending_layer_->set_invalidation(gfx::Rect(gfx::Point(50, 50), tile_size));
-
- CreateHighLowResAndSetAllTilesVisible();
+ gfx::Rect invalidation(gfx::Point(50, 50), tile_size);
+ SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation);
// Initialize all high-res tiles in the active layer.
active_layer_->SetAllTilesReadyInTiling(active_layer_->HighResTiling());
@@ -3261,12 +3167,6 @@
EXPECT_TRUE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
}
-class NoLowResPictureLayerImplTest : public PictureLayerImplTest {
- public:
- NoLowResPictureLayerImplTest()
- : PictureLayerImplTest(NoLowResTilingsSettings()) {}
-};
-
TEST_F(NoLowResPictureLayerImplTest, ManageTilingsCreatesTilings) {
gfx::Size tile_size(400, 400);
gfx::Size layer_bounds(1300, 1900);
@@ -3277,11 +3177,73 @@
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupTrees(pending_pile, active_pile);
- EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings());
float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
EXPECT_LT(low_res_factor, 1.f);
+ ResetTilingsAndRasterScales();
+
+ SetupDrawPropertiesAndUpdateTiles(active_layer_,
+ 6.f, // ideal contents scale
+ 3.f, // device scale
+ 2.f, // page scale
+ 1.f, // maximum animation scale
+ false);
+ ASSERT_EQ(1u, active_layer_->tilings()->num_tilings());
+ EXPECT_FLOAT_EQ(6.f,
+ active_layer_->tilings()->tiling_at(0)->contents_scale());
+
+ // If we change the page scale factor, then we should get new tilings.
+ SetupDrawPropertiesAndUpdateTiles(active_layer_,
+ 6.6f, // ideal contents scale
+ 3.f, // device scale
+ 2.2f, // page scale
+ 1.f, // maximum animation scale
+ false);
+ ASSERT_EQ(2u, active_layer_->tilings()->num_tilings());
+ EXPECT_FLOAT_EQ(6.6f,
+ active_layer_->tilings()->tiling_at(0)->contents_scale());
+
+ // If we change the device scale factor, then we should get new tilings.
+ SetupDrawPropertiesAndUpdateTiles(active_layer_,
+ 7.26f, // ideal contents scale
+ 3.3f, // device scale
+ 2.2f, // page scale
+ 1.f, // maximum animation scale
+ false);
+ ASSERT_EQ(3u, active_layer_->tilings()->num_tilings());
+ EXPECT_FLOAT_EQ(7.26f,
+ active_layer_->tilings()->tiling_at(0)->contents_scale());
+
+ // If we change the device scale factor, but end up at the same total scale
+ // factor somehow, then we don't get new tilings.
+ SetupDrawPropertiesAndUpdateTiles(active_layer_,
+ 7.26f, // ideal contents scale
+ 2.2f, // device scale
+ 3.3f, // page scale
+ 1.f, // maximum animation scale
+ false);
+ ASSERT_EQ(3u, active_layer_->tilings()->num_tilings());
+ EXPECT_FLOAT_EQ(7.26f,
+ active_layer_->tilings()->tiling_at(0)->contents_scale());
+}
+
+TEST_F(NoLowResPictureLayerImplTest, PendingLayerOnlyHasHighResTiling) {
+ gfx::Size tile_size(400, 400);
+ gfx::Size layer_bounds(1300, 1900);
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+ SetupTrees(pending_pile, active_pile);
+
+ float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
+ EXPECT_LT(low_res_factor, 1.f);
+
+ ResetTilingsAndRasterScales();
+
SetupDrawPropertiesAndUpdateTiles(pending_layer_,
6.f, // ideal contents scale
3.f, // device scale
@@ -3299,7 +3261,7 @@
2.2f, // page scale
1.f, // maximum animation scale
false);
- ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings());
+ ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings());
EXPECT_FLOAT_EQ(6.6f,
pending_layer_->tilings()->tiling_at(0)->contents_scale());
@@ -3310,7 +3272,7 @@
2.2f, // page scale
1.f, // maximum animation scale
false);
- ASSERT_EQ(3u, pending_layer_->tilings()->num_tilings());
+ ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings());
EXPECT_FLOAT_EQ(7.26f,
pending_layer_->tilings()->tiling_at(0)->contents_scale());
@@ -3322,7 +3284,7 @@
3.3f, // page scale
1.f, // maximum animation scale
false);
- ASSERT_EQ(3u, pending_layer_->tilings()->num_tilings());
+ ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings());
EXPECT_FLOAT_EQ(7.26f,
pending_layer_->tilings()->tiling_at(0)->contents_scale());
}
@@ -3331,11 +3293,7 @@
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
- host_impl_.SetViewportSize(layer_bounds);
-
- SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
-
- CreateHighLowResAndSetAllTilesVisible();
+ SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region());
Tile* some_active_tile =
active_layer_->HighResTiling()->AllTilesForTesting()[0];
@@ -3355,6 +3313,7 @@
TEST_F(NoLowResPictureLayerImplTest, NothingRequiredIfActiveMissingTiles) {
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
+
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
// This pile will create tilings, but has no recordings so will not create any
@@ -3364,11 +3323,8 @@
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateEmptyPileThatThinksItHasRecordings(
tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
- pending_layer_->set_fixed_tile_size(tile_size);
- active_layer_->set_fixed_tile_size(tile_size);
- CreateHighLowResAndSetAllTilesVisible();
+ SetupTreesWithFixedTileSize(pending_pile, active_pile, tile_size, Region());
// Active layer has tilings, but no tiles due to missing recordings.
EXPECT_TRUE(active_layer_->CanHaveTilings());
@@ -3401,10 +3357,8 @@
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
+ SetupTreesWithInvalidation(pending_pile, active_pile, Region());
- Region invalidation;
- AddDefaultTilingsWithInvalidation(invalidation);
SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, false);
// UpdateTiles with valid viewport. Should update tile viewport.
@@ -3484,7 +3438,6 @@
std::vector<PictureLayerTiling*> used_tilings;
SetupTrees(pending_pile, active_pile);
- EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings());
float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
EXPECT_LT(low_res_factor, 1.f);
@@ -3493,6 +3446,8 @@
float page_scale = 3.2f;
float scale = 1.f;
+ ResetTilingsAndRasterScales();
+
SetContentsScaleOnBothLayers(scale, device_scale, page_scale, 1.f, false);
ASSERT_EQ(1u, active_layer_->tilings()->num_tilings());
@@ -3578,80 +3533,6 @@
ASSERT_EQ(1u, active_layer_->tilings()->num_tilings());
}
-TEST_F(PictureLayerImplTest, ScaleCollision) {
- gfx::Size tile_size(400, 400);
- gfx::Size layer_bounds(1300, 1900);
-
- scoped_refptr<FakePicturePileImpl> pending_pile =
- FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- scoped_refptr<FakePicturePileImpl> active_pile =
- FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
-
- std::vector<PictureLayerTiling*> used_tilings;
-
- SetupTrees(pending_pile, active_pile);
-
- float pending_contents_scale = 1.f;
- float active_contents_scale = 2.f;
- float device_scale_factor = 1.f;
- float page_scale_factor = 1.f;
- float maximum_animation_contents_scale = 1.f;
- bool animating_transform = false;
-
- EXPECT_TRUE(host_impl_.settings().create_low_res_tiling);
- float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
- EXPECT_LT(low_res_factor, 1.f);
-
- SetupDrawPropertiesAndUpdateTiles(pending_layer_,
- pending_contents_scale,
- device_scale_factor,
- page_scale_factor,
- maximum_animation_contents_scale,
- animating_transform);
- SetupDrawPropertiesAndUpdateTiles(active_layer_,
- active_contents_scale,
- device_scale_factor,
- page_scale_factor,
- maximum_animation_contents_scale,
- animating_transform);
-
- ASSERT_EQ(4u, pending_layer_->tilings()->num_tilings());
- ASSERT_EQ(4u, active_layer_->tilings()->num_tilings());
-
- EXPECT_EQ(active_contents_scale,
- pending_layer_->tilings()->tiling_at(0)->contents_scale());
- EXPECT_EQ(pending_contents_scale,
- pending_layer_->tilings()->tiling_at(1)->contents_scale());
- EXPECT_EQ(active_contents_scale * low_res_factor,
- pending_layer_->tilings()->tiling_at(2)->contents_scale());
- EXPECT_EQ(pending_contents_scale * low_res_factor,
- pending_layer_->tilings()->tiling_at(3)->contents_scale());
-
- EXPECT_EQ(active_contents_scale,
- active_layer_->tilings()->tiling_at(0)->contents_scale());
- EXPECT_EQ(pending_contents_scale,
- active_layer_->tilings()->tiling_at(1)->contents_scale());
- EXPECT_EQ(active_contents_scale * low_res_factor,
- active_layer_->tilings()->tiling_at(2)->contents_scale());
- EXPECT_EQ(pending_contents_scale * low_res_factor,
- active_layer_->tilings()->tiling_at(3)->contents_scale());
-
- // The unused low res tiling from the pending tree must be kept or we may add
- // it again on the active tree and collide with the pending tree.
- used_tilings.push_back(active_layer_->tilings()->tiling_at(1));
- active_layer_->CleanUpTilingsOnActiveLayer(used_tilings);
- ASSERT_EQ(4u, active_layer_->tilings()->num_tilings());
-
- EXPECT_EQ(active_contents_scale,
- active_layer_->tilings()->tiling_at(0)->contents_scale());
- EXPECT_EQ(pending_contents_scale,
- active_layer_->tilings()->tiling_at(1)->contents_scale());
- EXPECT_EQ(active_contents_scale * low_res_factor,
- active_layer_->tilings()->tiling_at(2)->contents_scale());
- EXPECT_EQ(pending_contents_scale * low_res_factor,
- active_layer_->tilings()->tiling_at(3)->contents_scale());
-}
-
TEST_F(NoLowResPictureLayerImplTest, ReleaseResources) {
gfx::Size tile_size(400, 400);
gfx::Size layer_bounds(1300, 1900);
@@ -3662,15 +3543,8 @@
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupTrees(pending_pile, active_pile);
- EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings());
-
- SetupDrawPropertiesAndUpdateTiles(pending_layer_,
- 1.3f, // ideal contents scale
- 2.7f, // device scale
- 3.2f, // page scale
- 1.f, // maximum animation scale
- false);
EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings());
+ EXPECT_EQ(1u, active_layer_->tilings()->num_tilings());
// All tilings should be removed when losing output surface.
active_layer_->ReleaseResources();
@@ -3694,7 +3568,7 @@
gfx::Size tile_size(400, 400);
gfx::Size layer_bounds(1000, 2000);
- host_impl_.SetViewportSize(layer_bounds);
+ host_impl_.SetViewportSize(gfx::Size(10000, 20000));
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
@@ -3703,14 +3577,12 @@
SetupTrees(pending_pile, active_pile);
- SetupDrawPropertiesAndUpdateTiles(pending_layer_, 2.5f, 1.f, 1.f, 1.f, false);
- host_impl_.pending_tree()->UpdateDrawProperties();
-
- active_layer_->draw_properties().visible_content_rect =
- gfx::Rect(layer_bounds);
- host_impl_.active_tree()->UpdateDrawProperties();
+ ResetTilingsAndRasterScales();
+ SetupDrawPropertiesAndUpdateTiles(active_layer_, 2.5f, 1.f, 1.f, 1.f, false);
float max_contents_scale = active_layer_->MaximumTilingContentsScale();
+ EXPECT_EQ(2.5f, max_contents_scale);
+
gfx::Transform scaled_draw_transform = active_layer_->draw_transform();
scaled_draw_transform.Scale(SK_MScalar1 / max_contents_scale,
SK_MScalar1 / max_contents_scale);
@@ -3747,40 +3619,35 @@
scoped_ptr<FakePictureLayerImpl> layer_with_mask =
FakePictureLayerImpl::Create(host_impl_.pending_tree(), 2);
-
layer_with_mask->SetBounds(bounds);
layer_with_mask->SetContentBounds(bounds);
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, bounds);
scoped_ptr<FakePictureLayerImpl> mask =
- FakePictureLayerImpl::CreateWithRasterSource(host_impl_.pending_tree(), 3,
- pending_pile);
- mask->set_is_mask(true);
-
+ FakePictureLayerImpl::CreateMaskWithRasterSource(
+ host_impl_.pending_tree(), 3, pending_pile);
mask->SetBounds(bounds);
mask->SetContentBounds(bounds);
mask->SetDrawsContent(true);
-
- FakePictureLayerImpl* pending_mask_content = mask.get();
layer_with_mask->SetMaskLayer(mask.Pass());
+ FakePictureLayerImpl* pending_mask =
+ static_cast<FakePictureLayerImpl*>(layer_with_mask->mask_layer());
+
scoped_ptr<FakePictureLayerImpl> child_of_layer_with_mask =
FakePictureLayerImpl::Create(host_impl_.pending_tree(), 4);
-
child_of_layer_with_mask->SetBounds(bounds);
child_of_layer_with_mask->SetContentBounds(bounds);
child_of_layer_with_mask->SetDrawsContent(true);
-
layer_with_mask->AddChild(child_of_layer_with_mask.Pass());
-
root->AddChild(layer_with_mask.Pass());
host_impl_.pending_tree()->SetRootLayer(root.Pass());
- EXPECT_FALSE(pending_mask_content->tilings());
+ EXPECT_EQ(0u, pending_mask->num_tilings());
host_impl_.pending_tree()->UpdateDrawProperties();
- EXPECT_NE(0u, pending_mask_content->num_tilings());
+ EXPECT_NE(0u, pending_mask->num_tilings());
}
class PictureLayerImplTestWithDelegatingRenderer : public PictureLayerImplTest {
@@ -3804,7 +3671,6 @@
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupPendingTree(pending_pile);
pending_layer_->SetBounds(layer_bounds);
- host_impl_.SetViewportSize(layer_bounds);
ActivateTree();
host_impl_.active_tree()->UpdateDrawProperties();
std::vector<Tile*> tiles =
@@ -3851,14 +3717,17 @@
OcclusionTrackingPictureLayerImplTest()
: PictureLayerImplTest(OcclusionTrackingSettings()) {}
- void VerifyEvictionConsidersOcclusion(
- PictureLayerImpl* layer,
- size_t expected_occluded_tile_count[NUM_TREE_PRIORITIES]) {
+ void VerifyEvictionConsidersOcclusion(FakePictureLayerImpl* layer,
+ FakePictureLayerImpl* twin_layer,
+ WhichTree tree,
+ size_t expected_occluded_tile_count) {
+ WhichTree twin_tree = tree == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE;
for (int priority_count = 0; priority_count < NUM_TREE_PRIORITIES;
++priority_count) {
TreePriority tree_priority = static_cast<TreePriority>(priority_count);
size_t occluded_tile_count = 0u;
Tile* last_tile = nullptr;
+ std::set<Tile*> shared_tiles;
scoped_ptr<TilingSetEvictionQueue> queue =
layer->CreateEvictionQueue(tree_priority);
@@ -3866,23 +3735,22 @@
Tile* tile = queue->Top();
if (!last_tile)
last_tile = tile;
+ if (tile->is_shared())
+ EXPECT_TRUE(shared_tiles.insert(tile).second);
// The only way we will encounter an occluded tile after an unoccluded
// tile is if the priorty bin decreased, the tile is required for
// activation, or the scale changed.
- bool tile_is_occluded =
- tile->is_occluded_for_tree_priority(tree_priority);
+ bool tile_is_occluded = tile->is_occluded(tree);
if (tile_is_occluded) {
occluded_tile_count++;
- bool last_tile_is_occluded =
- last_tile->is_occluded_for_tree_priority(tree_priority);
+ bool last_tile_is_occluded = last_tile->is_occluded(tree);
if (!last_tile_is_occluded) {
TilePriority::PriorityBin tile_priority_bin =
- tile->priority_for_tree_priority(tree_priority).priority_bin;
+ tile->priority(tree).priority_bin;
TilePriority::PriorityBin last_tile_priority_bin =
- last_tile->priority_for_tree_priority(tree_priority)
- .priority_bin;
+ last_tile->priority(tree).priority_bin;
EXPECT_TRUE(
(tile_priority_bin < last_tile_priority_bin) ||
@@ -3893,8 +3761,74 @@
last_tile = tile;
queue->Pop();
}
- EXPECT_EQ(expected_occluded_tile_count[priority_count],
- occluded_tile_count);
+ // Count also shared tiles which are occluded in the tree but which were
+ // not returned by the tiling set eviction queue. Those shared tiles
+ // shall be returned by the twin tiling set eviction queue.
+ queue = twin_layer->CreateEvictionQueue(tree_priority);
+ while (!queue->IsEmpty()) {
+ Tile* tile = queue->Top();
+ if (tile->is_shared()) {
+ EXPECT_TRUE(shared_tiles.insert(tile).second);
+ if (tile->is_occluded(tree))
+ ++occluded_tile_count;
+ // Check the reasons why the shared tile was not returned by
+ // the first tiling set eviction queue.
+ switch (tree_priority) {
+ case SAME_PRIORITY_FOR_BOTH_TREES: {
+ const TilePriority& priority = tile->priority(tree);
+ const TilePriority& priority_for_tree_priority =
+ tile->priority_for_tree_priority(tree_priority);
+ const TilePriority& twin_priority = tile->priority(twin_tree);
+ // Check if the shared tile was not returned by the first tiling
+ // set eviction queue because it was out of order for the first
+ // tiling set eviction queue but not for the twin tiling set
+ // eviction queue.
+ if (priority.priority_bin != twin_priority.priority_bin) {
+ EXPECT_LT(priority_for_tree_priority.priority_bin,
+ priority.priority_bin);
+ EXPECT_EQ(priority_for_tree_priority.priority_bin,
+ twin_priority.priority_bin);
+ EXPECT_TRUE(priority_for_tree_priority.priority_bin <
+ priority.priority_bin);
+ } else if (tile->is_occluded(tree) !=
+ tile->is_occluded(twin_tree)) {
+ EXPECT_TRUE(tile->is_occluded(tree));
+ EXPECT_FALSE(tile->is_occluded(twin_tree));
+ EXPECT_FALSE(
+ tile->is_occluded_for_tree_priority(tree_priority));
+ } else if (priority.distance_to_visible !=
+ twin_priority.distance_to_visible) {
+ EXPECT_LT(priority_for_tree_priority.distance_to_visible,
+ priority.distance_to_visible);
+ EXPECT_EQ(priority_for_tree_priority.distance_to_visible,
+ twin_priority.distance_to_visible);
+ EXPECT_TRUE(priority_for_tree_priority.distance_to_visible <
+ priority.distance_to_visible);
+ } else {
+ // Shared tiles having the same active and pending priorities
+ // should be returned only by a pending tree eviction queue.
+ EXPECT_EQ(ACTIVE_TREE, tree);
+ }
+ break;
+ }
+ case SMOOTHNESS_TAKES_PRIORITY:
+ // Shared tiles should be returned only by an active tree
+ // eviction queue.
+ EXPECT_EQ(PENDING_TREE, tree);
+ break;
+ case NEW_CONTENT_TAKES_PRIORITY:
+ // Shared tiles should be returned only by a pending tree
+ // eviction queue.
+ EXPECT_EQ(ACTIVE_TREE, tree);
+ break;
+ case NUM_TREE_PRIORITIES:
+ NOTREACHED();
+ break;
+ }
+ }
+ queue->Pop();
+ }
+ EXPECT_EQ(expected_occluded_tile_count, occluded_tile_count);
}
}
};
@@ -3911,13 +3845,11 @@
gfx::Size viewport_size(500, 500);
gfx::Point occluding_layer_position(310, 0);
+ host_impl_.SetViewportSize(viewport_size);
+
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupPendingTree(pending_pile);
- pending_layer_->set_fixed_tile_size(tile_size);
-
- host_impl_.SetViewportSize(viewport_size);
- host_impl_.pending_tree()->UpdateDrawProperties();
+ SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, Region());
// No occlusion.
int unoccluded_tile_count = 0;
@@ -4004,13 +3936,11 @@
gfx::Size viewport_size(500, 500);
gfx::Point occluding_layer_position(310, 0);
+ host_impl_.SetViewportSize(viewport_size);
+
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupPendingTree(pending_pile);
- pending_layer_->set_fixed_tile_size(tile_size);
-
- host_impl_.SetViewportSize(viewport_size);
- host_impl_.pending_tree()->UpdateDrawProperties();
+ SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, Region());
// No occlusion.
int occluded_tile_count = 0;
@@ -4125,6 +4055,11 @@
}
TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) {
+ base::TimeTicks time_ticks;
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(1000, 1000);
gfx::Size viewport_size(500, 500);
@@ -4132,20 +4067,12 @@
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupPendingTree(pending_pile);
- pending_layer_->set_fixed_tile_size(tile_size);
+ host_impl_.SetViewportSize(viewport_size);
+
+ SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, Region());
ASSERT_TRUE(pending_layer_->CanHaveTilings());
- float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
-
- std::vector<PictureLayerTiling*> tilings;
- tilings.push_back(pending_layer_->AddTiling(low_res_factor));
- tilings.push_back(pending_layer_->AddTiling(0.3f));
- tilings.push_back(pending_layer_->AddTiling(0.7f));
- tilings.push_back(pending_layer_->AddTiling(1.0f));
- tilings.push_back(pending_layer_->AddTiling(2.0f));
-
pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 1));
LayerImpl* layer1 = pending_layer_->children()[0];
layer1->SetBounds(layer_bounds);
@@ -4154,49 +4081,56 @@
layer1->SetContentsOpaque(true);
layer1->SetPosition(occluding_layer_position);
- host_impl_.SetViewportSize(viewport_size);
+ pending_layer_->tilings()->RemoveAllTilings();
+ float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
+ pending_layer_->AddTiling(low_res_factor);
+ pending_layer_->AddTiling(0.3f);
+ pending_layer_->AddTiling(0.7f);
+ pending_layer_->AddTiling(1.0f);
+ pending_layer_->AddTiling(2.0f);
+
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ // UpdateDrawProperties with the occluding layer.
host_impl_.pending_tree()->UpdateDrawProperties();
- int tiling_count = 0;
+ EXPECT_EQ(5u, pending_layer_->num_tilings());
+
int occluded_tile_count = 0;
- for (std::vector<PictureLayerTiling*>::iterator tiling_iterator =
- tilings.begin();
- tiling_iterator != tilings.end();
- ++tiling_iterator) {
- (*tiling_iterator)->UpdateAllTilePrioritiesForTesting();
- std::vector<Tile*> tiles = (*tiling_iterator)->AllTilesForTesting();
+ for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
+ PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
+ tiling->UpdateAllTilePrioritiesForTesting();
+ std::vector<Tile*> tiles = tiling->AllTilesForTesting();
occluded_tile_count = 0;
- for (size_t i = 0; i < tiles.size(); ++i) {
- if (tiles[i]->is_occluded(PENDING_TREE)) {
+ for (size_t j = 0; j < tiles.size(); ++j) {
+ if (tiles[j]->is_occluded(PENDING_TREE)) {
gfx::Rect scaled_content_rect = ScaleToEnclosingRect(
- tiles[i]->content_rect(), 1.0f / tiles[i]->contents_scale());
+ tiles[j]->content_rect(), 1.0f / tiles[j]->contents_scale());
EXPECT_GE(scaled_content_rect.x(), occluding_layer_position.x());
occluded_tile_count++;
}
}
- switch (tiling_count) {
+
+ switch (i) {
case 0:
+ EXPECT_EQ(occluded_tile_count, 30);
+ break;
case 1:
- EXPECT_EQ(occluded_tile_count, 2);
+ EXPECT_EQ(occluded_tile_count, 5);
break;
case 2:
EXPECT_EQ(occluded_tile_count, 4);
break;
- case 3:
- EXPECT_EQ(occluded_tile_count, 5);
- break;
case 4:
- EXPECT_EQ(occluded_tile_count, 30);
+ case 3:
+ EXPECT_EQ(occluded_tile_count, 2);
break;
default:
NOTREACHED();
}
-
- tiling_count++;
}
-
- EXPECT_EQ(tiling_count, 5);
}
TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) {
@@ -4210,24 +4144,23 @@
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
+
+ host_impl_.SetViewportSize(viewport_size);
+ SetupPendingTree(active_pile);
// Partially occlude the active layer.
- active_layer_->AddChild(LayerImpl::Create(host_impl_.active_tree(), 2));
- LayerImpl* layer1 = active_layer_->children()[0];
+ pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 2));
+ LayerImpl* layer1 = pending_layer_->children()[0];
layer1->SetBounds(layer_bounds);
layer1->SetContentBounds(layer_bounds);
layer1->SetDrawsContent(true);
layer1->SetContentsOpaque(true);
layer1->SetPosition(occluding_layer_position);
+ ActivateTree();
+
// Partially invalidate the pending layer.
- pending_layer_->set_invalidation(invalidation_rect);
-
- host_impl_.SetViewportSize(viewport_size);
-
- active_layer_->CreateDefaultTilingsAndTiles();
- pending_layer_->CreateDefaultTilingsAndTiles();
+ SetupPendingTreeWithInvalidation(pending_pile, invalidation_rect);
for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
@@ -4306,36 +4239,45 @@
TEST_F(OcclusionTrackingPictureLayerImplTest,
OccludedTilesConsideredDuringEviction) {
+ base::TimeTicks time_ticks;
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(1000, 1000);
- gfx::Size viewport_size(500, 500);
+ gfx::Size viewport_size(1000, 1000);
gfx::Point pending_occluding_layer_position(310, 0);
gfx::Point active_occluding_layer_position(0, 310);
gfx::Rect invalidation_rect(230, 230, 102, 102);
+ host_impl_.SetViewportSize(viewport_size);
+ host_impl_.SetDeviceScaleFactor(2.f);
+
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupTrees(pending_pile, active_pile);
- pending_layer_->set_fixed_tile_size(tile_size);
- active_layer_->set_fixed_tile_size(tile_size);
+ SetupPendingTreeWithFixedTileSize(active_pile, tile_size, Region());
- float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
+ // Partially occlude the active layer.
+ pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 2));
+ LayerImpl* active_occluding_layer = pending_layer_->children()[0];
+ active_occluding_layer->SetBounds(layer_bounds);
+ active_occluding_layer->SetContentBounds(layer_bounds);
+ active_occluding_layer->SetDrawsContent(true);
+ active_occluding_layer->SetContentsOpaque(true);
+ active_occluding_layer->SetPosition(active_occluding_layer_position);
- std::vector<PictureLayerTiling*> tilings;
- tilings.push_back(pending_layer_->AddTiling(low_res_factor));
- tilings.push_back(pending_layer_->AddTiling(0.3f));
- tilings.push_back(pending_layer_->AddTiling(0.7f));
- tilings.push_back(pending_layer_->AddTiling(1.0f));
- tilings.push_back(pending_layer_->AddTiling(2.0f));
+ ActivateTree();
- EXPECT_EQ(5u, pending_layer_->num_tilings());
- EXPECT_EQ(5u, active_layer_->num_tilings());
+ // Partially invalidate the pending layer. Tiles inside the invalidation rect
+ // are not shared between trees.
+ SetupPendingTreeWithFixedTileSize(pending_pile, tile_size, invalidation_rect);
- // Partially occlude the pending layer.
- pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 1));
+ // Partially occlude the pending layer in a different way.
+ pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 3));
LayerImpl* pending_occluding_layer = pending_layer_->children()[0];
pending_occluding_layer->SetBounds(layer_bounds);
pending_occluding_layer->SetContentBounds(layer_bounds);
@@ -4343,52 +4285,38 @@
pending_occluding_layer->SetContentsOpaque(true);
pending_occluding_layer->SetPosition(pending_occluding_layer_position);
- // Partially occlude the active layer.
- active_layer_->AddChild(LayerImpl::Create(host_impl_.active_tree(), 2));
- LayerImpl* active_occluding_layer = active_layer_->children()[0];
- active_occluding_layer->SetBounds(layer_bounds);
- active_occluding_layer->SetContentBounds(layer_bounds);
- active_occluding_layer->SetDrawsContent(true);
- active_occluding_layer->SetContentsOpaque(true);
- active_occluding_layer->SetPosition(active_occluding_layer_position);
+ EXPECT_EQ(2u, pending_layer_->num_tilings());
+ EXPECT_EQ(2u, active_layer_->num_tilings());
- // Partially invalidate the pending layer. Tiles inside the invalidation rect
- // are not shared between trees.
- pending_layer_->set_invalidation(invalidation_rect);
-
- host_impl_.SetViewportSize(viewport_size);
- host_impl_.active_tree()->UpdateDrawProperties();
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ // UpdateDrawProperties with the occluding layer.
host_impl_.pending_tree()->UpdateDrawProperties();
- // The expected number of occluded tiles on each of the 5 tilings for each of
+ // The expected number of occluded tiles on each of the 2 tilings for each of
// the 3 tree priorities.
- size_t expected_occluded_tile_count_on_both[] = {9u, 1u, 1u, 1u, 1u};
- size_t expected_occluded_tile_count_on_active[] = {30u, 5u, 4u, 2u, 2u};
- size_t expected_occluded_tile_count_on_pending[] = {30u, 5u, 4u, 2u, 2u};
+ size_t expected_occluded_tile_count_on_both[] = {9u, 1u};
+ size_t expected_occluded_tile_count_on_active[] = {30u, 3u};
+ size_t expected_occluded_tile_count_on_pending[] = {30u, 3u};
- // The total expected number of occluded tiles on all tilings for each of the
- // 3 tree priorities.
- size_t total_expected_occluded_tile_count[] = {13u, 43u, 43u};
-
- ASSERT_EQ(arraysize(total_expected_occluded_tile_count), NUM_TREE_PRIORITIES);
+ size_t total_expected_occluded_tile_count_on_trees[] = {33u, 33u};
// Verify number of occluded tiles on the pending layer for each tiling.
for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
- tiling->CreateAllTilesForTesting();
tiling->UpdateAllTilePrioritiesForTesting();
size_t occluded_tile_count_on_pending = 0u;
size_t occluded_tile_count_on_active = 0u;
size_t occluded_tile_count_on_both = 0u;
- for (PictureLayerTiling::CoverageIterator iter(
- tiling,
- pending_layer_->contents_scale_x(),
- gfx::Rect(layer_bounds));
- iter;
- ++iter) {
+ for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f,
+ gfx::Rect(layer_bounds));
+ iter; ++iter) {
Tile* tile = *iter;
+ if (!tile)
+ continue;
if (tile->is_occluded(PENDING_TREE))
occluded_tile_count_on_pending++;
if (tile->is_occluded(ACTIVE_TREE))
@@ -4398,19 +4326,18 @@
}
EXPECT_EQ(expected_occluded_tile_count_on_pending[i],
occluded_tile_count_on_pending)
- << i;
+ << tiling->contents_scale();
EXPECT_EQ(expected_occluded_tile_count_on_active[i],
occluded_tile_count_on_active)
- << i;
+ << tiling->contents_scale();
EXPECT_EQ(expected_occluded_tile_count_on_both[i],
occluded_tile_count_on_both)
- << i;
+ << tiling->contents_scale();
}
// Verify number of occluded tiles on the active layer for each tiling.
for (size_t i = 0; i < active_layer_->num_tilings(); ++i) {
PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i);
- tiling->CreateAllTilesForTesting();
tiling->UpdateAllTilePrioritiesForTesting();
size_t occluded_tile_count_on_pending = 0u;
@@ -4424,6 +4351,8 @@
++iter) {
Tile* tile = *iter;
+ if (!tile)
+ continue;
if (tile->is_occluded(PENDING_TREE))
occluded_tile_count_on_pending++;
if (tile->is_occluded(ACTIVE_TREE))
@@ -4443,20 +4372,38 @@
}
std::vector<Tile*> all_tiles;
- for (std::vector<PictureLayerTiling*>::iterator tiling_iterator =
- tilings.begin();
- tiling_iterator != tilings.end();
- ++tiling_iterator) {
- std::vector<Tile*> tiles = (*tiling_iterator)->AllTilesForTesting();
- std::copy(tiles.begin(), tiles.end(), std::back_inserter(all_tiles));
+ for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
+ PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
+ std::vector<Tile*> tiles = tiling->AllTilesForTesting();
+ all_tiles.insert(all_tiles.end(), tiles.begin(), tiles.end());
}
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles);
- VerifyEvictionConsidersOcclusion(pending_layer_,
- total_expected_occluded_tile_count);
- VerifyEvictionConsidersOcclusion(active_layer_,
- total_expected_occluded_tile_count);
+ VerifyEvictionConsidersOcclusion(
+ pending_layer_, active_layer_, PENDING_TREE,
+ total_expected_occluded_tile_count_on_trees[PENDING_TREE]);
+ VerifyEvictionConsidersOcclusion(
+ active_layer_, pending_layer_, ACTIVE_TREE,
+ total_expected_occluded_tile_count_on_trees[ACTIVE_TREE]);
+
+ // Repeat the tests without valid active tree priorities.
+ active_layer_->set_has_valid_tile_priorities(false);
+ VerifyEvictionConsidersOcclusion(
+ pending_layer_, active_layer_, PENDING_TREE,
+ total_expected_occluded_tile_count_on_trees[PENDING_TREE]);
+ VerifyEvictionConsidersOcclusion(
+ active_layer_, pending_layer_, ACTIVE_TREE, 0u);
+ active_layer_->set_has_valid_tile_priorities(true);
+
+ // Repeat the tests without valid pending tree priorities.
+ pending_layer_->set_has_valid_tile_priorities(false);
+ VerifyEvictionConsidersOcclusion(
+ active_layer_, pending_layer_, ACTIVE_TREE,
+ total_expected_occluded_tile_count_on_trees[ACTIVE_TREE]);
+ VerifyEvictionConsidersOcclusion(
+ pending_layer_, active_layer_, PENDING_TREE, 0u);
+ pending_layer_->set_has_valid_tile_priorities(true);
}
TEST_F(PictureLayerImplTest, PendingOrActiveTwinLayer) {
@@ -4530,8 +4477,6 @@
host->SetRootLayer(layer);
RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
- host_impl_.SetViewportSize(layer_bounds);
-
int frame_number = 0;
client.set_fill_with_nonsolid_color(!test_for_solid);
@@ -4544,11 +4489,9 @@
scoped_refptr<RasterSource> pending_raster_source =
recording_source->CreateRasterSource();
- SetupPendingTree(pending_raster_source);
+ SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region());
ActivateTree();
- active_layer_->set_fixed_tile_size(tile_size);
- host_impl_.active_tree()->UpdateDrawProperties();
if (test_for_solid) {
EXPECT_EQ(0u, active_layer_->tilings()->num_tilings());
} else {
@@ -4597,8 +4540,6 @@
host->SetRootLayer(layer);
RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
- host_impl_.SetViewportSize(layer_bounds);
-
int frame_number = 0;
client.set_fill_with_nonsolid_color(true);
@@ -4696,6 +4637,66 @@
EXPECT_TRUE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
}
+TEST_F(PictureLayerImplTest, CloneMissingRecordings) {
+ gfx::Size tile_size(100, 100);
+ gfx::Size layer_bounds(400, 400);
+
+ scoped_refptr<FakePicturePileImpl> filled_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ scoped_refptr<FakePicturePileImpl> partial_pile =
+ FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
+ for (int i = 1; i < partial_pile->tiling().num_tiles_x(); ++i) {
+ for (int j = 1; j < partial_pile->tiling().num_tiles_y(); ++j)
+ partial_pile->AddRecordingAt(i, j);
+ }
+
+ SetupPendingTreeWithFixedTileSize(filled_pile, tile_size, Region());
+ ActivateTree();
+
+ PictureLayerTiling* pending_tiling = old_pending_layer_->HighResTiling();
+ PictureLayerTiling* active_tiling = active_layer_->HighResTiling();
+
+ // We should have all tiles in both tile sets.
+ EXPECT_EQ(5u * 5u, pending_tiling->AllTilesForTesting().size());
+ EXPECT_EQ(5u * 5u, active_tiling->AllTilesForTesting().size());
+
+ // Now put a partially-recorded pile on the pending tree (and invalidate
+ // everything, since the main thread PicturePile will invalidate dropped
+ // recordings). This will cause us to be missing some tiles.
+ SetupPendingTreeWithFixedTileSize(partial_pile, tile_size,
+ Region(gfx::Rect(layer_bounds)));
+ EXPECT_EQ(3u * 3u, pending_tiling->AllTilesForTesting().size());
+ EXPECT_FALSE(pending_tiling->TileAt(0, 0));
+ EXPECT_FALSE(pending_tiling->TileAt(1, 1));
+ EXPECT_TRUE(pending_tiling->TileAt(2, 2));
+
+ // Active is not affected yet.
+ EXPECT_EQ(5u * 5u, active_tiling->AllTilesForTesting().size());
+
+ // Activate the tree. The same tiles go missing on the active tree.
+ ActivateTree();
+ EXPECT_EQ(3u * 3u, active_tiling->AllTilesForTesting().size());
+ EXPECT_FALSE(active_tiling->TileAt(0, 0));
+ EXPECT_FALSE(active_tiling->TileAt(1, 1));
+ EXPECT_TRUE(active_tiling->TileAt(2, 2));
+
+ // Now put a full recording on the pending tree again. We'll get all our tiles
+ // back.
+ SetupPendingTreeWithFixedTileSize(filled_pile, tile_size,
+ Region(gfx::Rect(layer_bounds)));
+ EXPECT_EQ(5u * 5u, pending_tiling->AllTilesForTesting().size());
+
+ // Active is not affected yet.
+ EXPECT_EQ(3u * 3u, active_tiling->AllTilesForTesting().size());
+
+ // Activate the tree. The tiles are created and shared on the active tree.
+ ActivateTree();
+ EXPECT_EQ(5u * 5u, active_tiling->AllTilesForTesting().size());
+ EXPECT_TRUE(active_tiling->TileAt(0, 0)->is_shared());
+ EXPECT_TRUE(active_tiling->TileAt(1, 1)->is_shared());
+ EXPECT_TRUE(active_tiling->TileAt(2, 2)->is_shared());
+}
+
class TileSizeSettings : public ImplSidePaintingSettings {
public:
TileSizeSettings() {
diff --git a/cc/layers/texture_layer_impl.cc b/cc/layers/texture_layer_impl.cc
index b174348..6e9cea1 100644
--- a/cc/layers/texture_layer_impl.cc
+++ b/cc/layers/texture_layer_impl.cc
@@ -111,8 +111,7 @@
if (texture_copy_->id()) {
std::vector<uint8> swizzled;
- uint8* pixels =
- static_cast<uint8*>(texture_mailbox_.shared_memory()->memory());
+ uint8* pixels = texture_mailbox_.shared_bitmap()->pixels();
if (!PlatformColor::SameComponentOrder(texture_copy_->format())) {
// Swizzle colors. This is slow, but should be really uncommon.
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc
index 4e2f675..f2dbb33 100644
--- a/cc/layers/texture_layer_unittest.cc
+++ b/cc/layers/texture_layer_unittest.cc
@@ -101,7 +101,7 @@
uint32 sync_point,
bool lost_resource));
MOCK_METHOD3(Release2,
- void(base::SharedMemory* shared_memory,
+ void(SharedBitmap* shared_bitmap,
uint32 sync_point,
bool lost_resource));
MOCK_METHOD4(ReleaseImpl,
@@ -110,19 +110,18 @@
bool lost_resource,
BlockingTaskRunner* main_thread_task_runner));
MOCK_METHOD4(ReleaseImpl2,
- void(base::SharedMemory* shared_memory,
+ void(SharedBitmap* shared_bitmap,
uint32 sync_point,
bool lost_resource,
BlockingTaskRunner* main_thread_task_runner));
};
struct CommonMailboxObjects {
- CommonMailboxObjects()
+ explicit CommonMailboxObjects(SharedBitmapManager* manager)
: mailbox_name1_(MailboxFromChar('1')),
mailbox_name2_(MailboxFromChar('2')),
sync_point1_(1),
- sync_point2_(2),
- shared_memory_(new base::SharedMemory) {
+ sync_point2_(2) {
release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
base::Unretained(&mock_callback_),
mailbox_name1_);
@@ -140,14 +139,15 @@
mailbox1_ = TextureMailbox(mailbox_name1_, arbitrary_target1, sync_point1_);
mailbox2_ = TextureMailbox(mailbox_name2_, arbitrary_target2, sync_point2_);
gfx::Size size(128, 128);
- EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea()));
- release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2,
- base::Unretained(&mock_callback_),
- shared_memory_.get());
- release_mailbox3_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl2,
- base::Unretained(&mock_callback_),
- shared_memory_.get());
- mailbox3_ = TextureMailbox(shared_memory_.get(), size);
+ shared_bitmap_ = manager->AllocateSharedBitmap(size);
+ DCHECK(shared_bitmap_);
+ release_mailbox3_ =
+ base::Bind(&MockMailboxCallback::Release2,
+ base::Unretained(&mock_callback_), shared_bitmap_.get());
+ release_mailbox3_impl_ =
+ base::Bind(&MockMailboxCallback::ReleaseImpl2,
+ base::Unretained(&mock_callback_), shared_bitmap_.get());
+ mailbox3_ = TextureMailbox(shared_bitmap_.get(), size);
}
gpu::Mailbox mailbox_name1_;
@@ -164,7 +164,7 @@
TextureMailbox mailbox3_;
uint32 sync_point1_;
uint32 sync_point2_;
- scoped_ptr<base::SharedMemory> shared_memory_;
+ scoped_ptr<SharedBitmap> shared_bitmap_;
};
class TextureLayerTest : public testing::Test {
@@ -172,7 +172,8 @@
TextureLayerTest()
: fake_client_(
FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
- host_impl_(&proxy_, &shared_bitmap_manager_) {}
+ host_impl_(&proxy_, &shared_bitmap_manager_),
+ test_data_(&shared_bitmap_manager_) {}
protected:
virtual void SetUp() {
@@ -195,6 +196,7 @@
FakeLayerTreeHostClient fake_client_;
TestSharedBitmapManager shared_bitmap_manager_;
FakeLayerTreeHostImpl host_impl_;
+ CommonMailboxObjects test_data_;
};
TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
@@ -309,8 +311,6 @@
false)).Times(1);
TextureLayerTest::TearDown();
}
-
- CommonMailboxObjects test_data_;
};
TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
@@ -359,9 +359,7 @@
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
EXPECT_CALL(test_data_.mock_callback_,
- Release2(test_data_.shared_memory_.get(),
- 0, false))
- .Times(1);
+ Release2(test_data_.shared_bitmap_.get(), 0, false)).Times(1);
test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
@@ -452,7 +450,6 @@
main_ref_;
base::Thread main_thread_;
scoped_ptr<BlockingTaskRunner> main_thread_task_runner_;
- CommonMailboxObjects test_data_;
};
TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
@@ -946,7 +943,6 @@
return will_draw;
}
- CommonMailboxObjects test_data_;
FakeLayerTreeHostClient fake_client_;
};
@@ -958,7 +954,7 @@
ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
.Times(AnyNumber());
EXPECT_CALL(test_data_.mock_callback_,
- ReleaseImpl2(test_data_.shared_memory_.get(), 0, false, _))
+ ReleaseImpl2(test_data_.shared_bitmap_.get(), 0, false, _))
.Times(AnyNumber());
// Hardware mode.
{
diff --git a/cc/layers/tiled_layer_impl.cc b/cc/layers/tiled_layer_impl.cc
index c66e124..a36c030 100644
--- a/cc/layers/tiled_layer_impl.cc
+++ b/cc/layers/tiled_layer_impl.cc
@@ -262,7 +262,8 @@
tile->resource_id(),
tex_coord_rect,
texture_size,
- tile->contents_swizzled());
+ tile->contents_swizzled(),
+ false);
}
}
}
diff --git a/cc/layers/tiled_layer_unittest.cc b/cc/layers/tiled_layer_unittest.cc
index a9a1e78..b4ee30f 100644
--- a/cc/layers/tiled_layer_unittest.cc
+++ b/cc/layers/tiled_layer_unittest.cc
@@ -45,18 +45,10 @@
}
};
-class SynchronousOutputSurfaceLayerTreeHost : public LayerTreeHost {
+class SynchronousOutputSurfaceClient : public FakeLayerTreeHostClient {
public:
- static scoped_ptr<SynchronousOutputSurfaceLayerTreeHost> Create(
- LayerTreeHostClient* client,
- SharedBitmapManager* manager,
- const LayerTreeSettings& settings,
- scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
- return make_scoped_ptr(new SynchronousOutputSurfaceLayerTreeHost(
- client, manager, settings, impl_task_runner));
- }
-
- ~SynchronousOutputSurfaceLayerTreeHost() override {}
+ SynchronousOutputSurfaceClient()
+ : FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D) {}
bool EnsureOutputSurfaceCreated() {
base::MessageLoop::current()->PostDelayedTask(
@@ -67,25 +59,19 @@
return output_surface_created_;
}
- void OnCreateAndInitializeOutputSurfaceAttempted(bool success) override {
- LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(success);
- output_surface_created_ = success;
+ void DidInitializeOutputSurface() override {
+ FakeLayerTreeHostClient::DidInitializeOutputSurface();
+ output_surface_created_ = true;
+ run_loop_.Quit();
+ }
+
+ void DidFailToInitializeOutputSurface() override {
+ FakeLayerTreeHostClient::DidFailToInitializeOutputSurface();
+ output_surface_created_ = false;
run_loop_.Quit();
}
private:
- SynchronousOutputSurfaceLayerTreeHost(
- LayerTreeHostClient* client,
- SharedBitmapManager* manager,
- const LayerTreeSettings& settings,
- scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner)
- : LayerTreeHost(client, manager, NULL, settings),
- output_surface_created_(false) {
- LayerTreeHost::InitializeThreaded(base::MessageLoopProxy::current(),
- impl_task_runner,
- nullptr);
- }
-
bool output_surface_created_;
base::RunLoop run_loop_;
};
@@ -97,7 +83,6 @@
output_surface_(FakeOutputSurface::Create3d()),
queue_(make_scoped_ptr(new ResourceUpdateQueue)),
impl_thread_("ImplThread"),
- fake_layer_tree_host_client_(FakeLayerTreeHostClient::DIRECT_3D),
occlusion_(nullptr) {
settings_.max_partial_texture_updates = std::numeric_limits<size_t>::max();
settings_.layer_transforms_should_scale_layer_contents = true;
@@ -106,16 +91,16 @@
void SetUp() override {
impl_thread_.Start();
shared_bitmap_manager_.reset(new TestSharedBitmapManager());
- layer_tree_host_ = SynchronousOutputSurfaceLayerTreeHost::Create(
- &fake_layer_tree_host_client_,
- shared_bitmap_manager_.get(),
- settings_,
- impl_thread_.message_loop_proxy());
- fake_layer_tree_host_client_.SetLayerTreeHost(layer_tree_host_.get());
+ layer_tree_host_ = LayerTreeHost::CreateThreaded(
+ &synchonous_output_surface_client_, shared_bitmap_manager_.get(),
+ nullptr, settings_, base::MessageLoopProxy::current(),
+ impl_thread_.message_loop_proxy(), nullptr);
+ synchonous_output_surface_client_.SetLayerTreeHost(layer_tree_host_.get());
proxy_ = layer_tree_host_->proxy();
resource_manager_ = PrioritizedResourceManager::Create(proxy_);
layer_tree_host_->SetLayerTreeHostClientReady();
- CHECK(layer_tree_host_->EnsureOutputSurfaceCreated());
+ CHECK(synchonous_output_surface_client_.EnsureOutputSurfaceCreated());
+
layer_tree_host_->SetRootLayer(Layer::Create());
CHECK(output_surface_->BindToClient(&output_surface_client_));
@@ -253,8 +238,8 @@
scoped_ptr<ResourceUpdateQueue> queue_;
PriorityCalculator priority_calculator_;
base::Thread impl_thread_;
- FakeLayerTreeHostClient fake_layer_tree_host_client_;
- scoped_ptr<SynchronousOutputSurfaceLayerTreeHost> layer_tree_host_;
+ SynchronousOutputSurfaceClient synchonous_output_surface_client_;
+ scoped_ptr<LayerTreeHost> layer_tree_host_;
scoped_ptr<FakeLayerTreeHostImpl> host_impl_;
scoped_ptr<PrioritizedResourceManager> resource_manager_;
TestOcclusionTracker* occlusion_;
diff --git a/cc/output/delegating_renderer_unittest.cc b/cc/output/delegating_renderer_unittest.cc
index fffa0ac..b72c76b 100644
--- a/cc/output/delegating_renderer_unittest.cc
+++ b/cc/output/delegating_renderer_unittest.cc
@@ -17,7 +17,7 @@
DelegatingRendererTest() : LayerTreeTest(), output_surface_(NULL) {}
virtual ~DelegatingRendererTest() {}
- scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) override {
+ scoped_ptr<OutputSurface> CreateOutputSurface() override {
scoped_ptr<FakeOutputSurface> output_surface =
FakeOutputSurface::CreateDelegating3d();
output_surface_ = output_surface.get();
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index 13cda6e..7896bb8 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -154,8 +154,6 @@
public:
static scoped_ptr<ScopedUseGrContext> Create(GLRenderer* renderer,
DrawingFrame* frame) {
- if (!renderer->output_surface_->context_provider()->GrContext())
- return nullptr;
return make_scoped_ptr(new ScopedUseGrContext(renderer, frame));
}
@@ -1627,7 +1625,8 @@
SetupQuadForAntialiasing(device_transform, quad, &local_quad, edge);
ResourceProvider::ScopedSamplerGL quad_resource_lock(
- resource_provider_, resource_id, GL_LINEAR);
+ resource_provider_, resource_id,
+ quad->nearest_neighbor ? GL_NEAREST : GL_LINEAR);
SamplerType sampler =
SamplerTypeFromTextureTarget(quad_resource_lock.target());
@@ -1711,7 +1710,8 @@
bool scaled = (tex_to_geom_scale_x != 1.f || tex_to_geom_scale_y != 1.f);
GLenum filter =
- (scaled || !quad->quadTransform().IsIdentityOrIntegerTranslation())
+ (scaled || !quad->quadTransform().IsIdentityOrIntegerTranslation()) &&
+ !quad->nearest_neighbor
? GL_LINEAR
: GL_NEAREST;
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
index cb14db3..58205a9 100644
--- a/cc/output/renderer_pixeltest.cc
+++ b/cc/output/renderer_pixeltest.cc
@@ -1384,6 +1384,7 @@
gfx::Rect viewport(this->device_viewport_size_);
// TODO(enne): the renderer should figure this out on its own.
ResourceFormat texture_format = RGBA_8888;
+ bool nearest_neighbor = false;
RenderPassId id(1, 1);
gfx::Transform transform_to_root;
@@ -1420,8 +1421,8 @@
blue_quad->SetNew(blue_shared_state,
viewport, // Intentionally bigger than clip.
gfx::Rect(), viewport, gfx::RectF(viewport),
- viewport.size(), texture_format, viewport, 1.f,
- blue_pile.get());
+ viewport.size(), nearest_neighbor, texture_format, viewport,
+ 1.f, blue_pile.get());
// One viewport-filling green quad.
scoped_refptr<FakePicturePileImpl> green_pile =
@@ -1439,7 +1440,8 @@
pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(),
- texture_format, viewport, 1.f, green_pile.get());
+ nearest_neighbor, texture_format, viewport, 1.f,
+ green_pile.get());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -1455,6 +1457,7 @@
gfx::Size pile_tile_size(1000, 1000);
gfx::Rect viewport(this->device_viewport_size_);
ResourceFormat texture_format = RGBA_8888;
+ bool nearest_neighbor = false;
RenderPassId id(1, 1);
gfx::Transform transform_to_root;
@@ -1477,8 +1480,8 @@
PictureDrawQuad* green_quad =
pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
- gfx::RectF(0, 0, 1, 1), viewport.size(), texture_format,
- viewport, 1.f, green_pile.get());
+ gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
+ texture_format, viewport, 1.f, green_pile.get());
// One viewport-filling white quad.
scoped_refptr<FakePicturePileImpl> white_pile =
@@ -1495,8 +1498,8 @@
PictureDrawQuad* white_quad =
pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
white_quad->SetNew(white_shared_state, viewport, gfx::Rect(), viewport,
- gfx::RectF(0, 0, 1, 1), viewport.size(), texture_format,
- viewport, 1.f, white_pile.get());
+ gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
+ texture_format, viewport, 1.f, white_pile.get());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -1532,6 +1535,7 @@
gfx::Size pile_tile_size(1000, 1000);
gfx::Rect viewport(this->device_viewport_size_);
ResourceFormat texture_format = RGBA_8888;
+ bool nearest_neighbor = false;
RenderPassId id(1, 1);
gfx::Transform transform_to_root;
@@ -1562,8 +1566,8 @@
PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
- gfx::RectF(0, 0, 2, 2), viewport.size(), texture_format,
- viewport, 1.f, pile.get());
+ gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
+ texture_format, viewport, 1.f, pile.get());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -1576,11 +1580,118 @@
ExactPixelComparator(true)));
}
+// This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad.
+TYPED_TEST(RendererPixelTest, PictureDrawQuadNearestNeighbor) {
+ gfx::Size pile_tile_size(1000, 1000);
+ gfx::Rect viewport(this->device_viewport_size_);
+ ResourceFormat texture_format = RGBA_8888;
+ bool nearest_neighbor = true;
+
+ RenderPassId id(1, 1);
+ gfx::Transform transform_to_root;
+ scoped_ptr<RenderPass> pass =
+ CreateTestRenderPass(id, viewport, transform_to_root);
+
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(2, 2);
+ {
+ SkAutoLockPixels lock(bitmap);
+ SkCanvas canvas(bitmap);
+ canvas.drawPoint(0, 0, SK_ColorGREEN);
+ canvas.drawPoint(0, 1, SK_ColorBLUE);
+ canvas.drawPoint(1, 0, SK_ColorBLUE);
+ canvas.drawPoint(1, 1, SK_ColorGREEN);
+ }
+
+ scoped_refptr<FakePicturePileImpl> pile =
+ FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size());
+ SkPaint paint;
+ paint.setFilterLevel(SkPaint::kLow_FilterLevel);
+ pile->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
+ pile->RerecordPile();
+
+ gfx::Transform content_to_target_transform;
+ SharedQuadState* shared_state = CreateTestSharedQuadState(
+ content_to_target_transform, viewport, pass.get());
+
+ PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
+ quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
+ gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
+ texture_format, viewport, 1.f, pile.get());
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ EXPECT_TRUE(this->RunPixelTest(
+ &pass_list,
+ base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
+ ExactPixelComparator(true)));
+}
+
+// This disables filtering by setting |nearest_neighbor| on the TileDrawQuad.
+TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) {
+ gfx::Rect viewport(this->device_viewport_size_);
+ bool swizzle_contents = true;
+ bool nearest_neighbor = true;
+
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(2, 2);
+ {
+ SkAutoLockPixels lock(bitmap);
+ SkCanvas canvas(bitmap);
+ canvas.drawPoint(0, 0, SK_ColorGREEN);
+ canvas.drawPoint(0, 1, SK_ColorBLUE);
+ canvas.drawPoint(1, 0, SK_ColorBLUE);
+ canvas.drawPoint(1, 1, SK_ColorGREEN);
+ }
+
+ gfx::Size tile_size(2, 2);
+ ResourceProvider::ResourceId resource =
+ this->resource_provider_->CreateResource(
+ tile_size,
+ GL_CLAMP_TO_EDGE,
+ ResourceProvider::TextureHintImmutable,
+ RGBA_8888);
+
+ {
+ SkAutoLockPixels lock(bitmap);
+ this->resource_provider_->SetPixels(
+ resource,
+ static_cast<uint8_t*>(bitmap.getPixels()),
+ gfx::Rect(tile_size),
+ gfx::Rect(tile_size),
+ gfx::Vector2d());
+ }
+
+ RenderPassId id(1, 1);
+ gfx::Transform transform_to_root;
+ scoped_ptr<RenderPass> pass =
+ CreateTestRenderPass(id, viewport, transform_to_root);
+
+ gfx::Transform content_to_target_transform;
+ SharedQuadState* shared_state = CreateTestSharedQuadState(
+ content_to_target_transform, viewport, pass.get());
+
+ TileDrawQuad* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>();
+ quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource,
+ gfx::Rect(tile_size), tile_size, swizzle_contents,
+ nearest_neighbor);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ EXPECT_TRUE(this->RunPixelTest(
+ &pass_list,
+ base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
+ ExactPixelComparator(true)));
+}
+
TYPED_TEST(RendererPixelTest, PictureDrawQuadNonIdentityScale) {
gfx::Size pile_tile_size(1000, 1000);
gfx::Rect viewport(this->device_viewport_size_);
// TODO(enne): the renderer should figure this out on its own.
ResourceFormat texture_format = RGBA_8888;
+ bool nearest_neighbor = false;
RenderPassId id(1, 1);
gfx::Transform transform_to_root;
@@ -1613,15 +1724,15 @@
pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
green_quad1->SetNew(top_right_green_shared_quad_state, green_rect1,
gfx::Rect(), green_rect1, gfx::RectF(green_rect1.size()),
- green_rect1.size(), texture_format, green_rect1, 1.f,
- green_pile.get());
+ green_rect1.size(), nearest_neighbor, texture_format,
+ green_rect1, 1.f, green_pile.get());
PictureDrawQuad* green_quad2 =
pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
green_quad2->SetNew(top_right_green_shared_quad_state, green_rect2,
gfx::Rect(), green_rect2, gfx::RectF(green_rect2.size()),
- green_rect2.size(), texture_format, green_rect2, 1.f,
- green_pile.get());
+ green_rect2.size(), nearest_neighbor, texture_format,
+ green_rect2, 1.f, green_pile.get());
// Add a green clipped checkerboard in the bottom right to help test
// interleaving picture quad content and solid color content.
@@ -1689,7 +1800,7 @@
PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
blue_quad->SetNew(blue_shared_state, quad_content_rect, gfx::Rect(),
quad_content_rect, gfx::RectF(quad_content_rect),
- content_union_rect.size(), texture_format,
+ content_union_rect.size(), nearest_neighbor, texture_format,
content_union_rect, contents_scale, pile.get());
// Fill left half of viewport with green.
@@ -1874,6 +1985,7 @@
gfx::Size pile_tile_size(1000, 1000);
gfx::Rect viewport(this->device_viewport_size_);
ResourceFormat texture_format = RGBA_4444;
+ bool nearest_neighbor = false;
RenderPassId id(1, 1);
gfx::Transform transform_to_root;
@@ -1895,7 +2007,8 @@
PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
blue_quad->SetNew(blue_shared_state, viewport, gfx::Rect(), viewport,
gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(),
- texture_format, viewport, 1.f, blue_pile.get());
+ nearest_neighbor, texture_format, viewport, 1.f,
+ blue_pile.get());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
diff --git a/cc/output/shader.cc b/cc/output/shader.cc
index e22e446..5bc7044 100644
--- a/cc/output/shader.cc
+++ b/cc/output/shader.cc
@@ -695,14 +695,14 @@
// clang-format off
static const std::string kFunctionApplyBlendMode = SHADER0(
// clang-format on
- uniform SamplerType s_backdropTexture;
+ uniform sampler2D s_backdropTexture;
uniform TexCoordPrecision vec4 backdropRect;
vec4 GetBackdropColor() {
TexCoordPrecision vec2 bgTexCoord = gl_FragCoord.xy - backdropRect.xy;
bgTexCoord.x /= backdropRect.z;
bgTexCoord.y /= backdropRect.w;
- return TextureLookup(s_backdropTexture, bgTexCoord);
+ return texture2D(s_backdropTexture, bgTexCoord);
}
vec4 ApplyBlendMode(vec4 src) {
diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc
index ddd3473..1b18648 100644
--- a/cc/output/software_renderer.cc
+++ b/cc/output/software_renderer.cc
@@ -347,7 +347,8 @@
// (http://crbug.com/280374).
skia::RefPtr<SkDrawFilter> opacity_filter =
skia::AdoptRef(new skia::OpacityDrawFilter(
- quad->opacity(), frame->disable_picture_quad_image_filtering));
+ quad->opacity(), frame->disable_picture_quad_image_filtering ||
+ quad->nearest_neighbor));
DCHECK(!current_canvas_->getDrawFilter());
current_canvas_->setDrawFilter(opacity_filter.get());
@@ -449,7 +450,9 @@
QuadVertexRect(), quad->rect, quad->visible_rect);
SkRect uv_rect = gfx::RectFToSkRect(visible_tex_coord_rect);
- current_paint_.setFilterLevel(SkPaint::kLow_FilterLevel);
+ current_paint_.setFilterLevel(quad->nearest_neighbor
+ ? SkPaint::kNone_FilterLevel
+ : SkPaint::kLow_FilterLevel);
current_canvas_->drawBitmapRectToRect(
*lock.sk_bitmap(),
&uv_rect,
diff --git a/cc/output/software_renderer_unittest.cc b/cc/output/software_renderer_unittest.cc
index ea584ee..7f689a8 100644
--- a/cc/output/software_renderer_unittest.cc
+++ b/cc/output/software_renderer_unittest.cc
@@ -211,6 +211,7 @@
resource_cyan,
gfx::RectF(inner_size),
inner_size,
+ false,
false);
TileDrawQuad* outer_quad =
root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
@@ -221,6 +222,7 @@
resource_yellow,
gfx::RectF(outer_size),
outer_size,
+ false,
false);
RenderPassList list;
@@ -294,6 +296,7 @@
resource_cyan,
gfx::RectF(tile_size),
tile_size,
+ false,
false);
quad->visible_rect = visible_rect;
diff --git a/cc/quads/content_draw_quad_base.cc b/cc/quads/content_draw_quad_base.cc
index fd6e91b..7304498 100644
--- a/cc/quads/content_draw_quad_base.cc
+++ b/cc/quads/content_draw_quad_base.cc
@@ -25,13 +25,15 @@
const gfx::Rect& visible_rect,
const gfx::RectF& tex_coord_rect,
const gfx::Size& texture_size,
- bool swizzle_contents) {
+ bool swizzle_contents,
+ bool nearest_neighbor) {
bool needs_blending = false;
DrawQuad::SetAll(shared_quad_state, material, rect, opaque_rect,
visible_rect, needs_blending);
this->tex_coord_rect = tex_coord_rect;
this->texture_size = texture_size;
this->swizzle_contents = swizzle_contents;
+ this->nearest_neighbor = nearest_neighbor;
}
void ContentDrawQuadBase::SetAll(const SharedQuadState* shared_quad_state,
@@ -42,12 +44,14 @@
bool needs_blending,
const gfx::RectF& tex_coord_rect,
const gfx::Size& texture_size,
- bool swizzle_contents) {
+ bool swizzle_contents,
+ bool nearest_neighbor) {
DrawQuad::SetAll(shared_quad_state, material, rect, opaque_rect,
visible_rect, needs_blending);
this->tex_coord_rect = tex_coord_rect;
this->texture_size = texture_size;
this->swizzle_contents = swizzle_contents;
+ this->nearest_neighbor = nearest_neighbor;
}
void ContentDrawQuadBase::ExtendValue(base::debug::TracedValue* value) const {
@@ -60,6 +64,7 @@
value->EndDictionary();
value->SetBoolean("swizzle_contents", swizzle_contents);
+ value->SetBoolean("nearest_neighbor", nearest_neighbor);
}
} // namespace cc
diff --git a/cc/quads/content_draw_quad_base.h b/cc/quads/content_draw_quad_base.h
index b0e53dc..58aa727 100644
--- a/cc/quads/content_draw_quad_base.h
+++ b/cc/quads/content_draw_quad_base.h
@@ -23,7 +23,8 @@
const gfx::Rect& visible_rect,
const gfx::RectF& tex_coord_rect,
const gfx::Size& texture_size,
- bool swizzle_contents);
+ bool swizzle_contents,
+ bool nearest_neighbor);
void SetAll(const SharedQuadState* shared_quad_state,
DrawQuad::Material material,
@@ -33,11 +34,13 @@
bool needs_blending,
const gfx::RectF& tex_coord_rect,
const gfx::Size& texture_size,
- bool swizzle_contents);
+ bool swizzle_contents,
+ bool nearest_neighbor);
gfx::RectF tex_coord_rect;
gfx::Size texture_size;
bool swizzle_contents;
+ bool nearest_neighbor;
protected:
ContentDrawQuadBase();
diff --git a/cc/quads/draw_quad_unittest.cc b/cc/quads/draw_quad_unittest.cc
index e65b326..97fea32 100644
--- a/cc/quads/draw_quad_unittest.cc
+++ b/cc/quads/draw_quad_unittest.cc
@@ -600,15 +600,17 @@
gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
gfx::Size texture_size(85, 32);
bool swizzle_contents = true;
+ bool nearest_neighbor = true;
CREATE_SHARED_STATE();
- CREATE_QUAD_6_NEW(TileDrawQuad,
+ CREATE_QUAD_7_NEW(TileDrawQuad,
opaque_rect,
visible_rect,
resource_id,
tex_coord_rect,
texture_size,
- swizzle_contents);
+ swizzle_contents,
+ nearest_neighbor);
EXPECT_EQ(DrawQuad::TILED_CONTENT, copy_quad->material);
EXPECT_EQ(opaque_rect, copy_quad->opaque_rect);
EXPECT_EQ(visible_rect, copy_quad->visible_rect);
@@ -616,17 +618,20 @@
EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
EXPECT_EQ(texture_size, copy_quad->texture_size);
EXPECT_EQ(swizzle_contents, copy_quad->swizzle_contents);
+ EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
- CREATE_QUAD_4_ALL(TileDrawQuad,
+ CREATE_QUAD_5_ALL(TileDrawQuad,
resource_id,
tex_coord_rect,
texture_size,
- swizzle_contents);
+ swizzle_contents,
+ nearest_neighbor);
EXPECT_EQ(DrawQuad::TILED_CONTENT, copy_quad->material);
EXPECT_EQ(resource_id, copy_quad->resource_id);
EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
EXPECT_EQ(texture_size, copy_quad->texture_size);
EXPECT_EQ(swizzle_contents, copy_quad->swizzle_contents);
+ EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
}
TEST(DrawQuadTest, CopyYUVVideoDrawQuad) {
@@ -680,31 +685,34 @@
gfx::Rect visible_rect(40, 50, 30, 20);
gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
gfx::Size texture_size(85, 32);
+ bool nearest_neighbor = true;
ResourceFormat texture_format = RGBA_8888;
gfx::Rect content_rect(30, 40, 20, 30);
float contents_scale = 3.141592f;
scoped_refptr<RasterSource> raster_source = PicturePileImpl::Create();
CREATE_SHARED_STATE();
- CREATE_QUAD_8_NEW(PictureDrawQuad, opaque_rect, visible_rect, tex_coord_rect,
- texture_size, texture_format, content_rect, contents_scale,
- raster_source);
+ CREATE_QUAD_9_NEW(PictureDrawQuad, opaque_rect, visible_rect, tex_coord_rect,
+ texture_size, nearest_neighbor, texture_format,
+ content_rect, contents_scale, raster_source);
EXPECT_EQ(DrawQuad::PICTURE_CONTENT, copy_quad->material);
EXPECT_EQ(opaque_rect, copy_quad->opaque_rect);
EXPECT_EQ(visible_rect, copy_quad->visible_rect);
EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
EXPECT_EQ(texture_size, copy_quad->texture_size);
+ EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
EXPECT_EQ(texture_format, copy_quad->texture_format);
EXPECT_EQ(content_rect, copy_quad->content_rect);
EXPECT_EQ(contents_scale, copy_quad->contents_scale);
EXPECT_EQ(raster_source, copy_quad->raster_source);
- CREATE_QUAD_6_ALL(PictureDrawQuad, tex_coord_rect, texture_size,
- texture_format, content_rect, contents_scale,
- raster_source);
+ CREATE_QUAD_7_ALL(PictureDrawQuad, tex_coord_rect, texture_size,
+ nearest_neighbor, texture_format, content_rect,
+ contents_scale, raster_source);
EXPECT_EQ(DrawQuad::PICTURE_CONTENT, copy_quad->material);
EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
EXPECT_EQ(texture_size, copy_quad->texture_size);
+ EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
EXPECT_EQ(texture_format, copy_quad->texture_format);
EXPECT_EQ(content_rect, copy_quad->content_rect);
EXPECT_EQ(contents_scale, copy_quad->contents_scale);
@@ -871,15 +879,17 @@
gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
gfx::Size texture_size(85, 32);
bool swizzle_contents = true;
+ bool nearest_neighbor = true;
CREATE_SHARED_STATE();
- CREATE_QUAD_6_NEW(TileDrawQuad,
+ CREATE_QUAD_7_NEW(TileDrawQuad,
opaque_rect,
visible_rect,
resource_id,
tex_coord_rect,
texture_size,
- swizzle_contents);
+ swizzle_contents,
+ nearest_neighbor);
EXPECT_EQ(resource_id, quad_new->resource_id);
EXPECT_EQ(1, IterateAndCount(quad_new));
EXPECT_EQ(resource_id + 1, quad_new->resource_id);
@@ -924,15 +934,16 @@
gfx::Rect visible_rect(40, 50, 30, 20);
gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
gfx::Size texture_size(85, 32);
+ bool nearest_neighbor = true;
ResourceFormat texture_format = RGBA_8888;
gfx::Rect content_rect(30, 40, 20, 30);
float contents_scale = 3.141592f;
scoped_refptr<PicturePileImpl> raster_source = PicturePileImpl::Create();
CREATE_SHARED_STATE();
- CREATE_QUAD_8_NEW(PictureDrawQuad, opaque_rect, visible_rect, tex_coord_rect,
- texture_size, texture_format, content_rect, contents_scale,
- raster_source);
+ CREATE_QUAD_9_NEW(PictureDrawQuad, opaque_rect, visible_rect, tex_coord_rect,
+ texture_size, nearest_neighbor, texture_format,
+ content_rect, contents_scale, raster_source);
EXPECT_EQ(0, IterateAndCount(quad_new));
}
diff --git a/cc/quads/picture_draw_quad.cc b/cc/quads/picture_draw_quad.cc
index bf329c2..2171542 100644
--- a/cc/quads/picture_draw_quad.cc
+++ b/cc/quads/picture_draw_quad.cc
@@ -23,6 +23,7 @@
const gfx::Rect& visible_rect,
const gfx::RectF& tex_coord_rect,
const gfx::Size& texture_size,
+ bool nearest_neighbor,
ResourceFormat texture_format,
const gfx::Rect& content_rect,
float contents_scale,
@@ -35,7 +36,8 @@
visible_rect,
tex_coord_rect,
texture_size,
- !PlatformColor::SameComponentOrder(texture_format));
+ !PlatformColor::SameComponentOrder(texture_format),
+ nearest_neighbor);
this->content_rect = content_rect;
this->contents_scale = contents_scale;
this->raster_source = raster_source;
@@ -49,6 +51,7 @@
bool needs_blending,
const gfx::RectF& tex_coord_rect,
const gfx::Size& texture_size,
+ bool nearest_neighbor,
ResourceFormat texture_format,
const gfx::Rect& content_rect,
float contents_scale,
@@ -62,7 +65,8 @@
tex_coord_rect,
texture_size,
!PlatformColor::SameComponentOrder(
- texture_format));
+ texture_format),
+ nearest_neighbor);
this->content_rect = content_rect;
this->contents_scale = contents_scale;
this->raster_source = raster_source;
diff --git a/cc/quads/picture_draw_quad.h b/cc/quads/picture_draw_quad.h
index 62c9f18..624b69c 100644
--- a/cc/quads/picture_draw_quad.h
+++ b/cc/quads/picture_draw_quad.h
@@ -28,6 +28,7 @@
const gfx::Rect& visible_rect,
const gfx::RectF& tex_coord_rect,
const gfx::Size& texture_size,
+ bool nearest_neighbor,
ResourceFormat texture_format,
const gfx::Rect& content_rect,
float contents_scale,
@@ -40,6 +41,7 @@
bool needs_blending,
const gfx::RectF& tex_coord_rect,
const gfx::Size& texture_size,
+ bool nearest_neighbor,
ResourceFormat texture_format,
const gfx::Rect& content_rect,
float contents_scale,
diff --git a/cc/quads/tile_draw_quad.cc b/cc/quads/tile_draw_quad.cc
index ea3a14a..88a4b3a 100644
--- a/cc/quads/tile_draw_quad.cc
+++ b/cc/quads/tile_draw_quad.cc
@@ -25,7 +25,8 @@
unsigned resource_id,
const gfx::RectF& tex_coord_rect,
const gfx::Size& texture_size,
- bool swizzle_contents) {
+ bool swizzle_contents,
+ bool nearest_neighbor) {
ContentDrawQuadBase::SetNew(shared_quad_state,
DrawQuad::TILED_CONTENT,
rect,
@@ -33,7 +34,8 @@
visible_rect,
tex_coord_rect,
texture_size,
- swizzle_contents);
+ swizzle_contents,
+ nearest_neighbor);
this->resource_id = resource_id;
}
@@ -45,10 +47,12 @@
unsigned resource_id,
const gfx::RectF& tex_coord_rect,
const gfx::Size& texture_size,
- bool swizzle_contents) {
+ bool swizzle_contents,
+ bool nearest_neighbor) {
ContentDrawQuadBase::SetAll(shared_quad_state, DrawQuad::TILED_CONTENT, rect,
opaque_rect, visible_rect, needs_blending,
- tex_coord_rect, texture_size, swizzle_contents);
+ tex_coord_rect, texture_size, swizzle_contents,
+ nearest_neighbor);
this->resource_id = resource_id;
}
diff --git a/cc/quads/tile_draw_quad.h b/cc/quads/tile_draw_quad.h
index d776057..e668ddb 100644
--- a/cc/quads/tile_draw_quad.h
+++ b/cc/quads/tile_draw_quad.h
@@ -21,7 +21,8 @@
unsigned resource_id,
const gfx::RectF& tex_coord_rect,
const gfx::Size& texture_size,
- bool swizzle_contents);
+ bool swizzle_contents,
+ bool nearest_neighbor);
void SetAll(const SharedQuadState* shared_quad_state,
const gfx::Rect& rect,
@@ -31,7 +32,8 @@
unsigned resource_id,
const gfx::RectF& tex_coord_rect,
const gfx::Size& texture_size,
- bool swizzle_contents);
+ bool swizzle_contents,
+ bool nearest_neighbor);
unsigned resource_id;
diff --git a/cc/resources/display_list_recording_source.cc b/cc/resources/display_list_recording_source.cc
index 3c0e0e4..ab4c646 100644
--- a/cc/resources/display_list_recording_source.cc
+++ b/cc/resources/display_list_recording_source.cc
@@ -142,9 +142,8 @@
if (display_list_->ApproximateOpCount() > kOpCountThatIsOkToAnalyze)
return;
- skia::AnalysisCanvas canvas(recorded_viewport_.width(),
- recorded_viewport_.height());
- canvas.translate(-recorded_viewport_.x(), -recorded_viewport_.y());
+ gfx::Size layer_size = GetSize();
+ skia::AnalysisCanvas canvas(layer_size.width(), layer_size.height());
display_list_->Raster(&canvas, nullptr, 1.f);
is_solid_color_ = canvas.GetColorIfSolid(&solid_color_);
}
diff --git a/cc/resources/eviction_tile_priority_queue.cc b/cc/resources/eviction_tile_priority_queue.cc
index 4d66987..cd681ef 100644
--- a/cc/resources/eviction_tile_priority_queue.cc
+++ b/cc/resources/eviction_tile_priority_queue.cc
@@ -200,6 +200,8 @@
const Tile* active_tile = active_queue->Top();
const Tile* pending_tile = pending_queue->Top();
+
+ // If tiles are the same, it doesn't matter which tree we return.
if (active_tile == pending_tile)
return ACTIVE_TREE;
@@ -208,6 +210,15 @@
const TilePriority& pending_priority =
pending_tile->priority_for_tree_priority(tree_priority);
+ // If the bins are the same and activation differs, then return the tree of
+ // the tile not required for activation.
+ if (active_priority.priority_bin == pending_priority.priority_bin &&
+ active_tile->required_for_activation() !=
+ pending_tile->required_for_activation()) {
+ return active_tile->required_for_activation() ? PENDING_TREE : ACTIVE_TREE;
+ }
+
+ // Return tile with a lower priority.
if (pending_priority.IsHigherPriorityThan(active_priority))
return ACTIVE_TREE;
return PENDING_TREE;
diff --git a/cc/resources/picture.cc b/cc/resources/picture.cc
index 6530866..ea7680c 100644
--- a/cc/resources/picture.cc
+++ b/cc/resources/picture.cc
@@ -121,7 +121,7 @@
if (skpicture == NULL)
return NULL;
- gfx::Rect layer_rect(skpicture->width(), skpicture->height());
+ gfx::Rect layer_rect(gfx::SkIRectToRect(skpicture->cullRect().roundOut()));
return make_scoped_refptr(new Picture(skpicture, layer_rect));
}
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc
index e9e3b86..d2d5484 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -25,63 +25,44 @@
const float kSoonBorderDistanceInScreenPixels = 312.f;
-class TileEvictionOrder {
- public:
- explicit TileEvictionOrder(TreePriority tree_priority)
- : tree_priority_(tree_priority) {}
- ~TileEvictionOrder() {}
-
- bool operator()(const Tile* a, const Tile* b) {
- const TilePriority& a_priority =
- a->priority_for_tree_priority(tree_priority_);
- const TilePriority& b_priority =
- b->priority_for_tree_priority(tree_priority_);
-
- DCHECK(a_priority.priority_bin == b_priority.priority_bin);
- DCHECK(a->required_for_activation() == b->required_for_activation());
-
- // Or if a is occluded and b is unoccluded.
- bool a_is_occluded = a->is_occluded_for_tree_priority(tree_priority_);
- bool b_is_occluded = b->is_occluded_for_tree_priority(tree_priority_);
- if (a_is_occluded != b_is_occluded)
- return a_is_occluded;
-
- // Or if a is farther away from visible.
- return a_priority.distance_to_visible > b_priority.distance_to_visible;
- }
-
- private:
- TreePriority tree_priority_;
-};
-
} // namespace
scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create(
float contents_scale,
const gfx::Size& layer_bounds,
- PictureLayerTilingClient* client) {
- return make_scoped_ptr(new PictureLayerTiling(contents_scale,
- layer_bounds,
- client));
+ PictureLayerTilingClient* client,
+ size_t max_tiles_for_interest_area,
+ float skewport_target_time_in_seconds,
+ int skewport_extrapolation_limit_in_content_pixels) {
+ return make_scoped_ptr(new PictureLayerTiling(
+ contents_scale, layer_bounds, client, max_tiles_for_interest_area,
+ skewport_target_time_in_seconds,
+ skewport_extrapolation_limit_in_content_pixels));
}
-PictureLayerTiling::PictureLayerTiling(float contents_scale,
- const gfx::Size& layer_bounds,
- PictureLayerTilingClient* client)
- : contents_scale_(contents_scale),
+PictureLayerTiling::PictureLayerTiling(
+ float contents_scale,
+ const gfx::Size& layer_bounds,
+ PictureLayerTilingClient* client,
+ size_t max_tiles_for_interest_area,
+ float skewport_target_time_in_seconds,
+ int skewport_extrapolation_limit_in_content_pixels)
+ : max_tiles_for_interest_area_(max_tiles_for_interest_area),
+ skewport_target_time_in_seconds_(skewport_target_time_in_seconds),
+ skewport_extrapolation_limit_in_content_pixels_(
+ skewport_extrapolation_limit_in_content_pixels),
+ contents_scale_(contents_scale),
layer_bounds_(layer_bounds),
resolution_(NON_IDEAL_RESOLUTION),
client_(client),
tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels),
last_impl_frame_time_in_seconds_(0.0),
- content_to_screen_scale_(0.f),
can_require_tiles_for_activation_(false),
+ current_content_to_screen_scale_(0.f),
has_visible_rect_tiles_(false),
has_skewport_rect_tiles_(false),
has_soon_border_rect_tiles_(false),
- has_eventually_rect_tiles_(false),
- eviction_tiles_cache_valid_(false),
- eviction_cache_tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES) {
+ has_eventually_rect_tiles_(false) {
gfx::Size content_bounds =
gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale));
gfx::Size tile_size = client_->CalculateTileSize(content_bounds);
@@ -105,13 +86,13 @@
it->second->set_shared(false);
}
-void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) {
- client_ = client;
-}
-
Tile* PictureLayerTiling::CreateTile(int i,
int j,
- const PictureLayerTiling* twin_tiling) {
+ const PictureLayerTiling* twin_tiling,
+ PictureLayerTiling* recycled_twin) {
+ // Can't have both a (pending or active) twin and a recycled twin tiling.
+ DCHECK_IMPLIES(twin_tiling, !recycled_twin);
+ DCHECK_IMPLIES(recycled_twin, !twin_tiling);
TileMapKey key(i, j);
DCHECK(tiles_.find(key) == tiles_.end());
@@ -144,14 +125,24 @@
DCHECK(!tile->is_shared());
tile->set_tiling_index(i, j);
tiles_[key] = tile;
+
+ if (recycled_twin) {
+ DCHECK(recycled_twin->tiles_.find(key) == recycled_twin->tiles_.end());
+ // Do what recycled_twin->CreateTile() would do.
+ tile->set_shared(true);
+ recycled_twin->tiles_[key] = tile;
+ }
}
- eviction_tiles_cache_valid_ = false;
return tile.get();
}
void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() {
const PictureLayerTiling* twin_tiling =
client_->GetPendingOrActiveTwinTiling(this);
+ // There is no recycled twin during commit from the main thread which is when
+ // this occurs.
+ PictureLayerTiling* null_recycled_twin = nullptr;
+ DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this));
bool include_borders = false;
for (TilingData::Iterator iter(
&tiling_data_, live_tiles_rect_, include_borders);
@@ -161,116 +152,160 @@
TileMap::iterator find = tiles_.find(key);
if (find != tiles_.end())
continue;
- CreateTile(key.first, key.second, twin_tiling);
+ CreateTile(key.first, key.second, twin_tiling, null_recycled_twin);
}
- VerifyLiveTilesRect();
+ VerifyLiveTilesRect(false);
}
-void PictureLayerTiling::UpdateTilesToCurrentRasterSource(
- RasterSource* raster_source,
- const Region& layer_invalidation,
- const gfx::Size& new_layer_bounds) {
- DCHECK(!new_layer_bounds.IsEmpty());
+void PictureLayerTiling::CloneTilesAndPropertiesFrom(
+ const PictureLayerTiling& twin_tiling) {
+ DCHECK_EQ(&twin_tiling, client_->GetPendingOrActiveTwinTiling(this));
+ Resize(twin_tiling.layer_bounds_);
+ DCHECK_EQ(twin_tiling.contents_scale_, contents_scale_);
+ DCHECK_EQ(twin_tiling.layer_bounds().ToString(), layer_bounds().ToString());
+ DCHECK_EQ(twin_tiling.tile_size().ToString(), tile_size().ToString());
+
+ resolution_ = twin_tiling.resolution_;
+
+ SetLiveTilesRect(twin_tiling.live_tiles_rect());
+
+ // Recreate unshared tiles.
+ std::vector<TileMapKey> to_remove;
+ for (const auto& tile_map_pair : tiles_) {
+ TileMapKey key = tile_map_pair.first;
+ Tile* tile = tile_map_pair.second.get();
+ if (!tile->is_shared())
+ to_remove.push_back(key);
+ }
+ // The recycled twin does not exist since there is a pending twin (which is
+ // |twin_tiling|).
+ PictureLayerTiling* null_recycled_twin = nullptr;
+ DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this));
+ for (const auto& key : to_remove) {
+ RemoveTileAt(key.first, key.second, null_recycled_twin);
+ CreateTile(key.first, key.second, &twin_tiling, null_recycled_twin);
+ }
+
+ // Create any missing tiles from the |twin_tiling|.
+ for (const auto& tile_map_pair : twin_tiling.tiles_) {
+ TileMapKey key = tile_map_pair.first;
+ Tile* tile = tile_map_pair.second.get();
+ if (!tile->is_shared())
+ CreateTile(key.first, key.second, &twin_tiling, null_recycled_twin);
+ }
+
+ DCHECK_EQ(twin_tiling.tiles_.size(), tiles_.size());
+#if DCHECK_IS_ON
+ for (const auto& tile_map_pair : tiles_)
+ DCHECK(tile_map_pair.second->is_shared());
+ VerifyLiveTilesRect(false);
+#endif
+
+ UpdateTilePriorityRects(twin_tiling.current_content_to_screen_scale_,
+ twin_tiling.current_visible_rect_,
+ twin_tiling.current_skewport_rect_,
+ twin_tiling.current_soon_border_rect_,
+ twin_tiling.current_eventually_rect_,
+ twin_tiling.current_occlusion_in_layer_space_);
+}
+
+void PictureLayerTiling::Resize(const gfx::Size& new_layer_bounds) {
+ gfx::Size layer_bounds = new_layer_bounds;
gfx::Size content_bounds =
gfx::ToCeiledSize(gfx::ScaleSize(new_layer_bounds, contents_scale_));
gfx::Size tile_size = client_->CalculateTileSize(content_bounds);
- if (new_layer_bounds != layer_bounds_) {
- if (tile_size.IsEmpty()) {
- layer_bounds_ = gfx::Size();
- content_bounds = gfx::Size();
- } else {
- layer_bounds_ = new_layer_bounds;
- }
-
- // The SetLiveTilesRect() method would drop tiles outside the new bounds,
- // but may do so incorrectly if resizing the tiling causes the number of
- // tiles in the tiling_data_ to change.
- gfx::Rect content_rect(content_bounds);
- int before_left = tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.x());
- int before_top = tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.y());
- int before_right =
- tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1);
- int before_bottom =
- tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1);
-
- // The live_tiles_rect_ is clamped to stay within the tiling size as we
- // change it.
- live_tiles_rect_.Intersect(content_rect);
- tiling_data_.SetTilingSize(content_bounds);
-
- int after_right = -1;
- int after_bottom = -1;
- if (!live_tiles_rect_.IsEmpty()) {
- after_right =
- tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1);
- after_bottom =
- tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1);
- }
-
- // There is no recycled twin since this is run on the pending tiling.
- PictureLayerTiling* recycled_twin = NULL;
- DCHECK_EQ(recycled_twin, client_->GetRecycledTwinTiling(this));
- DCHECK_EQ(PENDING_TREE, client_->GetTree());
-
- // Drop tiles outside the new layer bounds if the layer shrank.
- for (int i = after_right + 1; i <= before_right; ++i) {
- for (int j = before_top; j <= before_bottom; ++j)
- RemoveTileAt(i, j, recycled_twin);
- }
- for (int i = before_left; i <= after_right; ++i) {
- for (int j = after_bottom + 1; j <= before_bottom; ++j)
- RemoveTileAt(i, j, recycled_twin);
- }
-
- // If the layer grew, the live_tiles_rect_ is not changed, but a new row
- // and/or column of tiles may now exist inside the same live_tiles_rect_.
- const PictureLayerTiling* twin_tiling =
- client_->GetPendingOrActiveTwinTiling(this);
- if (after_right > before_right) {
- DCHECK_EQ(after_right, before_right + 1);
- for (int j = before_top; j <= after_bottom; ++j)
- CreateTile(after_right, j, twin_tiling);
- }
- if (after_bottom > before_bottom) {
- DCHECK_EQ(after_bottom, before_bottom + 1);
- for (int i = before_left; i <= before_right; ++i)
- CreateTile(i, after_bottom, twin_tiling);
- }
+ if (tile_size.IsEmpty()) {
+ layer_bounds = gfx::Size();
+ content_bounds = gfx::Size();
}
+ // The layer bounds are only allowed to be empty when the tile size is empty.
+ // Otherwise we should not have such a tiling in the first place.
+ DCHECK_IMPLIES(!tile_size.IsEmpty(), !layer_bounds_.IsEmpty());
+
+ bool resized = layer_bounds != layer_bounds_;
+ layer_bounds_ = layer_bounds;
+
if (tile_size != tiling_data_.max_texture_size()) {
+ tiling_data_.SetTilingSize(content_bounds);
tiling_data_.SetMaxTextureSize(tile_size);
// When the tile size changes, the TilingData positions no longer work
- // as valid keys to the TileMap, so just drop all tiles.
+ // as valid keys to the TileMap, so just drop all tiles and clear the live
+ // tiles rect.
Reset();
- } else {
- Invalidate(layer_invalidation);
+ return;
}
- for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it)
- it->second->set_raster_source(raster_source);
- VerifyLiveTilesRect();
+ if (!resized)
+ return;
+
+ // The SetLiveTilesRect() method would drop tiles outside the new bounds,
+ // but may do so incorrectly if resizing the tiling causes the number of
+ // tiles in the tiling_data_ to change.
+ gfx::Rect content_rect(content_bounds);
+ int before_left = tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.x());
+ int before_top = tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.y());
+ int before_right =
+ tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1);
+ int before_bottom =
+ tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1);
+
+ // The live_tiles_rect_ is clamped to stay within the tiling size as we
+ // change it.
+ live_tiles_rect_.Intersect(content_rect);
+ tiling_data_.SetTilingSize(content_bounds);
+
+ int after_right = -1;
+ int after_bottom = -1;
+ if (!live_tiles_rect_.IsEmpty()) {
+ after_right =
+ tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1);
+ after_bottom =
+ tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1);
+ }
+
+ // There is no recycled twin since this is run on the pending tiling
+ // during commit, and on the active tree during activate.
+ PictureLayerTiling* null_recycled_twin = nullptr;
+ DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this));
+
+ // Drop tiles outside the new layer bounds if the layer shrank.
+ for (int i = after_right + 1; i <= before_right; ++i) {
+ for (int j = before_top; j <= before_bottom; ++j)
+ RemoveTileAt(i, j, null_recycled_twin);
+ }
+ for (int i = before_left; i <= after_right; ++i) {
+ for (int j = after_bottom + 1; j <= before_bottom; ++j)
+ RemoveTileAt(i, j, null_recycled_twin);
+ }
+
+ // If the layer grew, the live_tiles_rect_ is not changed, but a new row
+ // and/or column of tiles may now exist inside the same live_tiles_rect_.
+ const PictureLayerTiling* twin_tiling =
+ client_->GetPendingOrActiveTwinTiling(this);
+ if (after_right > before_right) {
+ DCHECK_EQ(after_right, before_right + 1);
+ for (int j = before_top; j <= after_bottom; ++j)
+ CreateTile(after_right, j, twin_tiling, null_recycled_twin);
+ }
+ if (after_bottom > before_bottom) {
+ DCHECK_EQ(after_bottom, before_bottom + 1);
+ for (int i = before_left; i <= before_right; ++i)
+ CreateTile(i, after_bottom, twin_tiling, null_recycled_twin);
+ }
}
-void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_region) {
- bool recreate_invalidated_tiles = false;
- DoInvalidate(layer_region, recreate_invalidated_tiles);
-}
-
-void PictureLayerTiling::Invalidate(const Region& layer_region) {
- bool recreate_invalidated_tiles = true;
- DoInvalidate(layer_region, recreate_invalidated_tiles);
-}
-
-void PictureLayerTiling::DoInvalidate(const Region& layer_region,
- bool recreate_invalidated_tiles) {
+void PictureLayerTiling::Invalidate(const Region& layer_invalidation) {
+ if (live_tiles_rect_.IsEmpty())
+ return;
std::vector<TileMapKey> new_tile_keys;
gfx::Rect expanded_live_tiles_rect =
tiling_data_.ExpandRectIgnoringBordersToTileBounds(live_tiles_rect_);
- for (Region::Iterator iter(layer_region); iter.has_rect(); iter.next()) {
+ for (Region::Iterator iter(layer_invalidation); iter.has_rect();
+ iter.next()) {
gfx::Rect layer_rect = iter.rect();
gfx::Rect content_rect =
gfx::ScaleToEnclosingRect(layer_rect, contents_scale_);
@@ -291,25 +326,40 @@
&tiling_data_, content_rect, include_borders);
iter;
++iter) {
- // There is no recycled twin since this is run on the pending tiling.
- PictureLayerTiling* recycled_twin = NULL;
- DCHECK_EQ(recycled_twin, client_->GetRecycledTwinTiling(this));
- DCHECK_EQ(PENDING_TREE, client_->GetTree());
- if (RemoveTileAt(iter.index_x(), iter.index_y(), recycled_twin))
+ // There is no recycled twin for the pending tree during commit, or for
+ // the active tree during activation.
+ PictureLayerTiling* null_recycled_twin = nullptr;
+ DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this));
+ if (RemoveTileAt(iter.index_x(), iter.index_y(), null_recycled_twin))
new_tile_keys.push_back(iter.index());
}
}
- if (recreate_invalidated_tiles && !new_tile_keys.empty()) {
+ if (!new_tile_keys.empty()) {
+ // During commit from the main thread, invalidations can never be shared
+ // with the active tree since the active tree has different content there.
+ // And when invalidating an active-tree tiling, it means there was no
+ // pending tiling to clone from.
+ const PictureLayerTiling* null_twin_tiling = nullptr;
+ PictureLayerTiling* null_recycled_twin = nullptr;
+ DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this));
for (size_t i = 0; i < new_tile_keys.size(); ++i) {
- // Don't try to share a tile with the twin layer, it's been invalidated so
- // we have to make our own tile here.
- const PictureLayerTiling* twin_tiling = NULL;
- CreateTile(new_tile_keys[i].first, new_tile_keys[i].second, twin_tiling);
+ CreateTile(new_tile_keys[i].first, new_tile_keys[i].second,
+ null_twin_tiling, null_recycled_twin);
}
}
}
+void PictureLayerTiling::SetRasterSource(
+ scoped_refptr<RasterSource> raster_source) {
+ // Shared (ie. non-invalidated) tiles on the pending tree are updated to use
+ // the new raster source. When this raster source is activated, the raster
+ // source will remain valid for shared tiles in the active tree.
+ for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it)
+ it->second->set_raster_source(raster_source);
+ VerifyLiveTilesRect(false);
+}
+
PictureLayerTiling::CoverageIterator::CoverageIterator()
: tiling_(NULL),
current_tile_(NULL),
@@ -468,10 +518,9 @@
return false;
found->second->set_shared(false);
tiles_.erase(found);
- eviction_tiles_cache_valid_ = false;
if (recycled_twin) {
- // Recycled twin does not also have a recycled twin, so pass NULL.
- recycled_twin->RemoveTileAt(i, j, NULL);
+ // Recycled twin does not also have a recycled twin, so pass null.
+ recycled_twin->RemoveTileAt(i, j, nullptr);
}
return true;
}
@@ -482,10 +531,9 @@
for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
it->second->set_shared(false);
if (recycled_twin)
- recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL);
+ recycled_twin->RemoveTileAt(it->first.first, it->first.second, nullptr);
}
tiles_.clear();
- eviction_tiles_cache_valid_ = false;
}
gfx::Rect PictureLayerTiling::ComputeSkewport(
@@ -500,10 +548,8 @@
if (time_delta == 0.0)
return skewport;
- float skewport_target_time_in_seconds =
- client_->GetSkewportTargetTimeInSeconds();
double extrapolation_multiplier =
- skewport_target_time_in_seconds / time_delta;
+ skewport_target_time_in_seconds_ / time_delta;
int old_x = last_visible_rect_in_content_space_.x();
int old_y = last_visible_rect_in_content_space_.y();
@@ -515,12 +561,11 @@
int new_right = visible_rect_in_content_space.right();
int new_bottom = visible_rect_in_content_space.bottom();
- int skewport_limit = client_->GetSkewportExtrapolationLimitInContentPixels();
-
- // Compute the maximum skewport based on |skewport_limit|.
+ // Compute the maximum skewport based on
+ // |skewport_extrapolation_limit_in_content_pixels_|.
gfx::Rect max_skewport = skewport;
- max_skewport.Inset(
- -skewport_limit, -skewport_limit, -skewport_limit, -skewport_limit);
+ max_skewport.Inset(-skewport_extrapolation_limit_in_content_pixels_,
+ -skewport_extrapolation_limit_in_content_pixels_);
// Inset the skewport by the needed adjustment.
skewport.Inset(extrapolation_multiplier * (new_x - old_x),
@@ -564,11 +609,9 @@
DCHECK(skewport.Contains(visible_rect_in_content_space));
// Calculate the eventually/live tiles rect.
- size_t max_tiles_for_interest_area = client_->GetMaxTilesForInterestArea();
-
gfx::Size tile_size = tiling_data_.max_texture_size();
int64 eventually_rect_area =
- max_tiles_for_interest_area * tile_size.width() * tile_size.height();
+ max_tiles_for_interest_area_ * tile_size.width() * tile_size.height();
gfx::Rect eventually_rect =
ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space,
@@ -582,29 +625,36 @@
<< " eventually_rect: " << eventually_rect.ToString();
// Calculate the soon border rect.
- content_to_screen_scale_ = ideal_contents_scale / contents_scale_;
+ float content_to_screen_scale = ideal_contents_scale / contents_scale_;
gfx::Rect soon_border_rect = visible_rect_in_content_space;
- float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_;
+ float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale;
soon_border_rect.Inset(-border, -border, -border, -border);
- // Update the tiling state.
- SetLiveTilesRect(eventually_rect);
-
last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
last_viewport_in_layer_space_ = viewport_in_layer_space;
last_visible_rect_in_content_space_ = visible_rect_in_content_space;
- eviction_tiles_cache_valid_ = false;
+ SetLiveTilesRect(eventually_rect);
+ UpdateTilePriorityRects(
+ content_to_screen_scale, visible_rect_in_content_space, skewport,
+ soon_border_rect, eventually_rect, occlusion_in_layer_space);
+}
+void PictureLayerTiling::UpdateTilePriorityRects(
+ float content_to_screen_scale,
+ const gfx::Rect& visible_rect_in_content_space,
+ const gfx::Rect& skewport,
+ const gfx::Rect& soon_border_rect,
+ const gfx::Rect& eventually_rect,
+ const Occlusion& occlusion_in_layer_space) {
current_visible_rect_ = visible_rect_in_content_space;
current_skewport_rect_ = skewport;
current_soon_border_rect_ = soon_border_rect;
current_eventually_rect_ = eventually_rect;
current_occlusion_in_layer_space_ = occlusion_in_layer_space;
+ current_content_to_screen_scale_ = content_to_screen_scale;
- // Update has_*_tiles state.
gfx::Rect tiling_rect(tiling_size());
-
has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_);
has_skewport_rect_tiles_ = tiling_rect.Intersects(current_skewport_rect_);
has_soon_border_rect_tiles_ =
@@ -621,8 +671,9 @@
if (live_tiles_rect_ == new_live_tiles_rect)
return;
- // Iterate to delete all tiles outside of our new live_tiles rect.
PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this);
+
+ // Iterate to delete all tiles outside of our new live_tiles rect.
for (TilingData::DifferenceIterator iter(&tiling_data_,
live_tiles_rect_,
new_live_tiles_rect);
@@ -641,16 +692,20 @@
iter;
++iter) {
TileMapKey key(iter.index());
- CreateTile(key.first, key.second, twin_tiling);
+ CreateTile(key.first, key.second, twin_tiling, recycled_twin);
}
live_tiles_rect_ = new_live_tiles_rect;
- VerifyLiveTilesRect();
+ VerifyLiveTilesRect(false);
+ if (recycled_twin) {
+ recycled_twin->live_tiles_rect_ = live_tiles_rect_;
+ recycled_twin->VerifyLiveTilesRect(true);
+ }
}
-void PictureLayerTiling::VerifyLiveTilesRect() {
+void PictureLayerTiling::VerifyLiveTilesRect(bool is_on_recycle_tree) const {
#if DCHECK_IS_ON
- for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
+ for (auto it = tiles_.begin(); it != tiles_.end(); ++it) {
if (!it->second.get())
continue;
DCHECK(it->first.first < tiling_data_.num_tiles_x())
@@ -667,6 +722,7 @@
<< " tile bounds "
<< tiling_data_.TileBounds(it->first.first, it->first.second).ToString()
<< " live_tiles_rect " << live_tiles_rect_.ToString();
+ DCHECK_IMPLIES(is_on_recycle_tree, it->second->is_shared());
}
#endif
}
@@ -805,10 +861,10 @@
tile->set_required_for_draw(false);
tile->set_is_occluded(tree, false);
- DCHECK_GT(content_to_screen_scale_, 0.f);
+ DCHECK_GT(current_content_to_screen_scale_, 0.f);
float distance_to_visible =
current_visible_rect_.ManhattanInternalDistance(tile_bounds) *
- content_to_screen_scale_;
+ current_content_to_screen_scale_;
if (max_tile_priority_bin <= TilePriority::SOON &&
(current_soon_border_rect_.Intersects(tile_bounds) ||
@@ -998,92 +1054,6 @@
return result;
}
-void PictureLayerTiling::UpdateEvictionCacheIfNeeded(
- TreePriority tree_priority) {
- if (eviction_tiles_cache_valid_ &&
- eviction_cache_tree_priority_ == tree_priority)
- return;
-
- eviction_tiles_now_.clear();
- eviction_tiles_now_and_required_for_activation_.clear();
- eviction_tiles_soon_.clear();
- eviction_tiles_soon_and_required_for_activation_.clear();
- eviction_tiles_eventually_.clear();
- eviction_tiles_eventually_and_required_for_activation_.clear();
-
- for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
- Tile* tile = it->second.get();
- UpdateTileAndTwinPriority(tile);
- const TilePriority& priority =
- tile->priority_for_tree_priority(tree_priority);
- switch (priority.priority_bin) {
- case TilePriority::EVENTUALLY:
- if (tile->required_for_activation())
- eviction_tiles_eventually_and_required_for_activation_.push_back(
- tile);
- else
- eviction_tiles_eventually_.push_back(tile);
- break;
- case TilePriority::SOON:
- if (tile->required_for_activation())
- eviction_tiles_soon_and_required_for_activation_.push_back(tile);
- else
- eviction_tiles_soon_.push_back(tile);
- break;
- case TilePriority::NOW:
- if (tile->required_for_activation())
- eviction_tiles_now_and_required_for_activation_.push_back(tile);
- else
- eviction_tiles_now_.push_back(tile);
- break;
- }
- }
-
- // TODO(vmpstr): Do this lazily. One option is to have a "sorted" flag that
- // can be updated for each of the queues.
- TileEvictionOrder sort_order(tree_priority);
- std::sort(eviction_tiles_now_.begin(), eviction_tiles_now_.end(), sort_order);
- std::sort(eviction_tiles_now_and_required_for_activation_.begin(),
- eviction_tiles_now_and_required_for_activation_.end(),
- sort_order);
- std::sort(
- eviction_tiles_soon_.begin(), eviction_tiles_soon_.end(), sort_order);
- std::sort(eviction_tiles_soon_and_required_for_activation_.begin(),
- eviction_tiles_soon_and_required_for_activation_.end(),
- sort_order);
- std::sort(eviction_tiles_eventually_.begin(),
- eviction_tiles_eventually_.end(),
- sort_order);
- std::sort(eviction_tiles_eventually_and_required_for_activation_.begin(),
- eviction_tiles_eventually_and_required_for_activation_.end(),
- sort_order);
-
- eviction_tiles_cache_valid_ = true;
- eviction_cache_tree_priority_ = tree_priority;
-}
-
-const std::vector<Tile*>* PictureLayerTiling::GetEvictionTiles(
- TreePriority tree_priority,
- EvictionCategory category) {
- UpdateEvictionCacheIfNeeded(tree_priority);
- switch (category) {
- case EVENTUALLY:
- return &eviction_tiles_eventually_;
- case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION:
- return &eviction_tiles_eventually_and_required_for_activation_;
- case SOON:
- return &eviction_tiles_soon_;
- case SOON_AND_REQUIRED_FOR_ACTIVATION:
- return &eviction_tiles_soon_and_required_for_activation_;
- case NOW:
- return &eviction_tiles_now_;
- case NOW_AND_REQUIRED_FOR_ACTIVATION:
- return &eviction_tiles_now_and_required_for_activation_;
- }
- NOTREACHED();
- return &eviction_tiles_eventually_;
-}
-
PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator()
: tiling_(NULL), current_tile_(NULL) {}
diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h
index daa0485..4b80aa0 100644
--- a/cc/resources/picture_layer_tiling.h
+++ b/cc/resources/picture_layer_tiling.h
@@ -48,9 +48,6 @@
virtual PictureLayerTiling* GetRecycledTwinTiling(
const PictureLayerTiling* tiling) = 0;
virtual TilePriority::PriorityBin GetMaxTilePriorityBin() const = 0;
- virtual size_t GetMaxTilesForInterestArea() const = 0;
- virtual float GetSkewportTargetTimeInSeconds() const = 0;
- virtual int GetSkewportExtrapolationLimitInContentPixels() const = 0;
virtual WhichTree GetTree() const = 0;
virtual bool RequiresHighResToDraw() const = 0;
@@ -62,15 +59,6 @@
public:
static const int kBorderTexels = 1;
- enum EvictionCategory {
- EVENTUALLY,
- EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION,
- SOON,
- SOON_AND_REQUIRED_FOR_ACTIVATION,
- NOW,
- NOW_AND_REQUIRED_FOR_ACTIVATION
- };
-
class CC_EXPORT TilingRasterTileIterator {
public:
TilingRasterTileIterator();
@@ -121,18 +109,24 @@
~PictureLayerTiling();
// Create a tiling with no tiles. CreateTiles must be called to add some.
+ // TODO(danakj): Pass the raster_source here instead of the size, store the
+ // raster source instead of layer bounds?
static scoped_ptr<PictureLayerTiling> Create(
float contents_scale,
const gfx::Size& layer_bounds,
- PictureLayerTilingClient* client);
- gfx::Size layer_bounds() const { return layer_bounds_; }
- void UpdateTilesToCurrentRasterSource(RasterSource* raster_source,
- const Region& layer_invalidation,
- const gfx::Size& new_layer_bounds);
- void CreateMissingTilesInLiveTilesRect();
- void RemoveTilesInRegion(const Region& layer_region);
+ PictureLayerTilingClient* client,
+ size_t max_tiles_for_interest_area,
+ float skewport_target_time_in_seconds,
+ int skewport_extrapolation_limit_in_content_pixels);
- void SetClient(PictureLayerTilingClient* client);
+ gfx::Size layer_bounds() const { return layer_bounds_; }
+ void Resize(const gfx::Size& new_layer_bounds);
+ void Invalidate(const Region& layer_invalidation);
+ void SetRasterSource(scoped_refptr<RasterSource> raster_source);
+ void CreateMissingTilesInLiveTilesRect();
+
+ void CloneTilesAndPropertiesFrom(const PictureLayerTiling& twin_tiling);
+
void set_resolution(TileResolution resolution) { resolution_ = resolution; }
TileResolution resolution() const { return resolution_; }
void set_can_require_tiles_for_activation(bool can_require_tiles) {
@@ -288,10 +282,16 @@
PictureLayerTiling(float contents_scale,
const gfx::Size& layer_bounds,
- PictureLayerTilingClient* client);
+ PictureLayerTilingClient* client,
+ size_t max_tiles_for_interest_area,
+ float skewport_target_time_in_seconds,
+ int skewport_extrapolation_limit_in_content_pixels);
void SetLiveTilesRect(const gfx::Rect& live_tiles_rect);
- void VerifyLiveTilesRect();
- Tile* CreateTile(int i, int j, const PictureLayerTiling* twin_tiling);
+ void VerifyLiveTilesRect(bool is_on_recycle_tree) const;
+ Tile* CreateTile(int i,
+ int j,
+ const PictureLayerTiling* twin_tiling,
+ PictureLayerTiling* recycled_twin);
// Returns true if the Tile existed and was removed from the tiling.
bool RemoveTileAt(int i, int j, PictureLayerTiling* recycled_twin);
@@ -303,18 +303,21 @@
const gfx::Rect& visible_rect_in_content_space)
const;
- void UpdateEvictionCacheIfNeeded(TreePriority tree_priority);
- const std::vector<Tile*>* GetEvictionTiles(TreePriority tree_priority,
- EvictionCategory category);
-
- void Invalidate(const Region& layer_region);
-
- void DoInvalidate(const Region& layer_region,
- bool recreate_invalidated_tiles);
+ // Save the required data for computing tile priorities later.
+ void UpdateTilePriorityRects(float content_to_screen_scale_,
+ const gfx::Rect& visible_rect_in_content_space,
+ const gfx::Rect& skewport,
+ const gfx::Rect& soon_border_rect,
+ const gfx::Rect& eventually_rect,
+ const Occlusion& occlusion_in_layer_space);
void UpdateTileAndTwinPriority(Tile* tile) const;
void UpdateTilePriority(Tile* tile) const;
+ const size_t max_tiles_for_interest_area_;
+ const float skewport_target_time_in_seconds_;
+ const int skewport_extrapolation_limit_in_content_pixels_;
+
// Given properties.
float contents_scale_;
gfx::Size layer_bounds_;
@@ -330,36 +333,23 @@
double last_impl_frame_time_in_seconds_;
gfx::Rect last_viewport_in_layer_space_;
gfx::Rect last_visible_rect_in_content_space_;
- float content_to_screen_scale_;
bool can_require_tiles_for_activation_;
- // Iteration rects in content space
+ // Iteration rects in content space.
gfx::Rect current_visible_rect_;
gfx::Rect current_skewport_rect_;
gfx::Rect current_soon_border_rect_;
gfx::Rect current_eventually_rect_;
+ // Other properties used for tile iteration and prioritization.
+ float current_content_to_screen_scale_;
+ Occlusion current_occlusion_in_layer_space_;
bool has_visible_rect_tiles_;
bool has_skewport_rect_tiles_;
bool has_soon_border_rect_tiles_;
bool has_eventually_rect_tiles_;
- Occlusion current_occlusion_in_layer_space_;
-
- // TODO(reveman): Remove this in favour of an array of eviction_tiles_ when we
- // change all enums to have a consistent way of getting the count/last
- // element.
- std::vector<Tile*> eviction_tiles_now_;
- std::vector<Tile*> eviction_tiles_now_and_required_for_activation_;
- std::vector<Tile*> eviction_tiles_soon_;
- std::vector<Tile*> eviction_tiles_soon_and_required_for_activation_;
- std::vector<Tile*> eviction_tiles_eventually_;
- std::vector<Tile*> eviction_tiles_eventually_and_required_for_activation_;
-
- bool eviction_tiles_cache_valid_;
- TreePriority eviction_cache_tree_priority_;
-
private:
DISALLOW_ASSIGN(PictureLayerTiling);
diff --git a/cc/resources/picture_layer_tiling_perftest.cc b/cc/resources/picture_layer_tiling_perftest.cc
index 3944e46..ee41bef 100644
--- a/cc/resources/picture_layer_tiling_perftest.cc
+++ b/cc/resources/picture_layer_tiling_perftest.cc
@@ -44,11 +44,14 @@
}
void SetUp() override {
+ LayerTreeSettings defaults;
picture_layer_tiling_client_.SetTileSize(gfx::Size(256, 256));
- picture_layer_tiling_client_.set_max_tiles_for_interest_area(250);
picture_layer_tiling_client_.set_tree(PENDING_TREE);
picture_layer_tiling_ = PictureLayerTiling::Create(
- 1, gfx::Size(256 * 50, 256 * 50), &picture_layer_tiling_client_);
+ 1, gfx::Size(256 * 50, 256 * 50), &picture_layer_tiling_client_,
+ defaults.max_tiles_for_interest_area,
+ defaults.skewport_target_time_in_seconds,
+ defaults.skewport_extrapolation_limit_in_content_pixels);
picture_layer_tiling_->CreateAllTilesForTesting();
}
@@ -57,9 +60,7 @@
void RunInvalidateTest(const std::string& test_name, const Region& region) {
timer_.Reset();
do {
- picture_layer_tiling_->UpdateTilesToCurrentRasterSource(
- picture_layer_tiling_client_.raster_source(), region,
- picture_layer_tiling_->tiling_size());
+ picture_layer_tiling_->Invalidate(region);
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
@@ -126,8 +127,12 @@
void RunRasterIteratorConstructTest(const std::string& test_name,
const gfx::Rect& viewport) {
gfx::Size bounds(viewport.size());
- picture_layer_tiling_ =
- PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
+ LayerTreeSettings defaults;
+ picture_layer_tiling_ = PictureLayerTiling::Create(
+ 1, bounds, &picture_layer_tiling_client_,
+ defaults.max_tiles_for_interest_area,
+ defaults.skewport_target_time_in_seconds,
+ defaults.skewport_extrapolation_limit_in_content_pixels);
picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
picture_layer_tiling_->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
Occlusion());
@@ -151,8 +156,12 @@
int num_tiles,
const gfx::Rect& viewport) {
gfx::Size bounds(10000, 10000);
- picture_layer_tiling_ =
- PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
+ LayerTreeSettings defaults;
+ picture_layer_tiling_ = PictureLayerTiling::Create(
+ 1, bounds, &picture_layer_tiling_client_,
+ defaults.max_tiles_for_interest_area,
+ defaults.skewport_target_time_in_seconds,
+ defaults.skewport_extrapolation_limit_in_content_pixels);
picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
picture_layer_tiling_->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
Occlusion());
diff --git a/cc/resources/picture_layer_tiling_set.cc b/cc/resources/picture_layer_tiling_set.cc
index 51896a5..a3348bc 100644
--- a/cc/resources/picture_layer_tiling_set.cc
+++ b/cc/resources/picture_layer_tiling_set.cc
@@ -29,26 +29,98 @@
// static
scoped_ptr<PictureLayerTilingSet> PictureLayerTilingSet::Create(
- PictureLayerTilingClient* client) {
- return make_scoped_ptr(new PictureLayerTilingSet(client));
+ PictureLayerTilingClient* client,
+ size_t max_tiles_for_interest_area,
+ float skewport_target_time_in_seconds,
+ int skewport_extrapolation_limit_in_content_pixels) {
+ return make_scoped_ptr(new PictureLayerTilingSet(
+ client, max_tiles_for_interest_area, skewport_target_time_in_seconds,
+ skewport_extrapolation_limit_in_content_pixels));
}
-PictureLayerTilingSet::PictureLayerTilingSet(PictureLayerTilingClient* client)
- : client_(client) {
+PictureLayerTilingSet::PictureLayerTilingSet(
+ PictureLayerTilingClient* client,
+ size_t max_tiles_for_interest_area,
+ float skewport_target_time_in_seconds,
+ int skewport_extrapolation_limit_in_content_pixels)
+ : max_tiles_for_interest_area_(max_tiles_for_interest_area),
+ skewport_target_time_in_seconds_(skewport_target_time_in_seconds),
+ skewport_extrapolation_limit_in_content_pixels_(
+ skewport_extrapolation_limit_in_content_pixels),
+ client_(client) {
}
PictureLayerTilingSet::~PictureLayerTilingSet() {
}
-void PictureLayerTilingSet::SetClient(PictureLayerTilingClient* client) {
- client_ = client;
- for (size_t i = 0; i < tilings_.size(); ++i)
- tilings_[i]->SetClient(client_);
-}
+void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSource(
+ RasterSource* raster_source,
+ const PictureLayerTilingSet* twin_set,
+ const gfx::Size& layer_bounds,
+ const Region& layer_invalidation,
+ float minimum_contents_scale) {
+ RemoveTilingsBelowScale(minimum_contents_scale);
-void PictureLayerTilingSet::RemoveTilesInRegion(const Region& region) {
- for (size_t i = 0; i < tilings_.size(); ++i)
- tilings_[i]->RemoveTilesInRegion(region);
+ // Copy over tilings that are shared with the |twin_set| tiling set (if it
+ // exists).
+ if (twin_set) {
+ for (PictureLayerTiling* twin_tiling : twin_set->tilings_) {
+ float contents_scale = twin_tiling->contents_scale();
+ DCHECK_GE(contents_scale, minimum_contents_scale);
+
+ PictureLayerTiling* this_tiling = FindTilingWithScale(contents_scale);
+ if (!this_tiling) {
+ scoped_ptr<PictureLayerTiling> new_tiling = PictureLayerTiling::Create(
+ contents_scale, layer_bounds, client_, max_tiles_for_interest_area_,
+ skewport_target_time_in_seconds_,
+ skewport_extrapolation_limit_in_content_pixels_);
+ tilings_.push_back(new_tiling.Pass());
+ this_tiling = tilings_.back();
+ }
+ this_tiling->CloneTilesAndPropertiesFrom(*twin_tiling);
+ }
+ }
+
+ // For unshared tilings, invalidate tiles and update them to the new raster
+ // source.
+ for (PictureLayerTiling* tiling : tilings_) {
+ if (twin_set && twin_set->FindTilingWithScale(tiling->contents_scale()))
+ continue;
+
+ tiling->Resize(layer_bounds);
+ tiling->Invalidate(layer_invalidation);
+ tiling->SetRasterSource(raster_source);
+ // This is needed for cases where the live tiles rect didn't change but
+ // recordings exist in the raster source that did not exist on the last
+ // raster source.
+ tiling->CreateMissingTilesInLiveTilesRect();
+
+ // If |twin_set| is present, use the resolutions from there. Otherwise leave
+ // all resolutions as they are.
+ if (twin_set)
+ tiling->set_resolution(NON_IDEAL_RESOLUTION);
+ }
+
+ tilings_.sort(LargestToSmallestScaleFunctor());
+
+#if DCHECK_IS_ON
+ for (PictureLayerTiling* tiling : tilings_) {
+ DCHECK(tiling->tile_size() ==
+ client_->CalculateTileSize(tiling->tiling_size()))
+ << "tile_size: " << tiling->tile_size().ToString()
+ << " tiling_size: " << tiling->tiling_size().ToString()
+ << " CalculateTileSize: "
+ << client_->CalculateTileSize(tiling->tiling_size()).ToString();
+ }
+
+ if (!tilings_.empty()) {
+ size_t num_high_res = std::count_if(tilings_.begin(), tilings_.end(),
+ [](PictureLayerTiling* tiling) {
+ return tiling->resolution() == HIGH_RESOLUTION;
+ });
+ DCHECK_EQ(1u, num_high_res);
+ }
+#endif
}
void PictureLayerTilingSet::CleanUpTilings(
@@ -91,14 +163,6 @@
}
for (auto* tiling : to_remove) {
- PictureLayerTiling* twin_tiling =
- twin_set ? twin_set->FindTilingWithScale(tiling->contents_scale())
- : nullptr;
- // Only remove tilings from the twin layer if they have
- // NON_IDEAL_RESOLUTION.
- if (twin_tiling && twin_tiling->resolution() == NON_IDEAL_RESOLUTION)
- twin_set->Remove(twin_tiling);
-
PictureLayerTiling* recycled_twin_tiling =
recycled_twin_set
? recycled_twin_set->FindTilingWithScale(tiling->contents_scale())
@@ -113,16 +177,24 @@
}
}
+void PictureLayerTilingSet::RemoveNonIdealTilings() {
+ auto to_remove = tilings_.remove_if([](PictureLayerTiling* t) {
+ return t->resolution() == NON_IDEAL_RESOLUTION;
+ });
+ tilings_.erase(to_remove, tilings_.end());
+}
+
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,
- float minimum_contents_scale,
- RasterSource* raster_source) {
+bool PictureLayerTilingSet::SyncTilingsForTesting(
+ const PictureLayerTilingSet& other,
+ const gfx::Size& new_layer_bounds,
+ const Region& layer_invalidation,
+ float minimum_contents_scale,
+ RasterSource* raster_source) {
if (new_layer_bounds.IsEmpty()) {
RemoveAllTilings();
return false;
@@ -151,8 +223,9 @@
if (PictureLayerTiling* this_tiling = FindTilingWithScale(contents_scale)) {
this_tiling->set_resolution(other.tilings_[i]->resolution());
- this_tiling->UpdateTilesToCurrentRasterSource(
- raster_source, layer_invalidation, new_layer_bounds);
+ this_tiling->Resize(new_layer_bounds);
+ this_tiling->Invalidate(layer_invalidation);
+ this_tiling->SetRasterSource(raster_source);
this_tiling->CreateMissingTilesInLiveTilesRect();
if (this_tiling->resolution() == HIGH_RESOLUTION)
have_high_res_tiling = true;
@@ -166,9 +239,9 @@
continue;
}
scoped_ptr<PictureLayerTiling> new_tiling = PictureLayerTiling::Create(
- contents_scale,
- new_layer_bounds,
- client_);
+ contents_scale, new_layer_bounds, client_, max_tiles_for_interest_area_,
+ skewport_target_time_in_seconds_,
+ skewport_extrapolation_limit_in_content_pixels_);
new_tiling->set_resolution(other.tilings_[i]->resolution());
if (new_tiling->resolution() == HIGH_RESOLUTION)
have_high_res_tiling = true;
@@ -185,8 +258,10 @@
for (size_t i = 0; i < tilings_.size(); ++i)
DCHECK_NE(tilings_[i]->contents_scale(), contents_scale);
- tilings_.push_back(
- PictureLayerTiling::Create(contents_scale, layer_bounds, client_));
+ tilings_.push_back(PictureLayerTiling::Create(
+ contents_scale, layer_bounds, client_, max_tiles_for_interest_area_,
+ skewport_target_time_in_seconds_,
+ skewport_extrapolation_limit_in_content_pixels_));
PictureLayerTiling* appended = tilings_.back();
tilings_.sort(LargestToSmallestScaleFunctor());
@@ -222,6 +297,14 @@
return *iter;
}
+void PictureLayerTilingSet::RemoveTilingsBelowScale(float minimum_scale) {
+ auto to_remove =
+ tilings_.remove_if([minimum_scale](PictureLayerTiling* tiling) {
+ return tiling->contents_scale() < minimum_scale;
+ });
+ tilings_.erase(to_remove, tilings_.end());
+}
+
void PictureLayerTilingSet::RemoveAllTilings() {
tilings_.clear();
}
diff --git a/cc/resources/picture_layer_tiling_set.h b/cc/resources/picture_layer_tiling_set.h
index f0d0fd7..4038b32 100644
--- a/cc/resources/picture_layer_tiling_set.h
+++ b/cc/resources/picture_layer_tiling_set.h
@@ -38,31 +38,42 @@
};
static scoped_ptr<PictureLayerTilingSet> Create(
- PictureLayerTilingClient* client);
+ PictureLayerTilingClient* client,
+ size_t max_tiles_for_interest_area,
+ float skewport_target_time_in_seconds,
+ int skewport_extrapolation_limit_in_content);
~PictureLayerTilingSet();
- void SetClient(PictureLayerTilingClient* client);
const PictureLayerTilingClient* client() const { return client_; }
- void RemoveTilesInRegion(const Region& region);
void CleanUpTilings(float min_acceptable_high_res_scale,
float max_acceptable_high_res_scale,
const std::vector<PictureLayerTiling*>& needed_tilings,
bool should_have_low_res,
PictureLayerTilingSet* twin_set,
PictureLayerTilingSet* recycled_twin_set);
-
+ void RemoveNonIdealTilings();
// Make this set of tilings match the same set of content scales from |other|.
// Delete any tilings that don't meet |minimum_contents_scale|. Recreate
// any tiles that intersect |layer_invalidation|. Update the size of all
// tilings to |new_layer_bounds|.
// Returns true if we had at least one high res tiling synced.
- bool SyncTilings(const PictureLayerTilingSet& other,
- const gfx::Size& new_layer_bounds,
- const Region& layer_invalidation,
- float minimum_contents_scale,
- RasterSource* raster_source);
+ // TODO(danakj): Remove this !!!
+ bool SyncTilingsForTesting(const PictureLayerTilingSet& other,
+ const gfx::Size& new_layer_bounds,
+ const Region& layer_invalidation,
+ float minimum_contents_scale,
+ RasterSource* raster_source);
+
+ void UpdateTilingsToCurrentRasterSource(
+ RasterSource* raster_source,
+ const PictureLayerTilingSet* twin_set,
+ // TODO(danakj): Don't need to pass layer bounds here, we have the raster
+ // source already, and they are the same as the raster source size.
+ const gfx::Size& layer_bounds,
+ const Region& layer_invalidation,
+ float minimum_contents_scale);
PictureLayerTiling* AddTiling(float contents_scale,
const gfx::Size& layer_bounds);
@@ -89,6 +100,9 @@
// exist.
float GetMaximumContentsScale() const;
+ // Removes all tilings with a contents scale < |minimum_scale|.
+ void RemoveTilingsBelowScale(float minimum_scale);
+
// Remove all tilings.
void RemoveAllTilings();
@@ -155,14 +169,22 @@
TilingRange GetTilingRange(TilingRangeType type) const;
private:
- explicit PictureLayerTilingSet(PictureLayerTilingClient* client);
+ explicit PictureLayerTilingSet(
+ PictureLayerTilingClient* client,
+ size_t max_tiles_for_interest_area,
+ float skewport_target_time_in_seconds,
+ int skewport_extrapolation_limit_in_content_pixels);
// Remove one tiling.
void Remove(PictureLayerTiling* tiling);
- PictureLayerTilingClient* client_;
ScopedPtrVector<PictureLayerTiling> tilings_;
+ const size_t max_tiles_for_interest_area_;
+ const float skewport_target_time_in_seconds_;
+ const int skewport_extrapolation_limit_in_content_pixels_;
+ PictureLayerTilingClient* client_;
+
friend class Iterator;
DISALLOW_COPY_AND_ASSIGN(PictureLayerTilingSet);
};
diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc
index 7acc55b..cfde42e 100644
--- a/cc/resources/picture_layer_tiling_set_unittest.cc
+++ b/cc/resources/picture_layer_tiling_set_unittest.cc
@@ -18,10 +18,19 @@
namespace cc {
namespace {
+scoped_ptr<PictureLayerTilingSet> CreateTilingSet(
+ PictureLayerTilingClient* client) {
+ LayerTreeSettings defaults;
+ return PictureLayerTilingSet::Create(
+ client, defaults.max_tiles_for_interest_area,
+ defaults.skewport_target_time_in_seconds,
+ defaults.skewport_extrapolation_limit_in_content_pixels);
+}
+
TEST(PictureLayerTilingSetTest, NoResources) {
FakePictureLayerTilingClient client;
gfx::Size layer_bounds(1000, 800);
- auto set = PictureLayerTilingSet::Create(&client);
+ auto set = CreateTilingSet(&client);
client.SetTileSize(gfx::Size(256, 256));
set->AddTiling(1.0, layer_bounds);
@@ -59,7 +68,7 @@
PictureLayerTiling* high_res_tiling;
PictureLayerTiling* low_res_tiling;
- auto set = PictureLayerTilingSet::Create(&client);
+ auto set = CreateTilingSet(&client);
set->AddTiling(2.0, layer_bounds);
high_res_tiling = set->AddTiling(1.0, layer_bounds);
high_res_tiling->set_resolution(HIGH_RESOLUTION);
@@ -91,7 +100,7 @@
EXPECT_EQ(4u, lower_than_low_res_range.start);
EXPECT_EQ(5u, lower_than_low_res_range.end);
- auto set_without_low_res = PictureLayerTilingSet::Create(&client);
+ auto set_without_low_res = CreateTilingSet(&client);
set_without_low_res->AddTiling(2.0, layer_bounds);
high_res_tiling = set_without_low_res->AddTiling(1.0, layer_bounds);
high_res_tiling->set_resolution(HIGH_RESOLUTION);
@@ -121,7 +130,7 @@
PictureLayerTilingSet::LOWER_THAN_LOW_RES);
EXPECT_EQ(0u, lower_than_low_res_range.end - lower_than_low_res_range.start);
- auto set_with_only_high_and_low_res = PictureLayerTilingSet::Create(&client);
+ auto set_with_only_high_and_low_res = CreateTilingSet(&client);
high_res_tiling =
set_with_only_high_and_low_res->AddTiling(1.0, layer_bounds);
high_res_tiling->set_resolution(HIGH_RESOLUTION);
@@ -153,7 +162,7 @@
PictureLayerTilingSet::LOWER_THAN_LOW_RES);
EXPECT_EQ(0u, lower_than_low_res_range.end - lower_than_low_res_range.start);
- auto set_with_only_high_res = PictureLayerTilingSet::Create(&client);
+ auto set_with_only_high_res = CreateTilingSet(&client);
high_res_tiling = set_with_only_high_res->AddTiling(1.0, layer_bounds);
high_res_tiling->set_resolution(HIGH_RESOLUTION);
@@ -209,7 +218,7 @@
client.SetTileSize(gfx::Size(256, 256));
client.set_tree(PENDING_TREE);
gfx::Size layer_bounds(1000, 800);
- auto set = PictureLayerTilingSet::Create(&client);
+ auto set = CreateTilingSet(&client);
float scale = min_scale;
for (int i = 0; i < num_tilings; ++i, scale += scale_increment) {
@@ -288,8 +297,8 @@
source_client_.set_tree(PENDING_TREE);
target_client_.SetTileSize(tile_size_);
target_client_.set_tree(PENDING_TREE);
- source_ = PictureLayerTilingSet::Create(&source_client_);
- target_ = PictureLayerTilingSet::Create(&target_client_);
+ source_ = CreateTilingSet(&source_client_);
+ target_ = CreateTilingSet(&target_client_);
}
// Sync from source to target.
@@ -301,8 +310,9 @@
for (size_t i = 0; i < target_->num_tilings(); ++i)
target_->tiling_at(i)->CreateAllTilesForTesting();
- target_->SyncTilings(*source_.get(), new_bounds, invalidation,
- minimum_scale, target_client_.raster_source());
+ target_->SyncTilingsForTesting(*source_.get(), new_bounds, invalidation,
+ minimum_scale,
+ target_client_.raster_source());
}
void SyncTilings(const gfx::Size& new_bounds) {
Region invalidation;
diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc
index 9190b98..1ed4613 100644
--- a/cc/resources/picture_layer_tiling_unittest.cc
+++ b/cc/resources/picture_layer_tiling_unittest.cc
@@ -54,17 +54,16 @@
static scoped_ptr<TestablePictureLayerTiling> Create(
float contents_scale,
const gfx::Size& layer_bounds,
- PictureLayerTilingClient* client) {
+ PictureLayerTilingClient* client,
+ const LayerTreeSettings& settings) {
return make_scoped_ptr(new TestablePictureLayerTiling(
- contents_scale,
- layer_bounds,
- client));
+ contents_scale, layer_bounds, client,
+ settings.max_tiles_for_interest_area,
+ settings.skewport_target_time_in_seconds,
+ settings.skewport_extrapolation_limit_in_content_pixels));
}
gfx::Rect live_tiles_rect() const { return live_tiles_rect_; }
- bool eviction_tiles_cache_valid() const {
- return eviction_tiles_cache_valid_;
- }
using PictureLayerTiling::ComputeSkewport;
using PictureLayerTiling::RemoveTileAt;
@@ -72,8 +71,16 @@
protected:
TestablePictureLayerTiling(float contents_scale,
const gfx::Size& layer_bounds,
- PictureLayerTilingClient* client)
- : PictureLayerTiling(contents_scale, layer_bounds, client) { }
+ PictureLayerTilingClient* client,
+ size_t max_tiles_for_interest_area,
+ float skewport_target_time,
+ int skewport_extrapolation_limit)
+ : PictureLayerTiling(contents_scale,
+ layer_bounds,
+ client,
+ max_tiles_for_interest_area,
+ skewport_target_time,
+ skewport_extrapolation_limit) {}
};
class PictureLayerTilingIteratorTest : public testing::Test {
@@ -86,9 +93,8 @@
const gfx::Size& layer_bounds) {
client_.SetTileSize(tile_size);
client_.set_tree(PENDING_TREE);
- tiling_ = TestablePictureLayerTiling::Create(contents_scale,
- layer_bounds,
- &client_);
+ tiling_ = TestablePictureLayerTiling::Create(contents_scale, layer_bounds,
+ &client_, LayerTreeSettings());
}
void SetLiveRectAndVerifyTiles(const gfx::Rect& live_tiles_rect) {
@@ -180,10 +186,6 @@
VerifyTilesExactlyCoverRect(rect_scale, dest_rect, clamped_rect);
}
- void set_max_tiles_for_interest_area(size_t area) {
- client_.set_max_tiles_for_interest_area(area);
- }
-
protected:
FakePictureLayerTilingClient client_;
scoped_ptr<TestablePictureLayerTiling> tiling_;
@@ -208,14 +210,15 @@
Region invalidation =
SubtractRegions(gfx::Rect(tile_size), gfx::Rect(original_layer_size));
- tiling_->UpdateTilesToCurrentRasterSource(client_.raster_source(),
- invalidation, gfx::Size(200, 200));
+ tiling_->Resize(gfx::Size(200, 200));
+ EXPECT_TRUE(tiling_->TileAt(0, 0));
+ tiling_->Invalidate(invalidation);
EXPECT_FALSE(tiling_->TileAt(0, 0));
}
TEST_F(PictureLayerTilingIteratorTest, CreateMissingTilesStaysInsideLiveRect) {
// The tiling has three rows and columns.
- Initialize(gfx::Size(100, 100), 1, gfx::Size(250, 250));
+ Initialize(gfx::Size(100, 100), 1.f, gfx::Size(250, 250));
EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_y());
@@ -243,7 +246,7 @@
TEST_F(PictureLayerTilingIteratorTest, ResizeTilingOverTileBorders) {
// The tiling has four rows and three columns.
- Initialize(gfx::Size(100, 100), 1, gfx::Size(250, 350));
+ Initialize(gfx::Size(100, 100), 1.f, gfx::Size(250, 350));
EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
EXPECT_EQ(4, tiling_->TilingDataForTesting().num_tiles_y());
@@ -263,9 +266,7 @@
// Shrink the tiling so that the last tile row/column is entirely in the
// border pixels of the interior tiles. That row/column is removed.
- Region invalidation;
- tiling_->UpdateTilesToCurrentRasterSource(
- client_.raster_source(), invalidation, gfx::Size(right + 1, bottom + 1));
+ tiling_->Resize(gfx::Size(right + 1, bottom + 1));
EXPECT_EQ(2, tiling_->TilingDataForTesting().num_tiles_x());
EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_y());
@@ -282,8 +283,7 @@
// Growing outside the current right/bottom tiles border pixels should create
// the tiles again, even though the live rect has not changed size.
- tiling_->UpdateTilesToCurrentRasterSource(
- client_.raster_source(), invalidation, gfx::Size(right + 2, bottom + 2));
+ tiling_->Resize(gfx::Size(right + 2, bottom + 2));
EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
EXPECT_EQ(4, tiling_->TilingDataForTesting().num_tiles_y());
@@ -306,7 +306,7 @@
TEST_F(PictureLayerTilingIteratorTest, ResizeLiveTileRectOverTileBorders) {
// The tiling has three rows and columns.
- Initialize(gfx::Size(100, 100), 1, gfx::Size(250, 350));
+ Initialize(gfx::Size(100, 100), 1.f, gfx::Size(250, 350));
EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
EXPECT_EQ(4, tiling_->TilingDataForTesting().num_tiles_y());
@@ -371,7 +371,7 @@
TEST_F(PictureLayerTilingIteratorTest, ResizeLiveTileRectOverSameTiles) {
// The tiling has four rows and three columns.
- Initialize(gfx::Size(100, 100), 1, gfx::Size(250, 350));
+ Initialize(gfx::Size(100, 100), 1.f, gfx::Size(250, 350));
EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
EXPECT_EQ(4, tiling_->TilingDataForTesting().num_tiles_y());
@@ -419,8 +419,9 @@
Region invalidation =
SubtractRegions(gfx::Rect(tile_size), gfx::Rect(original_layer_size));
- tiling_->UpdateTilesToCurrentRasterSource(client_.raster_source(),
- invalidation, gfx::Size(200, 200));
+ tiling_->Resize(gfx::Size(200, 200));
+ EXPECT_TRUE(tiling_->TileAt(0, 0));
+ tiling_->Invalidate(invalidation);
EXPECT_FALSE(tiling_->TileAt(0, 0));
// The original tile was the same size after resize, but it would include new
@@ -430,7 +431,7 @@
}
TEST_F(PictureLayerTilingIteratorTest, LiveTilesExactlyCoverLiveTileRect) {
- Initialize(gfx::Size(100, 100), 1, gfx::Size(1099, 801));
+ Initialize(gfx::Size(100, 100), 1.f, gfx::Size(1099, 801));
SetLiveRectAndVerifyTiles(gfx::Rect(100, 100));
SetLiveRectAndVerifyTiles(gfx::Rect(101, 99));
SetLiveRectAndVerifyTiles(gfx::Rect(1099, 1));
@@ -440,13 +441,13 @@
}
TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsNoScale) {
- Initialize(gfx::Size(100, 100), 1, gfx::Size(1099, 801));
+ Initialize(gfx::Size(100, 100), 1.f, gfx::Size(1099, 801));
VerifyTilesExactlyCoverRect(1, gfx::Rect());
VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1099, 801));
VerifyTilesExactlyCoverRect(1, gfx::Rect(52, 83, 789, 412));
// With borders, a size of 3x3 = 1 pixel of content.
- Initialize(gfx::Size(3, 3), 1, gfx::Size(10, 10));
+ Initialize(gfx::Size(3, 3), 1.f, gfx::Size(10, 10));
VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1, 1));
VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 2, 2));
VerifyTilesExactlyCoverRect(1, gfx::Rect(1, 1, 2, 2));
@@ -532,7 +533,6 @@
TEST(PictureLayerTilingTest, SkewportLimits) {
FakePictureLayerTilingClient client;
- client.set_skewport_extrapolation_limit_in_content_pixels(75);
client.set_tree(ACTIVE_TREE);
scoped_ptr<TestablePictureLayerTiling> tiling;
@@ -540,7 +540,11 @@
gfx::Size layer_bounds(200, 200);
client.SetTileSize(gfx::Size(100, 100));
- tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
+ LayerTreeSettings settings;
+ settings.max_tiles_for_interest_area = 10000;
+ settings.skewport_extrapolation_limit_in_content_pixels = 75;
+ tiling =
+ TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client, settings);
tiling->ComputeTilePriorityRects(viewport, 1.f, 1.0, Occlusion());
@@ -606,7 +610,8 @@
client.SetTileSize(gfx::Size(100, 100));
client.set_tree(ACTIVE_TREE);
- tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
+ tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client,
+ LayerTreeSettings());
tiling->ComputeTilePriorityRects(viewport, 1.f, 1.0, Occlusion());
@@ -665,13 +670,16 @@
client.SetTileSize(gfx::Size(10, 10));
client.set_tree(ACTIVE_TREE);
+ LayerTreeSettings settings;
+ settings.max_tiles_for_interest_area = 10000;
// Tiling at 0.25 scale: this should create 47x47 tiles of size 10x10.
// The reason is that each tile has a one pixel border, so tile at (1, 2)
// for instance begins at (8, 16) pixels. So tile at (46, 46) will begin at
// (368, 368) and extend to the end of 1500 * 0.25 = 375 edge of the
// tiling.
- tiling = TestablePictureLayerTiling::Create(0.25f, layer_bounds, &client);
+ tiling = TestablePictureLayerTiling::Create(0.25f, layer_bounds, &client,
+ settings);
gfx::Rect viewport_in_content_space =
gfx::ToEnclosedRect(gfx::ScaleRect(viewport, 0.25f));
@@ -825,7 +833,8 @@
EXPECT_FLOAT_EQ(8.f, priority.distance_to_visible);
// Test additional scales.
- tiling = TestablePictureLayerTiling::Create(0.2f, layer_bounds, &client);
+ tiling = TestablePictureLayerTiling::Create(0.2f, layer_bounds, &client,
+ LayerTreeSettings());
tiling->ComputeTilePriorityRects(viewport, 1.0f, 4.0, Occlusion());
tiling->UpdateAllTilePrioritiesForTesting();
@@ -1085,8 +1094,11 @@
client.SetTileSize(gfx::Size(30, 30));
client.set_tree(ACTIVE_TREE);
+ LayerTreeSettings settings;
+ settings.max_tiles_for_interest_area = 10000;
- tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
+ tiling =
+ TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client, settings);
tiling->ComputeTilePriorityRects(viewport, 1.0f, 1.0, Occlusion());
tiling->UpdateAllTilePrioritiesForTesting();
@@ -1190,8 +1202,11 @@
client.SetTileSize(gfx::Size(30, 30));
client.set_tree(ACTIVE_TREE);
+ LayerTreeSettings settings;
+ settings.max_tiles_for_interest_area = 10000;
- tiling = TestablePictureLayerTiling::Create(1.f, layer_bounds, &client);
+ tiling =
+ TestablePictureLayerTiling::Create(1.f, layer_bounds, &client, settings);
tiling->ComputeTilePriorityRects(viewport, 1.0f, 1.0, Occlusion());
tiling->ComputeTilePriorityRects(moved_viewport, 1.0f, 2.0, Occlusion());
tiling->UpdateAllTilePrioritiesForTesting();
@@ -1326,14 +1341,19 @@
TEST_F(PictureLayerTilingIteratorTest,
TilesExistLargeViewportAndLayerWithSmallVisibleArea) {
gfx::Size layer_bounds(10000, 10000);
- Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
+ client_.SetTileSize(gfx::Size(100, 100));
+ client_.set_tree(PENDING_TREE);
+ LayerTreeSettings settings;
+ settings.max_tiles_for_interest_area = 1;
+
+ tiling_ =
+ TestablePictureLayerTiling::Create(1.f, layer_bounds, &client_, settings);
VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
gfx::Rect visible_rect(8000, 8000, 50, 50);
client_.set_tree(ACTIVE_TREE);
- set_max_tiles_for_interest_area(1);
tiling_->ComputeTilePriorityRects(visible_rect, // visible content rect
1.f, // current contents scale
1.0, // current frame time
@@ -1350,7 +1370,10 @@
client_.SetTileSize(tile_size);
client_.set_tree(PENDING_TREE);
- auto active_set = PictureLayerTilingSet::Create(&client_);
+ LayerTreeSettings defaults;
+ auto active_set = PictureLayerTilingSet::Create(
+ &client_, 10000, defaults.skewport_target_time_in_seconds,
+ defaults.skewport_extrapolation_limit_in_content_pixels);
active_set->AddTiling(1.f, layer_bounds);
@@ -1367,10 +1390,12 @@
base::Bind(&TileExists, true));
// Add the same tilings to the pending set.
- auto pending_set = PictureLayerTilingSet::Create(&client_);
+ auto pending_set = PictureLayerTilingSet::Create(
+ &client_, 10000, defaults.skewport_target_time_in_seconds,
+ defaults.skewport_extrapolation_limit_in_content_pixels);
Region invalidation;
- pending_set->SyncTilings(*active_set, layer_bounds, invalidation, 0.f,
- client_.raster_source());
+ pending_set->SyncTilingsForTesting(*active_set, layer_bounds, invalidation,
+ 0.f, client_.raster_source());
// The pending tiling starts with no tiles.
VerifyTiles(pending_set->tiling_at(0), 1.f, gfx::Rect(layer_bounds),
@@ -1407,8 +1432,8 @@
client.SetTileSize(gfx::Size(100, 100));
client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
- current_layer_bounds,
- &client);
+ current_layer_bounds, &client,
+ LayerTreeSettings());
tiling->ComputeTilePriorityRects(viewport_in_layer_space,
current_layer_contents_scale,
@@ -1461,8 +1486,8 @@
client.SetTileSize(gfx::Size(100, 100));
client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
- current_layer_bounds,
- &client);
+ current_layer_bounds, &client,
+ LayerTreeSettings());
tiling->ComputeTilePriorityRects(viewport_in_layer_space,
current_layer_contents_scale,
@@ -1525,8 +1550,8 @@
client.SetTileSize(gfx::Size(100, 100));
client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
- current_layer_bounds,
- &client);
+ current_layer_bounds, &client,
+ LayerTreeSettings());
tiling->ComputeTilePriorityRects(viewport_in_layer_space,
current_layer_contents_scale,
@@ -1583,8 +1608,8 @@
client.SetTileSize(gfx::Size(100, 100));
client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
- current_layer_bounds,
- &client);
+ current_layer_bounds, &client,
+ LayerTreeSettings());
tiling->ComputeTilePriorityRects(viewport_in_layer_space,
current_layer_contents_scale,
@@ -1665,8 +1690,8 @@
client.SetTileSize(gfx::Size(100, 100));
client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
- current_layer_bounds,
- &client);
+ current_layer_bounds, &client,
+ LayerTreeSettings());
tiling->ComputeTilePriorityRects(viewport_in_layer_space,
current_layer_contents_scale,
@@ -1757,8 +1782,8 @@
client.SetTileSize(gfx::Size(100, 100));
client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
- current_layer_bounds,
- &client);
+ current_layer_bounds, &client,
+ LayerTreeSettings());
tiling->ComputeTilePriorityRects(viewport_in_layer_space,
current_layer_contents_scale,
@@ -1818,9 +1843,11 @@
client.SetTileSize(gfx::Size(100, 100));
client.set_tree(ACTIVE_TREE);
+ LayerTreeSettings settings;
+ settings.max_tiles_for_interest_area = 10000;
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
- current_layer_bounds,
- &client);
+ current_layer_bounds, &client,
+ settings);
// previous ("last") frame
tiling->ComputeTilePriorityRects(viewport_in_layer_space,
@@ -1894,8 +1921,8 @@
client.SetTileSize(gfx::Size(100, 100));
client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
- current_layer_bounds,
- &client);
+ current_layer_bounds, &client,
+ LayerTreeSettings());
// previous ("last") frame
tiling->ComputeTilePriorityRects(viewport_in_layer_space,
@@ -1942,10 +1969,11 @@
active_client.SetTileSize(gfx::Size(100, 100));
active_client.set_tree(ACTIVE_TREE);
- active_client.set_max_tiles_for_interest_area(10);
+ LayerTreeSettings settings;
+ settings.max_tiles_for_interest_area = 10;
active_tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
gfx::Size(10000, 10000),
- &active_client);
+ &active_client, settings);
// Create all tiles on this tiling.
active_tiling->ComputeTilePriorityRects(gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f,
Occlusion());
@@ -1954,12 +1982,11 @@
recycle_client.SetTileSize(gfx::Size(100, 100));
recycle_client.set_tree(PENDING_TREE);
recycle_client.set_twin_tiling(active_tiling.get());
- recycle_client.set_max_tiles_for_interest_area(10);
scoped_ptr<TestablePictureLayerTiling> recycle_tiling;
- recycle_tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
- gfx::Size(10000, 10000),
- &recycle_client);
+ recycle_tiling = TestablePictureLayerTiling::Create(
+ 1.0f, // contents_scale
+ gfx::Size(10000, 10000), &recycle_client, settings);
// Create all tiles on the second tiling. All tiles should be shared.
recycle_tiling->ComputeTilePriorityRects(gfx::Rect(0, 0, 100, 100), 1.0f,
@@ -1986,9 +2013,9 @@
active_tiling->ComputeTilePriorityRects(gfx::Rect(0, 0, 100, 100), 1.0f, 3.0,
Occlusion());
- // Ensure that we now have a tile here, but the recycle tiling does not.
+ // Ensure that we now have a tile here on both tilings again.
EXPECT_TRUE(active_tiling->TileAt(0, 0));
- EXPECT_FALSE(recycle_tiling->TileAt(0, 0));
+ EXPECT_TRUE(recycle_tiling->TileAt(0, 0));
}
TEST(PictureLayerTilingTest, RecycledTilesClearedOnReset) {
@@ -1997,9 +2024,9 @@
active_client.SetTileSize(gfx::Size(100, 100));
active_client.set_tree(ACTIVE_TREE);
- active_tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
- gfx::Size(100, 100),
- &active_client);
+ active_tiling = TestablePictureLayerTiling::Create(
+ 1.0f, // contents_scale
+ gfx::Size(100, 100), &active_client, LayerTreeSettings());
// Create all tiles on this tiling.
active_tiling->ComputeTilePriorityRects(gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f,
Occlusion());
@@ -2008,12 +2035,13 @@
recycle_client.SetTileSize(gfx::Size(100, 100));
recycle_client.set_tree(PENDING_TREE);
recycle_client.set_twin_tiling(active_tiling.get());
- recycle_client.set_max_tiles_for_interest_area(10);
+ LayerTreeSettings settings;
+ settings.max_tiles_for_interest_area = 10;
scoped_ptr<TestablePictureLayerTiling> recycle_tiling;
- recycle_tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
- gfx::Size(100, 100),
- &recycle_client);
+ recycle_tiling = TestablePictureLayerTiling::Create(
+ 1.0f, // contents_scale
+ gfx::Size(100, 100), &recycle_client, settings);
// Create all tiles on the recycle tiling. All tiles should be shared.
recycle_tiling->ComputeTilePriorityRects(gfx::Rect(0, 0, 100, 100), 1.0f,
@@ -2037,7 +2065,7 @@
TEST_F(PictureLayerTilingIteratorTest, ResizeTilesAndUpdateToCurrent) {
// The tiling has four rows and three columns.
- Initialize(gfx::Size(150, 100), 1, gfx::Size(250, 150));
+ Initialize(gfx::Size(150, 100), 1.f, gfx::Size(250, 150));
tiling_->CreateAllTilesForTesting();
EXPECT_EQ(150, tiling_->TilingDataForTesting().max_texture_size().width());
EXPECT_EQ(100, tiling_->TilingDataForTesting().max_texture_size().height());
@@ -2050,9 +2078,7 @@
EXPECT_EQ(150, tiling_->TilingDataForTesting().max_texture_size().width());
EXPECT_EQ(100, tiling_->TilingDataForTesting().max_texture_size().height());
- Region invalidation;
- tiling_->UpdateTilesToCurrentRasterSource(client_.raster_source(),
- invalidation, gfx::Size(250, 150));
+ tiling_->Resize(gfx::Size(250, 150));
// Tile size in the tiling should be resized to 250x200.
EXPECT_EQ(250, tiling_->TilingDataForTesting().max_texture_size().width());
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc
index 698fe2c..31bc2d3 100644
--- a/cc/resources/picture_pile.cc
+++ b/cc/resources/picture_pile.cc
@@ -693,9 +693,10 @@
if (it->second.GetPicture() != picture)
return;
}
- skia::AnalysisCanvas canvas(recorded_viewport_.width(),
- recorded_viewport_.height());
- canvas.translate(-recorded_viewport_.x(), -recorded_viewport_.y());
+
+ gfx::Size layer_size = GetSize();
+ skia::AnalysisCanvas canvas(layer_size.width(), layer_size.height());
+
picture->Raster(&canvas, nullptr, Region(), 1.0f);
is_solid_color_ = canvas.GetColorIfSolid(&solid_color_);
}
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index c0e8f1b..5b8bcd2 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -622,21 +622,11 @@
RGBA_8888);
} else {
DCHECK(mailbox.IsSharedMemory());
- base::SharedMemory* shared_memory = mailbox.shared_memory();
- DCHECK(shared_memory->memory());
- uint8_t* pixels = reinterpret_cast<uint8_t*>(shared_memory->memory());
+ SharedBitmap* shared_bitmap = mailbox.shared_bitmap();
+ uint8_t* pixels = shared_bitmap->pixels();
DCHECK(pixels);
- scoped_ptr<SharedBitmap> shared_bitmap;
- if (shared_bitmap_manager_) {
- shared_bitmap =
- shared_bitmap_manager_->GetBitmapForSharedMemory(shared_memory);
- }
- resource = Resource(pixels,
- shared_bitmap.release(),
- mailbox.shared_memory_size(),
- Resource::External,
- GL_LINEAR,
- GL_CLAMP_TO_EDGE);
+ resource = Resource(pixels, shared_bitmap, mailbox.shared_memory_size(),
+ Resource::External, GL_LINEAR, GL_CLAMP_TO_EDGE);
}
resource.allocated = true;
resource.mailbox = mailbox;
@@ -714,13 +704,8 @@
}
} else {
DCHECK(resource->mailbox.IsSharedMemory());
- base::SharedMemory* shared_memory = resource->mailbox.shared_memory();
- if (resource->pixels && shared_memory) {
- DCHECK(shared_memory->memory() == resource->pixels);
- resource->pixels = NULL;
- delete resource->shared_bitmap;
- resource->shared_bitmap = NULL;
- }
+ resource->shared_bitmap = nullptr;
+ resource->pixels = nullptr;
}
resource->release_callback_impl.Run(
sync_point, lost_resource, blocking_main_thread_task_runner_);
@@ -1123,11 +1108,6 @@
!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)
- return nullptr;
-
resource_provider_->LazyAllocate(resource_);
GrBackendTextureDesc desc;
@@ -1137,6 +1117,8 @@
desc.fConfig = ToGrPixelConfig(resource_->format);
desc.fOrigin = kTopLeft_GrSurfaceOrigin;
desc.fTextureHandle = resource_->gl_id;
+
+ class GrContext* gr_context = resource_provider_->GrContext();
skia::RefPtr<GrTexture> gr_texture =
skia::AdoptRef(gr_context->wrapBackendTexture(desc));
if (!gr_texture)
diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc
index 2c8ed58..53741ab 100644
--- a/cc/resources/resource_provider_unittest.cc
+++ b/cc/resources/resource_provider_unittest.cc
@@ -59,15 +59,15 @@
*release_main_thread_task_runner = main_thread_task_runner;
}
-static void SharedMemoryReleaseCallback(
- scoped_ptr<base::SharedMemory> memory,
+static void SharedBitmapReleaseCallback(
+ scoped_ptr<SharedBitmap> bitmap,
uint32 sync_point,
bool lost_resource,
BlockingTaskRunner* main_thread_task_runner) {
}
-static void ReleaseSharedMemoryCallback(
- scoped_ptr<base::SharedMemory> shared_memory,
+static void ReleaseSharedBitmapCallback(
+ scoped_ptr<SharedBitmap> shared_bitmap,
bool* release_called,
uint32* release_sync_point,
bool* lost_resource_result,
@@ -79,15 +79,16 @@
*lost_resource_result = lost_resource;
}
-static scoped_ptr<base::SharedMemory> CreateAndFillSharedMemory(
+static scoped_ptr<SharedBitmap> CreateAndFillSharedBitmap(
+ SharedBitmapManager* manager,
const gfx::Size& size,
uint32_t value) {
- scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
- CHECK(shared_memory->CreateAndMapAnonymous(4 * size.GetArea()));
- uint32_t* pixels = reinterpret_cast<uint32_t*>(shared_memory->memory());
+ scoped_ptr<SharedBitmap> shared_bitmap = manager->AllocateSharedBitmap(size);
+ CHECK(shared_bitmap);
+ uint32_t* pixels = reinterpret_cast<uint32_t*>(shared_bitmap->pixels());
CHECK(pixels);
std::fill_n(pixels, size.GetArea(), value);
- return shared_memory.Pass();
+ return shared_bitmap.Pass();
}
class TextureStateTrackingContext : public TestWebGraphicsContext3D {
@@ -466,32 +467,26 @@
*sync_point = child_context_->insertSyncPoint();
EXPECT_LT(0u, *sync_point);
- scoped_ptr<base::SharedMemory> shared_memory;
+ scoped_ptr<SharedBitmap> shared_bitmap;
scoped_ptr<SingleReleaseCallbackImpl> callback =
- SingleReleaseCallbackImpl::Create(
- base::Bind(ReleaseSharedMemoryCallback,
- base::Passed(&shared_memory),
- release_called,
- release_sync_point,
- lost_resource));
+ SingleReleaseCallbackImpl::Create(base::Bind(
+ ReleaseSharedBitmapCallback, base::Passed(&shared_bitmap),
+ release_called, release_sync_point, lost_resource));
return child_resource_provider_->CreateResourceFromTextureMailbox(
TextureMailbox(gpu_mailbox, GL_TEXTURE_2D, *sync_point),
callback.Pass());
} else {
gfx::Size size(64, 64);
- scoped_ptr<base::SharedMemory> shared_memory(
- CreateAndFillSharedMemory(size, 0));
+ scoped_ptr<SharedBitmap> shared_bitmap(
+ CreateAndFillSharedBitmap(shared_bitmap_manager_.get(), size, 0));
- base::SharedMemory* shared_memory_ptr = shared_memory.get();
+ SharedBitmap* shared_bitmap_ptr = shared_bitmap.get();
scoped_ptr<SingleReleaseCallbackImpl> callback =
- SingleReleaseCallbackImpl::Create(
- base::Bind(ReleaseSharedMemoryCallback,
- base::Passed(&shared_memory),
- release_called,
- release_sync_point,
- lost_resource));
+ SingleReleaseCallbackImpl::Create(base::Bind(
+ ReleaseSharedBitmapCallback, base::Passed(&shared_bitmap),
+ release_called, release_sync_point, lost_resource));
return child_resource_provider_->CreateResourceFromTextureMailbox(
- TextureMailbox(shared_memory_ptr, size), callback.Pass());
+ TextureMailbox(shared_bitmap_ptr, size), callback.Pass());
}
}
@@ -982,14 +977,14 @@
uint8_t data2[4] = { 5, 5, 5, 5 };
child_resource_provider_->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
- scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
- shared_memory->CreateAndMapAnonymous(1);
- base::SharedMemory* shared_memory_ptr = shared_memory.get();
+ scoped_ptr<SharedBitmap> shared_bitmap(CreateAndFillSharedBitmap(
+ shared_bitmap_manager_.get(), gfx::Size(1, 1), 0));
+ SharedBitmap* shared_bitmap_ptr = shared_bitmap.get();
ResourceProvider::ResourceId id3 =
child_resource_provider_->CreateResourceFromTextureMailbox(
- TextureMailbox(shared_memory_ptr, gfx::Size(1, 1)),
+ TextureMailbox(shared_bitmap_ptr, gfx::Size(1, 1)),
SingleReleaseCallbackImpl::Create(base::Bind(
- &SharedMemoryReleaseCallback, base::Passed(&shared_memory))));
+ &SharedBitmapReleaseCallback, base::Passed(&shared_bitmap))));
ReturnedResourceArray returned_to_child;
int child_id =
@@ -2556,8 +2551,8 @@
gfx::Size size(64, 64);
const uint32_t kBadBeef = 0xbadbeef;
- scoped_ptr<base::SharedMemory> shared_memory(
- CreateAndFillSharedMemory(size, kBadBeef));
+ scoped_ptr<SharedBitmap> shared_bitmap(
+ CreateAndFillSharedBitmap(shared_bitmap_manager_.get(), size, kBadBeef));
FakeOutputSurfaceClient output_surface_client;
scoped_ptr<OutputSurface> output_surface(
@@ -2582,7 +2577,7 @@
&release_sync_point,
&lost_resource,
&main_thread_task_runner));
- TextureMailbox mailbox(shared_memory.get(), size);
+ TextureMailbox mailbox(shared_bitmap.get(), size);
ResourceProvider::ResourceId id =
resource_provider->CreateResourceFromTextureMailbox(
diff --git a/cc/resources/scoped_gpu_raster.cc b/cc/resources/scoped_gpu_raster.cc
index 517c7a7..9d1dfe5 100644
--- a/cc/resources/scoped_gpu_raster.cc
+++ b/cc/resources/scoped_gpu_raster.cc
@@ -30,18 +30,14 @@
gl->PushGroupMarkerEXT(0, "GpuRasterization");
class GrContext* gr_context = context_provider_->GrContext();
- // TODO(sohanjg): Remove when TestContextProvider gives a GrContext.
- if (gr_context)
- gr_context->resetContext();
+ gr_context->resetContext();
}
void ScopedGpuRaster::EndGpuRaster() {
GLES2Interface* gl = context_provider_->ContextGL();
class GrContext* gr_context = context_provider_->GrContext();
- // TODO(sohanjg): Remove when TestContextProvider gives a GrContext.
- if (gr_context)
- gr_context->flush();
+ gr_context->flush();
// TODO(alokp): Use a trace macro to push/pop markers.
// Using push/pop functions directly incurs cost to evaluate function
diff --git a/cc/resources/shared_bitmap.h b/cc/resources/shared_bitmap.h
index bbf0823..6980afb 100644
--- a/cc/resources/shared_bitmap.h
+++ b/cc/resources/shared_bitmap.h
@@ -6,13 +6,10 @@
#define CC_RESOURCES_SHARED_BITMAP_H_
#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "ui/gfx/geometry/size.h"
-namespace base { class SharedMemory; }
-
namespace cc {
typedef gpu::Mailbox SharedBitmapId;
@@ -24,8 +21,6 @@
uint8* pixels() { return pixels_; }
- virtual base::SharedMemory* memory() = 0;
-
const SharedBitmapId& id() { return id_; }
// Returns true if the size is valid and false otherwise.
diff --git a/cc/resources/shared_bitmap_manager.h b/cc/resources/shared_bitmap_manager.h
index fe61b09..d5239e4 100644
--- a/cc/resources/shared_bitmap_manager.h
+++ b/cc/resources/shared_bitmap_manager.h
@@ -6,6 +6,7 @@
#define CC_RESOURCES_SHARED_BITMAP_MANAGER_H_
#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
#include "cc/resources/shared_bitmap.h"
#include "ui/gfx/geometry/size.h"
@@ -21,8 +22,6 @@
virtual scoped_ptr<SharedBitmap> GetSharedBitmapFromId(
const gfx::Size&,
const SharedBitmapId&) = 0;
- virtual scoped_ptr<SharedBitmap> GetBitmapForSharedMemory(
- base::SharedMemory*) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(SharedBitmapManager);
diff --git a/cc/resources/texture_mailbox.cc b/cc/resources/texture_mailbox.cc
index 07cbec0..9bf242e 100644
--- a/cc/resources/texture_mailbox.cc
+++ b/cc/resources/texture_mailbox.cc
@@ -9,25 +9,28 @@
namespace cc {
-TextureMailbox::TextureMailbox() : shared_memory_(NULL) {}
+TextureMailbox::TextureMailbox() : shared_bitmap_(NULL) {
+}
TextureMailbox::TextureMailbox(const gpu::MailboxHolder& mailbox_holder)
: mailbox_holder_(mailbox_holder),
- shared_memory_(NULL),
+ shared_bitmap_(NULL),
allow_overlay_(false),
- nearest_neighbor_(false) {}
+ nearest_neighbor_(false) {
+}
TextureMailbox::TextureMailbox(const gpu::Mailbox& mailbox,
uint32 target,
uint32 sync_point)
: mailbox_holder_(mailbox, target, sync_point),
- shared_memory_(NULL),
+ shared_bitmap_(NULL),
allow_overlay_(false),
- nearest_neighbor_(false) {}
+ nearest_neighbor_(false) {
+}
-TextureMailbox::TextureMailbox(base::SharedMemory* shared_memory,
+TextureMailbox::TextureMailbox(SharedBitmap* shared_bitmap,
const gfx::Size& size)
- : shared_memory_(shared_memory),
+ : shared_bitmap_(shared_bitmap),
shared_memory_size_(size),
allow_overlay_(false),
nearest_neighbor_(false) {
@@ -44,8 +47,7 @@
other.mailbox_holder_.mailbox.name,
sizeof(mailbox_holder_.mailbox.name));
} else if (other.IsSharedMemory()) {
- return IsSharedMemory() &&
- shared_memory_->handle() == other.shared_memory_->handle();
+ return IsSharedMemory() && (shared_bitmap_ == other.shared_bitmap_);
}
DCHECK(!other.IsValid());
diff --git a/cc/resources/texture_mailbox.h b/cc/resources/texture_mailbox.h
index 9bf41e1..cec60ce 100644
--- a/cc/resources/texture_mailbox.h
+++ b/cc/resources/texture_mailbox.h
@@ -13,6 +13,7 @@
#include "ui/gfx/geometry/size.h"
namespace cc {
+class SharedBitmap;
// TODO(skaslev, danakj) Rename this class more apropriately since now it
// can hold a shared memory resource as well as a texture mailbox.
@@ -21,13 +22,13 @@
TextureMailbox();
explicit TextureMailbox(const gpu::MailboxHolder& mailbox_holder);
TextureMailbox(const gpu::Mailbox& mailbox, uint32 target, uint32 sync_point);
- TextureMailbox(base::SharedMemory* shared_memory, const gfx::Size& size);
+ TextureMailbox(SharedBitmap* shared_bitmap, const gfx::Size& size);
~TextureMailbox();
bool IsValid() const { return IsTexture() || IsSharedMemory(); }
bool IsTexture() const { return !mailbox_holder_.mailbox.IsZero(); }
- bool IsSharedMemory() const { return shared_memory_ != NULL; }
+ bool IsSharedMemory() const { return shared_bitmap_ != NULL; }
bool Equals(const TextureMailbox&) const;
@@ -46,13 +47,13 @@
nearest_neighbor_ = nearest_neighbor;
}
- base::SharedMemory* shared_memory() const { return shared_memory_; }
+ SharedBitmap* shared_bitmap() const { return shared_bitmap_; }
gfx::Size shared_memory_size() const { return shared_memory_size_; }
size_t SharedMemorySizeInBytes() const;
private:
gpu::MailboxHolder mailbox_holder_;
- base::SharedMemory* shared_memory_;
+ SharedBitmap* shared_bitmap_;
gfx::Size shared_memory_size_;
bool allow_overlay_;
bool nearest_neighbor_;
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index 7ab1fbf..309c2b3 100644
--- a/cc/resources/tile_manager.cc
+++ b/cc/resources/tile_manager.cc
@@ -41,7 +41,6 @@
const void* tile_id,
int source_frame_number,
bool analyze_picture,
- RenderingStatsInstrumentation* rendering_stats,
const base::Callback<void(const RasterSource::SolidColorAnalysis&, bool)>&
reply,
ImageDecodeTask::Vector* dependencies)
@@ -54,7 +53,6 @@
tile_id_(tile_id),
source_frame_number_(source_frame_number),
analyze_picture_(analyze_picture),
- rendering_stats_(rendering_stats),
reply_(reply) {}
// Overridden from Task:
@@ -128,7 +126,6 @@
const void* tile_id_;
int source_frame_number_;
bool analyze_picture_;
- RenderingStatsInstrumentation* rendering_stats_;
const base::Callback<void(const RasterSource::SolidColorAnalysis&, bool)>
reply_;
scoped_ptr<RasterBuffer> raster_buffer_;
@@ -140,11 +137,9 @@
public:
ImageDecodeTaskImpl(SkPixelRef* pixel_ref,
int layer_id,
- RenderingStatsInstrumentation* rendering_stats,
const base::Callback<void(bool was_canceled)>& reply)
: pixel_ref_(skia::SharePtr(pixel_ref)),
layer_id_(layer_id),
- rendering_stats_(rendering_stats),
reply_(reply) {}
// Overridden from Task:
@@ -169,7 +164,6 @@
private:
skia::RefPtr<SkPixelRef> pixel_ref_;
int layer_id_;
- RenderingStatsInstrumentation* rendering_stats_;
const base::Callback<void(bool was_canceled)> reply_;
DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl);
@@ -209,11 +203,10 @@
base::SequencedTaskRunner* task_runner,
ResourcePool* resource_pool,
TileTaskRunner* tile_task_runner,
- RenderingStatsInstrumentation* rendering_stats_instrumentation,
size_t scheduled_raster_task_limit) {
- return make_scoped_ptr(new TileManager(
- client, task_runner, resource_pool, tile_task_runner,
- rendering_stats_instrumentation, scheduled_raster_task_limit));
+ return make_scoped_ptr(new TileManager(client, task_runner, resource_pool,
+ tile_task_runner,
+ scheduled_raster_task_limit));
}
TileManager::TileManager(
@@ -221,7 +214,6 @@
const scoped_refptr<base::SequencedTaskRunner>& task_runner,
ResourcePool* resource_pool,
TileTaskRunner* tile_task_runner,
- RenderingStatsInstrumentation* rendering_stats_instrumentation,
size_t scheduled_raster_task_limit)
: client_(client),
task_runner_(task_runner),
@@ -229,7 +221,6 @@
tile_task_runner_(tile_task_runner),
scheduled_raster_task_limit_(scheduled_raster_task_limit),
all_tiles_that_need_to_be_rasterized_are_scheduled_(true),
- rendering_stats_instrumentation_(rendering_stats_instrumentation),
did_check_for_completed_tasks_since_last_schedule_tasks_(true),
did_oom_on_last_assign_(false),
ready_to_activate_check_notifier_(
@@ -719,7 +710,6 @@
return make_scoped_refptr(new ImageDecodeTaskImpl(
pixel_ref,
tile->layer_id(),
- rendering_stats_instrumentation_,
base::Bind(&TileManager::OnImageDecodeTaskCompleted,
base::Unretained(this),
tile->layer_id(),
@@ -766,7 +756,6 @@
static_cast<const void*>(tile),
tile->source_frame_number(),
tile->use_picture_analysis(),
- rendering_stats_instrumentation_,
base::Bind(&TileManager::OnRasterTaskCompleted,
base::Unretained(this),
tile->id(),
diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h
index 638fecb..a5005bf 100644
--- a/cc/resources/tile_manager.h
+++ b/cc/resources/tile_manager.h
@@ -16,7 +16,6 @@
#include "base/values.h"
#include "cc/base/ref_counted_managed.h"
#include "cc/base/unique_notifier.h"
-#include "cc/debug/rendering_stats_instrumentation.h"
#include "cc/resources/eviction_tile_priority_queue.h"
#include "cc/resources/managed_tile_state.h"
#include "cc/resources/memory_history.h"
@@ -102,7 +101,6 @@
base::SequencedTaskRunner* task_runner,
ResourcePool* resource_pool,
TileTaskRunner* tile_task_runner,
- RenderingStatsInstrumentation* rendering_stats_instrumentation,
size_t scheduled_raster_task_limit);
~TileManager() override;
@@ -176,7 +174,6 @@
const scoped_refptr<base::SequencedTaskRunner>& task_runner,
ResourcePool* resource_pool,
TileTaskRunner* tile_task_runner,
- RenderingStatsInstrumentation* rendering_stats_instrumentation,
size_t scheduled_raster_task_limit);
void FreeResourcesForReleasedTiles();
@@ -260,8 +257,6 @@
bool all_tiles_that_need_to_be_rasterized_are_scheduled_;
MemoryHistory::Entry memory_stats_from_last_assign_;
- RenderingStatsInstrumentation* rendering_stats_instrumentation_;
-
bool did_check_for_completed_tasks_since_last_schedule_tasks_;
bool did_oom_on_last_assign_;
diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc
index fdd876e..eb5d737 100644
--- a/cc/resources/tile_manager_unittest.cc
+++ b/cc/resources/tile_manager_unittest.cc
@@ -109,7 +109,7 @@
if (old_pending_root) {
pending_layer.reset(
static_cast<FakePictureLayerImpl*>(old_pending_root.release()));
- pending_layer->SetRasterSource(pile);
+ pending_layer->SetRasterSourceOnPending(pile, Region());
} else {
pending_layer =
FakePictureLayerImpl::CreateWithRasterSource(pending_tree, id_, pile);
@@ -124,14 +124,6 @@
pending_layer_->DoPostCommitInitializationIfNeeded();
}
- void CreateHighLowResAndSetAllTilesVisible() {
- // Active layer must get updated first so pending layer can share from it.
- active_layer_->CreateDefaultTilingsAndTiles();
- active_layer_->SetAllTilesVisible();
- pending_layer_->CreateDefaultTilingsAndTiles();
- pending_layer_->SetAllTilesVisible();
- }
-
TileManager* tile_manager() { return host_impl_.tile_manager(); }
protected:
@@ -195,10 +187,8 @@
// Invalidate the pending tree.
pending_layer_->set_invalidation(invalidation);
- pending_layer_->HighResTiling()->UpdateTilesToCurrentRasterSource(
- pending_layer_->raster_source(), invalidation, gfx::Size(1000, 1000));
- pending_layer_->LowResTiling()->UpdateTilesToCurrentRasterSource(
- pending_layer_->raster_source(), invalidation, gfx::Size(1000, 1000));
+ pending_layer_->HighResTiling()->Invalidate(invalidation);
+ pending_layer_->LowResTiling()->Invalidate(invalidation);
active_layer_->ResetAllTilesPriorities();
pending_layer_->ResetAllTilesPriorities();
@@ -445,10 +435,8 @@
// Invalidate the pending tree.
pending_layer_->set_invalidation(invalidation);
- pending_layer_->HighResTiling()->UpdateTilesToCurrentRasterSource(
- pending_layer_->raster_source(), invalidation, gfx::Size(1000, 1000));
- pending_layer_->LowResTiling()->UpdateTilesToCurrentRasterSource(
- pending_layer_->raster_source(), invalidation, gfx::Size(1000, 1000));
+ pending_layer_->HighResTiling()->Invalidate(invalidation);
+ pending_layer_->LowResTiling()->Invalidate(invalidation);
active_layer_->ResetAllTilesPriorities();
pending_layer_->ResetAllTilesPriorities();
@@ -495,6 +483,8 @@
// Here we expect to get increasing ACTIVE_TREE priority_bin.
queue.Reset();
host_impl_.BuildEvictionQueue(&queue, SMOOTHNESS_TAKES_PRIORITY);
+ int distance_increasing = 0;
+ int distance_decreasing = 0;
while (!queue.IsEmpty()) {
Tile* tile = queue.Top();
EXPECT_TRUE(tile);
@@ -511,8 +501,11 @@
tile->required_for_activation());
if (last_tile->required_for_activation() ==
tile->required_for_activation()) {
- EXPECT_GE(last_tile->priority(ACTIVE_TREE).distance_to_visible,
- tile->priority(ACTIVE_TREE).distance_to_visible);
+ if (last_tile->priority(ACTIVE_TREE).distance_to_visible >=
+ tile->priority(ACTIVE_TREE).distance_to_visible)
+ ++distance_decreasing;
+ else
+ ++distance_increasing;
}
}
@@ -522,6 +515,8 @@
queue.Pop();
}
+ EXPECT_EQ(3, distance_increasing);
+ EXPECT_EQ(16, distance_decreasing);
EXPECT_EQ(tile_count, smoothness_tiles.size());
EXPECT_EQ(all_tiles, smoothness_tiles);
@@ -530,6 +525,8 @@
// Here we expect to get increasing PENDING_TREE priority_bin.
queue.Reset();
host_impl_.BuildEvictionQueue(&queue, NEW_CONTENT_TAKES_PRIORITY);
+ distance_decreasing = 0;
+ distance_increasing = 0;
while (!queue.IsEmpty()) {
Tile* tile = queue.Top();
EXPECT_TRUE(tile);
@@ -545,8 +542,11 @@
tile->required_for_activation());
if (last_tile->required_for_activation() ==
tile->required_for_activation()) {
- EXPECT_GE(last_tile->priority(PENDING_TREE).distance_to_visible,
- tile->priority(PENDING_TREE).distance_to_visible);
+ if (last_tile->priority(PENDING_TREE).distance_to_visible >=
+ tile->priority(PENDING_TREE).distance_to_visible)
+ ++distance_decreasing;
+ else
+ ++distance_increasing;
}
}
@@ -555,6 +555,8 @@
queue.Pop();
}
+ EXPECT_EQ(3, distance_increasing);
+ EXPECT_EQ(16, distance_decreasing);
EXPECT_EQ(tile_count, new_content_tiles.size());
EXPECT_EQ(all_tiles, new_content_tiles);
}
diff --git a/cc/resources/tiling_set_eviction_queue.cc b/cc/resources/tiling_set_eviction_queue.cc
index 8c5ff52..18f659e 100644
--- a/cc/resources/tiling_set_eviction_queue.cc
+++ b/cc/resources/tiling_set_eviction_queue.cc
@@ -2,38 +2,53 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <utility>
+
#include "cc/resources/tiling_set_eviction_queue.h"
namespace cc {
TilingSetEvictionQueue::TilingSetEvictionQueue()
: tiling_set_(nullptr),
+ tree_(ACTIVE_TREE),
tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES),
- current_category_(PictureLayerTiling::EVENTUALLY),
+ skip_all_shared_tiles_(false),
+ skip_shared_out_of_order_tiles_(false),
+ processing_soon_border_rect_(false),
+ processing_tiling_with_required_for_activation_tiles_(false),
+ tiling_index_with_required_for_activation_tiles_(0u),
+ current_priority_bin_(TilePriority::EVENTUALLY),
current_tiling_index_(0u),
current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES),
- current_eviction_tile_(nullptr),
- eviction_tiles_(nullptr),
- next_eviction_tile_index_(0u) {
+ current_eviction_tile_(nullptr) {
}
TilingSetEvictionQueue::TilingSetEvictionQueue(
PictureLayerTilingSet* tiling_set,
- TreePriority tree_priority)
+ TreePriority tree_priority,
+ bool skip_shared_out_of_order_tiles)
: tiling_set_(tiling_set),
+ tree_(tiling_set->client()->GetTree()),
tree_priority_(tree_priority),
- current_category_(PictureLayerTiling::EVENTUALLY),
+ skip_all_shared_tiles_(
+ skip_shared_out_of_order_tiles &&
+ tree_priority == (tree_ == ACTIVE_TREE ? NEW_CONTENT_TAKES_PRIORITY
+ : SMOOTHNESS_TAKES_PRIORITY)),
+ skip_shared_out_of_order_tiles_(skip_shared_out_of_order_tiles),
+ processing_soon_border_rect_(false),
+ processing_tiling_with_required_for_activation_tiles_(false),
+ tiling_index_with_required_for_activation_tiles_(0u),
+ current_priority_bin_(TilePriority::EVENTUALLY),
current_tiling_index_(0u),
current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES),
- current_eviction_tile_(nullptr),
- eviction_tiles_(nullptr),
- next_eviction_tile_index_(0u) {
- DCHECK(tiling_set_);
-
+ current_eviction_tile_(nullptr) {
// Early out if the layer has no tilings.
if (!tiling_set_->num_tilings())
return;
+ tiling_index_with_required_for_activation_tiles_ =
+ TilingIndexWithRequiredForActivationTiles();
+
current_tiling_index_ = CurrentTilingRange().start - 1u;
AdvanceToNextValidTiling();
}
@@ -62,60 +77,132 @@
return current_eviction_tile_;
}
-bool TilingSetEvictionQueue::AdvanceToNextCategory() {
- // Advance to the next category. This is done only after all tiling range
- // types within the previous category have been gone through.
- DCHECK_EQ(current_tiling_range_type_, PictureLayerTilingSet::HIGH_RES);
-
- switch (current_category_) {
- case PictureLayerTiling::EVENTUALLY:
- current_category_ =
- PictureLayerTiling::EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION;
- return true;
- case PictureLayerTiling::EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION:
- current_category_ = PictureLayerTiling::SOON;
- return true;
- case PictureLayerTiling::SOON:
- current_category_ = PictureLayerTiling::SOON_AND_REQUIRED_FOR_ACTIVATION;
- return true;
- case PictureLayerTiling::SOON_AND_REQUIRED_FOR_ACTIVATION:
- current_category_ = PictureLayerTiling::NOW;
- return true;
- case PictureLayerTiling::NOW:
- current_category_ = PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION;
- return true;
- case PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION:
- return false;
- }
- NOTREACHED();
- return false;
-}
-
bool TilingSetEvictionQueue::AdvanceToNextEvictionTile() {
- // Advance to the next eviction tile within the current category and tiling.
- // This is done while advancing to a new tiling (in which case the next
- // eviction tile index is 0) and while popping the current tile (in which
- // case the next eviction tile index is greater than 0).
- DCHECK_EQ(next_eviction_tile_index_ > 0, current_eviction_tile_ != nullptr);
+ // Advance to the next eviction tile within the current priority bin and
+ // tiling. This is done while advancing to a new tiling and while popping
+ // the current tile.
- while (next_eviction_tile_index_ < eviction_tiles_->size()) {
- Tile* tile = (*eviction_tiles_)[next_eviction_tile_index_];
- ++next_eviction_tile_index_;
- if (tile->HasResources()) {
+ bool required_for_activation =
+ processing_tiling_with_required_for_activation_tiles_;
+
+ for (;;) {
+ while (spiral_iterator_) {
+ std::pair<int, int> next_index = spiral_iterator_.index();
+ Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second);
+ ++spiral_iterator_;
+ if (!tile || !tile->HasResources())
+ continue;
+ if (skip_all_shared_tiles_ && tile->is_shared())
+ continue;
+ current_tiling_->UpdateTileAndTwinPriority(tile);
+ if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile))
+ continue;
+ if (tile->required_for_activation() != required_for_activation)
+ continue;
current_eviction_tile_ = tile;
return true;
}
+ if (processing_soon_border_rect_) {
+ // Advance from soon border rect to skewport rect.
+ processing_soon_border_rect_ = false;
+ if (current_tiling_->has_skewport_rect_tiles_) {
+ spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
+ ¤t_tiling_->tiling_data_,
+ current_tiling_->current_skewport_rect_,
+ current_tiling_->current_visible_rect_,
+ current_tiling_->current_visible_rect_);
+ continue;
+ }
+ }
+ break;
+ }
+
+ TilePriority::PriorityBin max_tile_priority_bin =
+ current_tiling_->client_->GetMaxTilePriorityBin();
+ while (visible_iterator_) {
+ std::pair<int, int> next_index = visible_iterator_.index();
+ Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second);
+ ++visible_iterator_;
+ if (!tile || !tile->HasResources())
+ continue;
+ if (skip_all_shared_tiles_ && tile->is_shared())
+ continue;
+ // If the max tile priority is not NOW, updated priorities for tiles
+ // returned by the visible iterator will not have NOW (but EVENTUALLY)
+ // priority bin and cannot therefore be required for activation tiles nor
+ // occluded NOW tiles in the current tiling.
+ if (max_tile_priority_bin <= TilePriority::NOW) {
+ // If the current tiling is a pending tree tiling, required for
+ // activation tiles can be detected without updating tile priorities.
+ if (tree_ == PENDING_TREE &&
+ current_tiling_->IsTileRequiredForActivationIfVisible(tile) !=
+ required_for_activation) {
+ continue;
+ }
+ // Unoccluded NOW tiles should be evicted (and thus returned) only after
+ // all occluded NOW tiles.
+ if (!current_tiling_->IsTileOccluded(tile)) {
+ unoccluded_now_tiles_.push_back(tile);
+ continue;
+ }
+ }
+ current_tiling_->UpdateTileAndTwinPriority(tile);
+ if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile))
+ continue;
+ if (tile->required_for_activation() != required_for_activation)
+ continue;
+ current_eviction_tile_ = tile;
+ return true;
+ }
+
+ while (!unoccluded_now_tiles_.empty()) {
+ // All (unoccluded) NOW tiles have the same priority bin (NOW) and the same
+ // distance to visible (0.0), so it does not matter that tiles are popped
+ // in reversed (FILO) order.
+ Tile* tile = unoccluded_now_tiles_.back();
+ unoccluded_now_tiles_.pop_back();
+ DCHECK(tile);
+ if (!tile->HasResources())
+ continue;
+ current_tiling_->UpdateTileAndTwinPriority(tile);
+ if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile))
+ continue;
+ if (tile->required_for_activation() != required_for_activation)
+ continue;
+ current_eviction_tile_ = tile;
+ return true;
}
current_eviction_tile_ = nullptr;
return false;
}
+bool TilingSetEvictionQueue::AdvanceToNextPriorityBin() {
+ // Advance to the next priority bin. This is done only after all tiling range
+ // types (including the required for activation tiling) within the previous
+ // priority bin have been gone through.
+ DCHECK_EQ(current_tiling_range_type_, PictureLayerTilingSet::HIGH_RES);
+
+ switch (current_priority_bin_) {
+ case TilePriority::EVENTUALLY:
+ current_priority_bin_ = TilePriority::SOON;
+ return true;
+ case TilePriority::SOON:
+ current_priority_bin_ = TilePriority::NOW;
+ return true;
+ case TilePriority::NOW:
+ return false;
+ }
+ NOTREACHED();
+ return false;
+}
+
bool TilingSetEvictionQueue::AdvanceToNextTilingRangeType() {
- // Advance to the next tiling range type within the current category or to
- // the first tiling range type within the next category. This is done only
- // after all tilings within the previous tiling range type have been gone
- // through.
+ // Advance to the next tiling range type within the current priority bin, to
+ // the required for activation tiling range type within the current priority
+ // bin or to the first tiling range type within the next priority bin. This
+ // is done only after all tilings within the previous tiling range type have
+ // been gone through.
DCHECK_EQ(current_tiling_index_, CurrentTilingRange().end);
switch (current_tiling_range_type_) {
@@ -133,7 +220,15 @@
current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES;
return true;
case PictureLayerTilingSet::HIGH_RES:
- if (!AdvanceToNextCategory())
+ if (!processing_tiling_with_required_for_activation_tiles_ &&
+ tiling_index_with_required_for_activation_tiles_ <
+ tiling_set_->num_tilings()) {
+ processing_tiling_with_required_for_activation_tiles_ = true;
+ return true;
+ }
+ processing_tiling_with_required_for_activation_tiles_ = false;
+
+ if (!AdvanceToNextPriorityBin())
return false;
current_tiling_range_type_ = PictureLayerTilingSet::HIGHER_THAN_HIGH_RES;
@@ -145,10 +240,10 @@
bool TilingSetEvictionQueue::AdvanceToNextValidTiling() {
// Advance to the next tiling within current tiling range type or to
- // the first tiling within the next tiling range type or category until
+ // the first tiling within the next tiling range type or priority bin until
// the next eviction tile is found. This is done only after all eviction
- // tiles within the previous tiling within the current category and tiling
- // range type have been gone through.
+ // tiles within the previous tiling within the current priority bin and
+ // tiling range type have been gone through.
DCHECK(!current_eviction_tile_);
DCHECK_NE(current_tiling_index_, CurrentTilingRange().end);
@@ -159,18 +254,54 @@
return false;
current_tiling_index_ = CurrentTilingRange().start;
}
+ current_tiling_ = tiling_set_->tiling_at(CurrentTilingIndex());
- PictureLayerTiling* tiling = tiling_set_->tiling_at(CurrentTilingIndex());
- eviction_tiles_ =
- tiling->GetEvictionTiles(tree_priority_, current_category_);
- next_eviction_tile_index_ = 0u;
- if (AdvanceToNextEvictionTile())
- return true;
+ switch (current_priority_bin_) {
+ case TilePriority::EVENTUALLY:
+ if (current_tiling_->has_eventually_rect_tiles_) {
+ spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
+ ¤t_tiling_->tiling_data_,
+ current_tiling_->current_eventually_rect_,
+ current_tiling_->current_skewport_rect_,
+ current_tiling_->current_soon_border_rect_);
+ if (AdvanceToNextEvictionTile())
+ return true;
+ }
+ break;
+ case TilePriority::SOON:
+ if (current_tiling_->has_skewport_rect_tiles_ ||
+ current_tiling_->has_soon_border_rect_tiles_) {
+ processing_soon_border_rect_ = true;
+ if (current_tiling_->has_soon_border_rect_tiles_)
+ spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
+ ¤t_tiling_->tiling_data_,
+ current_tiling_->current_soon_border_rect_,
+ current_tiling_->current_skewport_rect_,
+ current_tiling_->current_visible_rect_);
+ if (AdvanceToNextEvictionTile())
+ return true;
+ }
+ break;
+ case TilePriority::NOW:
+ if (current_tiling_->has_visible_rect_tiles_) {
+ visible_iterator_ =
+ TilingData::Iterator(¤t_tiling_->tiling_data_,
+ current_tiling_->current_visible_rect_,
+ false /* include_borders */);
+ if (AdvanceToNextEvictionTile())
+ return true;
+ }
+ break;
+ }
}
}
PictureLayerTilingSet::TilingRange
TilingSetEvictionQueue::CurrentTilingRange() const {
+ if (processing_tiling_with_required_for_activation_tiles_)
+ return PictureLayerTilingSet::TilingRange(
+ tiling_index_with_required_for_activation_tiles_,
+ tiling_index_with_required_for_activation_tiles_ + 1);
return tiling_set_->GetTilingRange(current_tiling_range_type_);
}
@@ -194,4 +325,77 @@
return 0;
}
+bool TilingSetEvictionQueue::IsSharedOutOfOrderTile(const Tile* tile) const {
+ if (!tile->is_shared())
+ return false;
+
+ switch (tree_priority_) {
+ case SMOOTHNESS_TAKES_PRIORITY:
+ DCHECK_EQ(ACTIVE_TREE, tree_);
+ return false;
+ case NEW_CONTENT_TAKES_PRIORITY:
+ DCHECK_EQ(PENDING_TREE, tree_);
+ return false;
+ case SAME_PRIORITY_FOR_BOTH_TREES:
+ break;
+ case NUM_TREE_PRIORITIES:
+ NOTREACHED();
+ break;
+ }
+
+ // The priority for tile priority of a shared tile will be a combined
+ // priority thus return shared tiles from a higher priority tree as
+ // it is out of order for a lower priority tree.
+ WhichTree twin_tree = tree_ == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE;
+ const TilePriority& priority = tile->priority(tree_);
+ const TilePriority& twin_priority = tile->priority(twin_tree);
+ if (priority.priority_bin != twin_priority.priority_bin)
+ return priority.priority_bin > twin_priority.priority_bin;
+ const bool occluded = tile->is_occluded(tree_);
+ const bool twin_occluded = tile->is_occluded(twin_tree);
+ if (occluded != twin_occluded)
+ return occluded;
+ if (priority.distance_to_visible != twin_priority.distance_to_visible)
+ return priority.distance_to_visible > twin_priority.distance_to_visible;
+
+ // If priorities are the same, it does not matter which tree returns
+ // the tile. Let's pick the pending tree.
+ return tree_ != PENDING_TREE;
}
+
+size_t TilingSetEvictionQueue::TilingIndexWithRequiredForActivationTiles()
+ const {
+ // Returns the tiling index of the tiling with requuired for activation tiles.
+ // If no such tiling exists, returns the past-the-last index (num_tilings).
+ size_t num_tilings = tiling_set_->num_tilings();
+
+ if (tree_ == PENDING_TREE) {
+ // For the pending tree, the tiling with required for activation tiles is
+ // the high res one.
+ PictureLayerTilingSet::TilingRange high_res_tiling_range =
+ tiling_set_->GetTilingRange(PictureLayerTilingSet::HIGH_RES);
+ if (high_res_tiling_range.start != high_res_tiling_range.end)
+ return high_res_tiling_range.start;
+ } else {
+ DCHECK_EQ(ACTIVE_TREE, tree_);
+ // Only pending tree tiles can be required for activation. They can appear
+ // also in the active tree only if they are shared. If we skip all shared
+ // tiles, there is no need to find them as they will not be returned.
+ if (skip_all_shared_tiles_)
+ return num_tilings;
+
+ // For the active tree, the tiling with required for activation tiles is
+ // the one whose twin tiling is the high res pending tiling.
+ for (size_t i = 0; i < num_tilings; ++i) {
+ const PictureLayerTiling* tiling = tiling_set_->tiling_at(i);
+ const PictureLayerTiling* pending_tiling =
+ tiling_set_->client()->GetPendingOrActiveTwinTiling(tiling);
+ if (pending_tiling && pending_tiling->resolution() == HIGH_RESOLUTION)
+ return i;
+ }
+ }
+
+ return num_tilings;
+}
+
+} // namespace cc
diff --git a/cc/resources/tiling_set_eviction_queue.h b/cc/resources/tiling_set_eviction_queue.h
index f88ce3b..4463cc3 100644
--- a/cc/resources/tiling_set_eviction_queue.h
+++ b/cc/resources/tiling_set_eviction_queue.h
@@ -5,16 +5,79 @@
#ifndef CC_RESOURCES_TILING_SET_EVICTION_QUEUE_H_
#define CC_RESOURCES_TILING_SET_EVICTION_QUEUE_H_
+#include <vector>
+
#include "cc/base/cc_export.h"
#include "cc/resources/picture_layer_tiling_set.h"
namespace cc {
+// This eviction queue returned tiles from all tilings in a tiling set in
+// the following order:
+// 1) Eventually rect tiles (EVENTUALLY tiles).
+// 1) Eventually rect tiles not required for activation from each tiling in
+// the tiling set, in turn, in the following order:
+// 1) the first higher than high res tiling, the second one and so on
+// 2) the first lower than low res tiling, the second one and so on
+// 3) the first between high and low res tiling, the second one and so on
+// 4) low res tiling
+// 5) high res tiling
+// 2) Eventually rect tiles required for activation from the tiling with
+// required for activation tiles. In the case of a pending tree tiling
+// set that is the high res tiling. In the case of an active tree tiling
+// set that is a tiling whose twin tiling is a pending tree high res
+// tiling.
+// 2) Soon border rect and skewport rect tiles (whose priority bin is SOON
+// unless the max tile priority bin is lowered by PictureLayerTilingClient).
+// 1) Soon border rect and skewport rect tiles not required for activation
+// from each tiling in the tiling set.
+// * Tilings are iterated in the same order as in the case of eventually
+// rect tiles not required for activation.
+// * For each tiling, first soon border rect tiles and then skewport
+// rect tiles are returned.
+// 2) Soon border rect and skewport rect tiles required for activation from
+// the tiling with required for activation tiles.
+// * First soon border rect tiles and then skewport rect tiles are
+// returned.
+// 3) Visible rect tiles (whose priority bin is NOW unless the max tile
+// priority bin is lowered by PictureLayerTilingClient).
+// 1) Visible rect tiles not required for activation from each tiling in
+// the tiling set.
+// * Tilings are iterated in the same order as in the case of eventually
+// rect tiles not required for activation.
+// * For each tiling, first occluded tiles and then unoccluded tiles
+// are returned.
+// 2) Visible rect tiles required for activation from the tiling with
+// required for activation tiles.
+// * First occluded tiles and then unoccluded tiles are returned.
+// If the max tile priority bin is lowered by PictureLayerTilingClient,
+// occlusion is not taken into account as occlusion is meaningful only for
+// NOW tiles.
+//
+// Within each tiling and tile priority rect, tiles are returned in reverse
+// spiral order i.e. in (mostly) decreasing distance-to-visible order.
+//
+// If the skip_shared_out_of_order_tiles value passed to the constructor is
+// true (like it should be when there is a twin layer with a twin tiling set),
+// eviction queue does not return shared which are out of order because their
+// priority for tree priority is lowered or raised by a twin layer.
+// * If tree_priority is SAME_PRIORITY_FOR_BOTH_TREES, this happens for
+// a tile specific lower priority tree eviction queue (because priority for
+// tree priority is a merged priority).
+// * If tree priority is NEW_CONTENT_TAKES_PRIORITY, this happens for
+// an active tree eviction queue (because priority for tree priority is
+// the pending priority).
+// * If tree_priority is SMOOTHNESS_TAKES_PRIORITY, this happens for a pending
+// tree eviction queue (because priority for tree priority is the active
+// priority).
+// Those skipped shared out of order tiles are when returned only by the twin
+// eviction queue.
class CC_EXPORT TilingSetEvictionQueue {
public:
TilingSetEvictionQueue();
TilingSetEvictionQueue(PictureLayerTilingSet* tiling_set,
- TreePriority tree_priority);
+ TreePriority tree_priority,
+ bool skip_shared_out_of_order_tiles);
~TilingSetEvictionQueue();
Tile* Top();
@@ -23,26 +86,36 @@
bool IsEmpty() const;
private:
- bool AdvanceToNextCategory();
bool AdvanceToNextEvictionTile();
+ bool AdvanceToNextPriorityBin();
bool AdvanceToNextTilingRangeType();
bool AdvanceToNextValidTiling();
PictureLayerTilingSet::TilingRange CurrentTilingRange() const;
size_t CurrentTilingIndex() const;
+ bool IsSharedOutOfOrderTile(const Tile* tile) const;
+ size_t TilingIndexWithRequiredForActivationTiles() const;
PictureLayerTilingSet* tiling_set_;
+ WhichTree tree_;
TreePriority tree_priority_;
+ bool skip_all_shared_tiles_;
+ bool skip_shared_out_of_order_tiles_;
+ bool processing_soon_border_rect_;
+ bool processing_tiling_with_required_for_activation_tiles_;
+ size_t tiling_index_with_required_for_activation_tiles_;
- PictureLayerTiling::EvictionCategory current_category_;
+ TilePriority::PriorityBin current_priority_bin_;
+ PictureLayerTiling* current_tiling_;
size_t current_tiling_index_;
PictureLayerTilingSet::TilingRangeType current_tiling_range_type_;
Tile* current_eviction_tile_;
- const std::vector<Tile*>* eviction_tiles_;
- size_t next_eviction_tile_index_;
+ TilingData::ReverseSpiralDifferenceIterator spiral_iterator_;
+ TilingData::Iterator visible_iterator_;
+ std::vector<Tile*> unoccluded_now_tiles_;
};
} // namespace cc
-#endif // CC_RESOURCES_TILING_SET_RASTER_QUEUE_H_
+#endif // CC_RESOURCES_TILING_SET_EVICTION_QUEUE_H_
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index 2c9a688..edbea9b 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -4,6 +4,8 @@
#include "cc/resources/video_resource_updater.h"
+#include <algorithm>
+
#include "base/bind.h"
#include "base/debug/trace_event.h"
#include "cc/output/gl_renderer.h"
@@ -48,6 +50,7 @@
resource_size(resource_size),
resource_format(resource_format),
mailbox(mailbox),
+ ref_count(0),
frame_ptr(nullptr),
plane_index(0) {
}
@@ -81,17 +84,43 @@
}
VideoResourceUpdater::~VideoResourceUpdater() {
- while (!all_resources_.empty()) {
- resource_provider_->DeleteResource(all_resources_.back());
- all_resources_.pop_back();
- }
+ for (const PlaneResource& plane_resource : all_resources_)
+ resource_provider_->DeleteResource(plane_resource.resource_id);
}
-void VideoResourceUpdater::DeleteResource(unsigned resource_id) {
- resource_provider_->DeleteResource(resource_id);
- all_resources_.erase(std::remove(all_resources_.begin(),
- all_resources_.end(),
- resource_id));
+VideoResourceUpdater::ResourceList::iterator
+VideoResourceUpdater::AllocateResource(const gfx::Size& plane_size,
+ ResourceFormat format,
+ bool has_mailbox) {
+ // TODO(danakj): Abstract out hw/sw resource create/delete from
+ // ResourceProvider and stop using ResourceProvider in this class.
+ const ResourceProvider::ResourceId resource_id =
+ resource_provider_->CreateResource(plane_size, GL_CLAMP_TO_EDGE,
+ ResourceProvider::TextureHintImmutable,
+ format);
+ if (resource_id == 0)
+ return all_resources_.end();
+
+ gpu::Mailbox mailbox;
+ if (has_mailbox) {
+ DCHECK(context_provider_);
+
+ gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
+
+ GLC(gl, gl->GenMailboxCHROMIUM(mailbox.name));
+ ResourceProvider::ScopedWriteLockGL lock(resource_provider_, resource_id);
+ GLC(gl, gl->ProduceTextureDirectCHROMIUM(lock.texture_id(), GL_TEXTURE_2D,
+ mailbox.name));
+ }
+ all_resources_.push_front(
+ PlaneResource(resource_id, plane_size, format, mailbox));
+ return all_resources_.begin();
+}
+
+void VideoResourceUpdater::DeleteResource(ResourceList::iterator resource_it) {
+ DCHECK_EQ(resource_it->ref_count, 0);
+ resource_provider_->DeleteResource(resource_it->resource_id);
+ all_resources_.erase(resource_it);
}
VideoFrameExternalResources VideoResourceUpdater::
@@ -157,19 +186,15 @@
#endif // defined(VIDEO_HOLE)
// Only YUV software video frames are supported.
- DCHECK(input_frame_format == media::VideoFrame::YV12 ||
- input_frame_format == media::VideoFrame::I420 ||
- input_frame_format == media::VideoFrame::YV12A ||
- input_frame_format == media::VideoFrame::YV12J ||
- input_frame_format == media::VideoFrame::YV16 ||
- input_frame_format == media::VideoFrame::YV24);
if (input_frame_format != media::VideoFrame::YV12 &&
input_frame_format != media::VideoFrame::I420 &&
input_frame_format != media::VideoFrame::YV12A &&
input_frame_format != media::VideoFrame::YV12J &&
input_frame_format != media::VideoFrame::YV16 &&
- input_frame_format != media::VideoFrame::YV24)
+ input_frame_format != media::VideoFrame::YV24) {
+ NOTREACHED() << input_frame_format;
return VideoFrameExternalResources();
+ }
bool software_compositor = context_provider_ == NULL;
@@ -186,81 +211,69 @@
output_plane_count = 1;
}
- int max_resource_size = resource_provider_->max_texture_size();
- std::vector<PlaneResource> plane_resources;
- bool allocation_success = true;
+ // Drop recycled resources that are the wrong format.
+ for (auto it = all_resources_.begin(); it != all_resources_.end();) {
+ if (it->ref_count == 0 && it->resource_format != output_resource_format)
+ DeleteResource(it++);
+ else
+ ++it;
+ }
+ const int max_resource_size = resource_provider_->max_texture_size();
+ std::vector<ResourceList::iterator> plane_resources;
for (size_t i = 0; i < output_plane_count; ++i) {
gfx::Size output_plane_resource_size =
SoftwarePlaneDimension(video_frame, software_compositor, i);
if (output_plane_resource_size.IsEmpty() ||
output_plane_resource_size.width() > max_resource_size ||
output_plane_resource_size.height() > max_resource_size) {
- allocation_success = false;
break;
}
// Try recycle a previously-allocated resource.
- auto recycled_it = recycled_resources_.end();
- for (auto it = recycled_resources_.begin(); it != recycled_resources_.end();
- ++it) {
- const bool resource_matches =
- it->resource_format == output_resource_format &&
- it->resource_size == output_plane_resource_size;
- const bool in_use = software_compositor &&
- resource_provider_->InUseByConsumer(it->resource_id);
- if (resource_matches && !in_use) {
- // We found a recycled resource with the allocation size and format we
- // are looking for.
- recycled_it = it;
- // Keep looking for a recycled resource that also contains the data we
- // are planning to put in it.
- if (PlaneResourceMatchesUniqueID(*it, video_frame.get(), i))
+ ResourceList::iterator resource_it = all_resources_.end();
+ for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) {
+ if (it->resource_size == output_plane_resource_size &&
+ it->resource_format == output_resource_format) {
+ if (PlaneResourceMatchesUniqueID(*it, video_frame.get(), i)) {
+ // Bingo, we found a resource that already contains the data we are
+ // planning to put in it. It's safe to reuse it even if
+ // resource_provider_ holds some references to it, because those
+ // references are read-only.
+ resource_it = it;
break;
+ }
+
+ // This extra check is needed because resources backed by SharedMemory
+ // are not ref-counted, unlike mailboxes. Full discussion in
+ // codereview.chromium.org/145273021.
+ const bool in_use =
+ software_compositor &&
+ resource_provider_->InUseByConsumer(it->resource_id);
+ if (it->ref_count == 0 && !in_use) {
+ // We found a resource with the correct size that we can overwrite.
+ resource_it = it;
+ }
}
}
- // Check if we can avoid allocating a new resource.
- if (recycled_it != recycled_resources_.end()) {
- plane_resources.push_back(*recycled_it);
- recycled_resources_.erase(recycled_it);
- continue;
+ // Check if we need to allocate a new resource.
+ if (resource_it == all_resources_.end()) {
+ resource_it =
+ AllocateResource(output_plane_resource_size, output_resource_format,
+ !software_compositor);
}
-
- // TODO(danakj): Abstract out hw/sw resource create/delete from
- // ResourceProvider and stop using ResourceProvider in this class.
- const ResourceProvider::ResourceId resource_id =
- resource_provider_->CreateResource(
- output_plane_resource_size, GL_CLAMP_TO_EDGE,
- ResourceProvider::TextureHintImmutable, output_resource_format);
- if (resource_id == 0) {
- allocation_success = false;
+ if (resource_it == all_resources_.end())
break;
- }
- all_resources_.push_back(resource_id);
- gpu::Mailbox mailbox;
- if (!software_compositor) {
- DCHECK(context_provider_);
-
- gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
-
- GLC(gl, gl->GenMailboxCHROMIUM(mailbox.name));
- ResourceProvider::ScopedWriteLockGL lock(resource_provider_, resource_id);
- GLC(gl, gl->ProduceTextureDirectCHROMIUM(lock.texture_id(), GL_TEXTURE_2D,
- mailbox.name));
- }
-
- DCHECK(software_compositor || !mailbox.IsZero());
- plane_resources.push_back(PlaneResource(resource_id,
- output_plane_resource_size,
- output_resource_format,
- mailbox));
+ ++resource_it->ref_count;
+ plane_resources.push_back(resource_it);
}
- if (!allocation_success) {
- for (size_t i = 0; i < plane_resources.size(); ++i)
- DeleteResource(plane_resources[i].resource_id);
+ if (plane_resources.size() != output_plane_count) {
+ // Allocation failed, nothing will be returned so restore reference counts.
+ for (ResourceList::iterator resource_it : plane_resources)
+ --resource_it->ref_count;
return VideoFrameExternalResources();
}
@@ -268,54 +281,52 @@
if (software_compositor) {
DCHECK_EQ(plane_resources.size(), 1u);
- DCHECK_EQ(plane_resources[0].resource_format, kRGBResourceFormat);
- DCHECK(plane_resources[0].mailbox.IsZero());
+ PlaneResource& plane_resource = *plane_resources[0];
+ DCHECK_EQ(plane_resource.resource_format, kRGBResourceFormat);
+ DCHECK(plane_resource.mailbox.IsZero());
- if (!PlaneResourceMatchesUniqueID(plane_resources[0], video_frame.get(),
- 0)) {
+ if (!PlaneResourceMatchesUniqueID(plane_resource, video_frame.get(), 0)) {
// We need to transfer data from |video_frame| to the plane resource.
if (!video_renderer_)
video_renderer_.reset(new media::SkCanvasVideoRenderer);
ResourceProvider::ScopedWriteLockSoftware lock(
- resource_provider_, plane_resources[0].resource_id);
+ resource_provider_, plane_resource.resource_id);
SkCanvas canvas(lock.sk_bitmap());
video_renderer_->Copy(video_frame, &canvas);
- SetPlaneResourceUniqueId(video_frame.get(), 0, &plane_resources[0]);
+ SetPlaneResourceUniqueId(video_frame.get(), 0, &plane_resource);
}
- external_resources.software_resources.push_back(
- plane_resources[0].resource_id);
+ external_resources.software_resources.push_back(plane_resource.resource_id);
external_resources.software_release_callback =
- base::Bind(&RecycleResource, AsWeakPtr(), plane_resources[0]);
+ base::Bind(&RecycleResource, AsWeakPtr(), plane_resource.resource_id);
external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE;
-
return external_resources;
}
for (size_t i = 0; i < plane_resources.size(); ++i) {
+ PlaneResource& plane_resource = *plane_resources[i];
// Update each plane's resource id with its content.
- DCHECK_EQ(plane_resources[i].resource_format,
+ DCHECK_EQ(plane_resource.resource_format,
resource_provider_->yuv_resource_format());
- if (!PlaneResourceMatchesUniqueID(plane_resources[i], video_frame.get(),
- i)) {
+ if (!PlaneResourceMatchesUniqueID(plane_resource, video_frame.get(), i)) {
// We need to transfer data from |video_frame| to the plane resource.
const uint8_t* input_plane_pixels = video_frame->data(i);
gfx::Rect image_rect(0, 0, video_frame->stride(i),
- plane_resources[i].resource_size.height());
- gfx::Rect source_rect(plane_resources[i].resource_size);
- resource_provider_->SetPixels(plane_resources[i].resource_id,
+ plane_resource.resource_size.height());
+ gfx::Rect source_rect(plane_resource.resource_size);
+ resource_provider_->SetPixels(plane_resource.resource_id,
input_plane_pixels, image_rect, source_rect,
gfx::Vector2d());
- SetPlaneResourceUniqueId(video_frame.get(), i, &plane_resources[i]);
+ SetPlaneResourceUniqueId(video_frame.get(), i, &plane_resource);
}
external_resources.mailboxes.push_back(
- TextureMailbox(plane_resources[i].mailbox, GL_TEXTURE_2D, 0));
+ TextureMailbox(plane_resource.mailbox, GL_TEXTURE_2D, 0));
external_resources.release_callbacks.push_back(
- base::Bind(&RecycleResource, AsWeakPtr(), plane_resources[i]));
+ base::Bind(&RecycleResource, AsWeakPtr(), plane_resource.resource_id));
}
external_resources.type = VideoFrameExternalResources::YUV_RESOURCE;
@@ -382,7 +393,7 @@
// static
void VideoResourceUpdater::RecycleResource(
base::WeakPtr<VideoResourceUpdater> updater,
- PlaneResource data,
+ ResourceProvider::ResourceId resource_id,
uint32 sync_point,
bool lost_resource,
BlockingTaskRunner* main_thread_task_runner) {
@@ -391,6 +402,14 @@
return;
}
+ const ResourceList::iterator resource_it = std::find_if(
+ updater->all_resources_.begin(), updater->all_resources_.end(),
+ [resource_id](const PlaneResource& plane_resource) {
+ return plane_resource.resource_id == resource_id;
+ });
+ if (resource_it == updater->all_resources_.end())
+ return;
+
ContextProvider* context_provider = updater->context_provider_;
if (context_provider && sync_point) {
GLC(context_provider->ContextGL(),
@@ -398,19 +417,13 @@
}
if (lost_resource) {
- updater->DeleteResource(data.resource_id);
+ resource_it->ref_count = 0;
+ updater->DeleteResource(resource_it);
return;
}
- // Drop recycled resources that are the wrong format.
- while (!updater->recycled_resources_.empty() &&
- updater->recycled_resources_.back().resource_format !=
- data.resource_format) {
- updater->DeleteResource(updater->recycled_resources_.back().resource_id);
- updater->recycled_resources_.pop_back();
- }
-
- updater->recycled_resources_.push_back(data);
+ --resource_it->ref_count;
+ DCHECK_GE(resource_it->ref_count, 0);
}
} // namespace cc
diff --git a/cc/resources/video_resource_updater.h b/cc/resources/video_resource_updater.h
index 38f6033..622fe68 100644
--- a/cc/resources/video_resource_updater.h
+++ b/cc/resources/video_resource_updater.h
@@ -5,6 +5,7 @@
#ifndef CC_RESOURCES_VIDEO_RESOURCE_UPDATER_H_
#define CC_RESOURCES_VIDEO_RESOURCE_UPDATER_H_
+#include <list>
#include <vector>
#include "base/basictypes.h"
@@ -78,6 +79,9 @@
gfx::Size resource_size;
ResourceFormat resource_format;
gpu::Mailbox mailbox;
+ // The balance between the number of times this resource has been returned
+ // from CreateForSoftwarePlanes vs released in RecycleResource.
+ int ref_count;
// These last three members will be used for identifying the data stored in
// this resource, and uniquely identifies a media::VideoFrame plane. The
// frame pointer will only be used for pointer comparison, i.e. the
@@ -100,7 +104,13 @@
int plane_index,
PlaneResource* plane_resource);
- void DeleteResource(unsigned resource_id);
+ // This needs to be a container where iterators can be erased without
+ // invalidating other iterators.
+ typedef std::list<PlaneResource> ResourceList;
+ ResourceList::iterator AllocateResource(const gfx::Size& plane_size,
+ ResourceFormat format,
+ bool has_mailbox);
+ void DeleteResource(ResourceList::iterator resource_it);
bool VerifyFrame(const scoped_refptr<media::VideoFrame>& video_frame);
VideoFrameExternalResources CreateForHardwarePlanes(
const scoped_refptr<media::VideoFrame>& video_frame);
@@ -108,7 +118,7 @@
const scoped_refptr<media::VideoFrame>& video_frame);
static void RecycleResource(base::WeakPtr<VideoResourceUpdater> updater,
- PlaneResource data,
+ unsigned resource_id,
uint32 sync_point,
bool lost_resource,
BlockingTaskRunner* main_thread_task_runner);
@@ -122,10 +132,9 @@
ResourceProvider* resource_provider_;
scoped_ptr<media::SkCanvasVideoRenderer> video_renderer_;
- std::vector<unsigned> all_resources_;
// Recycle resources so that we can reduce the number of allocations and
// data transfers.
- std::vector<PlaneResource> recycled_resources_;
+ ResourceList all_resources_;
DISALLOW_COPY_AND_ASSIGN(VideoResourceUpdater);
};
diff --git a/cc/resources/video_resource_updater_unittest.cc b/cc/resources/video_resource_updater_unittest.cc
index 1e3481b..5433bcf 100644
--- a/cc/resources/video_resource_updater_unittest.cc
+++ b/cc/resources/video_resource_updater_unittest.cc
@@ -115,26 +115,36 @@
// Expect exactly three texture uploads, one for each plane.
EXPECT_EQ(3, context3d_->UploadCount());
- const ResourceProvider::ResourceId y_resource =
- resource_provider3d_->CreateResourceFromTextureMailbox(
- resources.mailboxes[media::VideoFrame::kYPlane],
- SingleReleaseCallbackImpl::Create(
- resources.release_callbacks[media::VideoFrame::kYPlane]));
- const ResourceProvider::ResourceId u_resource =
- resource_provider3d_->CreateResourceFromTextureMailbox(
- resources.mailboxes[media::VideoFrame::kUPlane],
- SingleReleaseCallbackImpl::Create(
- resources.release_callbacks[media::VideoFrame::kUPlane]));
- const ResourceProvider::ResourceId v_resource =
- resource_provider3d_->CreateResourceFromTextureMailbox(
- resources.mailboxes[media::VideoFrame::kVPlane],
- SingleReleaseCallbackImpl::Create(
- resources.release_callbacks[media::VideoFrame::kVPlane]));
+ // Simulate the ResourceProvider releasing the resources back to the video
+ // updater.
+ for (ReleaseCallbackImpl& release_callback : resources.release_callbacks)
+ release_callback.Run(0, false, nullptr);
- // Delete the resources.
- resource_provider3d_->DeleteResource(y_resource);
- resource_provider3d_->DeleteResource(u_resource);
- resource_provider3d_->DeleteResource(v_resource);
+ // Allocate resources for the same frame.
+ context3d_->ResetUploadCount();
+ resources = updater.CreateExternalResourcesFromVideoFrame(video_frame);
+ EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
+ EXPECT_EQ(size_t(3), resources.mailboxes.size());
+ EXPECT_EQ(size_t(3), resources.release_callbacks.size());
+ // The data should be reused so expect no texture uploads.
+ EXPECT_EQ(0, context3d_->UploadCount());
+}
+
+TEST_F(VideoResourceUpdaterTest, ReuseResourceNoDelete) {
+ VideoResourceUpdater updater(output_surface3d_->context_provider(),
+ resource_provider3d_.get());
+ scoped_refptr<media::VideoFrame> video_frame = CreateTestYUVVideoFrame();
+ video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234));
+
+ // Allocate the resources for a YUV video frame.
+ context3d_->ResetUploadCount();
+ VideoFrameExternalResources resources =
+ updater.CreateExternalResourcesFromVideoFrame(video_frame);
+ EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
+ EXPECT_EQ(size_t(3), resources.mailboxes.size());
+ EXPECT_EQ(size_t(3), resources.release_callbacks.size());
+ // Expect exactly three texture uploads, one for each plane.
+ EXPECT_EQ(3, context3d_->UploadCount());
// Allocate resources for the same frame.
context3d_->ResetUploadCount();
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index 3e7653f..143c3ff 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -723,10 +723,6 @@
RescheduleBeginImplFrameDeadlineIfNeeded();
}
-bool Scheduler::WillDrawIfNeeded() const {
- return !state_machine_.PendingDrawsShouldBeAborted();
-}
-
scoped_refptr<base::debug::ConvertableToTraceFormat> Scheduler::AsValue()
const {
scoped_refptr<base::debug::TracedValue> state =
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h
index 27dbee3..dea7c3e 100644
--- a/cc/scheduler/scheduler.h
+++ b/cc/scheduler/scheduler.h
@@ -153,8 +153,6 @@
return !begin_impl_frame_deadline_task_.IsCancelled();
}
- bool WillDrawIfNeeded() const;
-
base::TimeTicks AnticipatedDrawTime() const;
void NotifyBeginMainFrameStarted();
diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc
index 7bbfa37..5f413b3 100644
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -9,24 +9,44 @@
#include "cc/test/begin_frame_args_test.h"
#include "testing/gtest/include/gtest/gtest.h"
-#define EXPECT_ACTION_UPDATE_STATE(action) \
- EXPECT_STREQ(SchedulerStateMachine::ActionToString(action), \
- SchedulerStateMachine::ActionToString(state.NextAction())) \
- << state.AsValue()->ToString(); \
- if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE || \
- action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) { \
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, \
- state.begin_impl_frame_state()) \
- << state.AsValue()->ToString(); \
- } \
- state.UpdateState(action); \
- if (action == SchedulerStateMachine::ACTION_NONE) { \
- if (state.begin_impl_frame_state() == \
- SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \
- state.OnBeginImplFrameDeadlinePending(); \
- if (state.begin_impl_frame_state() == \
- SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \
- state.OnBeginImplFrameIdle(); \
+// Macro to compare two enum values and get nice output.
+// Without:
+// Value of: actual() Actual: 7
+// Expected: expected() Which is: 0
+// With:
+// Value of: actual() Actual: "ACTION_ANIMATE"
+// Expected: expected() Which is: "ACTION_NONE"
+#define EXPECT_ENUM_EQ(enum_tostring, expected, actual) \
+ EXPECT_STREQ(SchedulerStateMachine::enum_tostring(expected), \
+ SchedulerStateMachine::enum_tostring(actual))
+
+#define EXPECT_IMPL_FRAME_STATE(expected) \
+ EXPECT_ENUM_EQ(BeginImplFrameStateToString, expected, \
+ state.begin_impl_frame_state()) \
+ << state.AsValue()->ToString()
+
+#define EXPECT_COMMIT_STATE(expected) \
+ EXPECT_ENUM_EQ(CommitStateToString, expected, state.CommitState())
+
+#define EXPECT_ACTION(expected) \
+ EXPECT_ENUM_EQ(ActionToString, expected, state.NextAction()) \
+ << state.AsValue()->ToString()
+
+#define EXPECT_ACTION_UPDATE_STATE(action) \
+ EXPECT_ACTION(action); \
+ if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE || \
+ action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) { \
+ EXPECT_IMPL_FRAME_STATE( \
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE); \
+ } \
+ state.UpdateState(action); \
+ if (action == SchedulerStateMachine::ACTION_NONE) { \
+ if (state.begin_impl_frame_state() == \
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \
+ state.OnBeginImplFrameDeadlinePending(); \
+ if (state.begin_impl_frame_state() == \
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \
+ state.OnBeginImplFrameIdle(); \
}
namespace cc {
@@ -177,8 +197,8 @@
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
EXPECT_FALSE(state.NeedsCommit());
}
}
@@ -210,7 +230,7 @@
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
@@ -243,7 +263,7 @@
state.DidSwapBuffersComplete();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
}
TEST(SchedulerStateMachineTest,
@@ -621,19 +641,16 @@
expected_action = SchedulerStateMachine::ACTION_COMMIT;
} else {
expected_action = SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
- EXPECT_EQ(state.NextAction(), SchedulerStateMachine::ACTION_ANIMATE)
- << state.AsValue()->ToString();
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_ANIMATE);
state.UpdateState(state.NextAction());
}
// Case 1: needs_commit=false.
- EXPECT_EQ(state.NextAction(), expected_action)
- << state.AsValue()->ToString();
+ EXPECT_ACTION(expected_action);
// Case 2: needs_commit=true.
state.SetNeedsCommit();
- EXPECT_EQ(state.NextAction(), expected_action)
- << state.AsValue()->ToString();
+ EXPECT_ACTION(expected_action);
}
}
@@ -740,8 +757,8 @@
state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
// Now, while the frame is in progress, set another commit.
state.SetNeedsCommit();
@@ -750,33 +767,31 @@
// Let the frame finish.
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
// Expect to commit regardless of BeginImplFrame state.
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
- state.begin_impl_frame_state());
- EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
+ EXPECT_IMPL_FRAME_STATE(
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
state.OnBeginImplFrameDeadlinePending();
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
- state.begin_impl_frame_state());
- EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
+ EXPECT_IMPL_FRAME_STATE(
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
state.OnBeginImplFrameDeadline();
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
- state.begin_impl_frame_state());
- EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
+ EXPECT_IMPL_FRAME_STATE(
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
state.OnBeginImplFrameIdle();
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
- state.begin_impl_frame_state());
- EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
+ EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
- state.begin_impl_frame_state());
- EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
+ EXPECT_IMPL_FRAME_STATE(
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
// Finish the commit, then make sure we start the next commit immediately
// and draw on the next BeginImplFrame.
@@ -813,16 +828,15 @@
state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
EXPECT_FALSE(state.NeedsCommit());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
// Tell the scheduler the frame finished.
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
// Commit.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
@@ -843,7 +857,7 @@
// Should be synchronized, no draw needed, no action needed.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
EXPECT_FALSE(state.needs_redraw());
}
@@ -864,16 +878,15 @@
state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
EXPECT_FALSE(state.NeedsCommit());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
// Tell the scheduler the frame finished.
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
// Commit.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
@@ -881,8 +894,7 @@
EXPECT_TRUE(state.needs_redraw());
// Now commit should wait for draw.
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW,
- state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW);
// Swap throttled. Do not draw.
state.DidSwapBuffers();
@@ -906,7 +918,7 @@
state.DidSwapBuffersComplete();
// Now will be able to start main frame.
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
EXPECT_FALSE(state.needs_redraw());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
@@ -931,23 +943,22 @@
state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
EXPECT_FALSE(state.NeedsCommit());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
// Tell the scheduler the frame finished.
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
// Commit.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
// Now commit should wait for activation.
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION);
// No activation yet, so this commit is not drawn yet. Force to draw this
// frame, and still block BeginMainFrame.
@@ -961,8 +972,8 @@
// Cannot BeginMainFrame yet since last commit is not yet activated and drawn.
state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
// Now activate sync tree.
@@ -971,8 +982,7 @@
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_TRUE(state.needs_redraw());
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW,
- state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW);
// Swap throttled. Do not draw.
state.DidSwapBuffers();
@@ -995,7 +1005,7 @@
state.DidSwapBuffersComplete();
// Now will be able to start main frame.
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
EXPECT_FALSE(state.needs_redraw());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
@@ -1017,8 +1027,8 @@
state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
EXPECT_FALSE(state.NeedsCommit());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
@@ -1029,8 +1039,7 @@
// Tell the scheduler the frame finished.
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
// First commit.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
@@ -1051,7 +1060,7 @@
// Should be synchronized, no draw needed, no action needed.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
EXPECT_FALSE(state.needs_redraw());
// Next BeginImplFrame should initiate second commit.
@@ -1086,8 +1095,8 @@
state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
EXPECT_FALSE(state.NeedsCommit());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
@@ -1096,7 +1105,7 @@
state.BeginMainFrameAborted(false);
// We should now be back in the idle state as if we never started the frame.
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
// We shouldn't do anything on the BeginImplFrame deadline.
@@ -1108,8 +1117,8 @@
// Although we have aborted on this frame and haven't cancelled the commit
// (i.e. need another), don't send another BeginMainFrame yet.
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.NeedsCommit());
// Start a new frame.
@@ -1118,8 +1127,8 @@
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
// We should be starting the commit now.
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
}
@@ -1137,17 +1146,17 @@
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
EXPECT_FALSE(state.NeedsCommit());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
// Abort the commit, cancelling future commits.
state.BeginMainFrameAborted(true);
// Verify that another commit doesn't start on the same frame.
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
EXPECT_FALSE(state.NeedsCommit());
// Start a new frame; draw because this is the first frame since output
@@ -1162,15 +1171,14 @@
state.DidSwapBuffersComplete();
// Verify another commit doesn't start on another frame either.
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
EXPECT_FALSE(state.NeedsCommit());
// Verify another commit can start if requested, though.
state.SetNeedsCommit();
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
- EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
- state.NextAction());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
}
TEST(SchedulerStateMachineTest,
@@ -1188,18 +1196,18 @@
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
EXPECT_FALSE(state.NeedsCommit());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
// Become invisible and abort BeginMainFrame.
state.SetVisible(false);
state.BeginMainFrameAborted(true);
// Verify that another commit doesn't start on the same frame.
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
EXPECT_FALSE(state.NeedsCommit());
// Become visible and start a new frame.
@@ -1216,15 +1224,14 @@
state.DidSwapBuffersComplete();
// Verify another commit doesn't start on another frame either.
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
EXPECT_FALSE(state.NeedsCommit());
// Verify another commit can start if requested, though.
state.SetNeedsCommit();
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
- EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
- state.NextAction());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
}
TEST(SchedulerStateMachineTest,
@@ -1242,30 +1249,30 @@
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
EXPECT_FALSE(state.NeedsCommit());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
// Become invisible and abort BeginMainFrame.
state.SetVisible(false);
state.BeginMainFrameAborted(true);
// Verify that another commit doesn't start on the same frame.
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
EXPECT_FALSE(state.NeedsCommit());
// Asking for a commit while not visible won't make it happen.
state.SetNeedsCommit();
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.NeedsCommit());
// Become visible but nothing happens until the next frame.
state.SetVisible(true);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.NeedsCommit());
// We should get that commit when we begin the next frame.
@@ -1290,10 +1297,10 @@
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
EXPECT_FALSE(state.NeedsCommit());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
// Become invisible and abort BeginMainFrame.
state.SetVisible(false);
@@ -1301,20 +1308,20 @@
// Asking for a commit while not visible won't make it happen.
state.SetNeedsCommit();
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.NeedsCommit());
// Begin a frame when not visible, the scheduler animates but does not commit.
state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.NeedsCommit());
// Become visible and the requested commit happens immediately.
state.SetVisible(true);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
+ EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
}
@@ -1358,8 +1365,7 @@
state.NextAction());
state.DidLoseOutputSurface();
- EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
- state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
state.UpdateState(state.NextAction());
// Once context recreation begins, nothing should happen.
@@ -1413,8 +1419,8 @@
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
- state.CommitState());
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
@@ -1430,14 +1436,11 @@
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
- EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
- state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
state.SetCanDraw(false);
- EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT,
- state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
state.SetCanDraw(true);
- EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
- state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
}
TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
@@ -1471,7 +1474,7 @@
// Ask for another draw. Expect nothing happens.
state.SetNeedsRedraw(true);
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
// Finish the frame, and commit.
state.NotifyBeginMainFrameStarted();
@@ -1484,25 +1487,23 @@
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
// Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
- state.begin_impl_frame_state());
- EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
- state.NextAction());
+ EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
- state.begin_impl_frame_state());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_IMPL_FRAME_STATE(
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadlinePending();
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
- state.begin_impl_frame_state());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_IMPL_FRAME_STATE(
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
- state.begin_impl_frame_state());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_IMPL_FRAME_STATE(
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
}
TEST(SchedulerStateMachineTest,
@@ -1551,25 +1552,23 @@
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
// Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
- state.begin_impl_frame_state());
- EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
- state.NextAction());
+ EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
- state.begin_impl_frame_state());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_IMPL_FRAME_STATE(
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadlinePending();
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
- state.begin_impl_frame_state());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_IMPL_FRAME_STATE(
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
- EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
- state.begin_impl_frame_state());
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_IMPL_FRAME_STATE(
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameIdle();
EXPECT_ACTION_UPDATE_STATE(
@@ -1607,15 +1606,13 @@
// Cause a lost output surface, and restore it.
state.DidLoseOutputSurface();
- EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
- state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
state.UpdateState(state.NextAction());
state.DidCreateAndInitializeOutputSurface();
EXPECT_FALSE(state.RedrawPending());
state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
- EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
- state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
}
TEST(SchedulerStateMachineTest,
@@ -1654,7 +1651,7 @@
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(false);
state.SetNeedsCommit();
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
}
TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) {
@@ -1670,7 +1667,7 @@
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
- EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
state.UpdateState(state.NextAction());
EXPECT_TRUE(state.active_tree_needs_first_draw());
@@ -1701,8 +1698,7 @@
// lost the output surface and are trying to get the first commit, since the
// main thread will just abort anyway.
state.SetVisible(false);
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction())
- << state.AsValue()->ToString();
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
}
TEST(SchedulerStateMachineTest, ReportIfNotDrawing) {
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc
index 9257446..8833037 100644
--- a/cc/surfaces/display.cc
+++ b/cc/surfaces/display.cc
@@ -118,6 +118,13 @@
TRACE_EVENT0("cc", "Display::Draw");
benchmark_instrumentation::IssueDisplayRenderingStatsEvent();
+
+ // Run callbacks early to allow pipelining.
+ for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
+ Surface* surface = manager_->GetSurfaceForId(id_entry.first);
+ if (surface)
+ surface->RunDrawCallbacks();
+ }
DelegatedFrameData* frame_data = frame->delegated_frame_data.get();
gfx::Size surface_size =
@@ -134,23 +141,13 @@
device_clip_rect,
disable_picture_quad_image_filtering);
- bool disable_swap = surface_size != current_surface_size_;
- if (disable_swap) {
+ if (surface_size != current_surface_size_) {
DidSwapBuffers();
+ DidSwapBuffersComplete();
} else {
renderer_->SwapBuffers(frame->metadata);
}
- for (SurfaceAggregator::SurfaceIndexMap::iterator it =
- aggregator_->previous_contained_surfaces().begin();
- it != aggregator_->previous_contained_surfaces().end();
- ++it) {
- Surface* surface = manager_->GetSurfaceForId(it->first);
- if (surface)
- surface->RunDrawCallbacks();
- }
- if (disable_swap)
- DidSwapBuffersComplete();
return true;
}
@@ -172,8 +169,11 @@
}
void Display::OnSurfaceDamaged(SurfaceId surface) {
- if (aggregator_ && aggregator_->previous_contained_surfaces().count(surface))
+ if (aggregator_ &&
+ aggregator_->previous_contained_surfaces().count(surface)) {
+ aggregator_->ReleaseResources(surface);
client_->DisplayDamaged();
+ }
}
SurfaceId Display::CurrentSurfaceId() {
diff --git a/cc/surfaces/surface.cc b/cc/surfaces/surface.cc
index c7b1145..98ae58c 100644
--- a/cc/surfaces/surface.cc
+++ b/cc/surfaces/surface.cc
@@ -33,10 +33,12 @@
¤t_resources);
factory_->UnrefResources(current_resources);
}
+ if (!draw_callback_.is_null())
+ draw_callback_.Run(false);
}
void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame,
- const base::Closure& callback) {
+ const DrawCallback& callback) {
DCHECK(factory_);
ClearCopyRequests();
TakeLatencyInfo(&frame->metadata.latency_info);
@@ -54,7 +56,7 @@
factory_->UnrefResources(previous_resources);
}
if (!draw_callback_.is_null())
- draw_callback_.Run();
+ draw_callback_.Run(false);
draw_callback_ = callback;
factory_->manager()->DidSatisfySequences(
SurfaceIdAllocator::NamespaceForId(surface_id_),
@@ -106,9 +108,9 @@
void Surface::RunDrawCallbacks() {
if (!draw_callback_.is_null()) {
- base::Closure callback = draw_callback_;
- draw_callback_ = base::Closure();
- callback.Run();
+ DrawCallback callback = draw_callback_;
+ draw_callback_ = DrawCallback();
+ callback.Run(true);
}
}
diff --git a/cc/surfaces/surface.h b/cc/surfaces/surface.h
index ed0061d..96152a0 100644
--- a/cc/surfaces/surface.h
+++ b/cc/surfaces/surface.h
@@ -34,13 +34,15 @@
class CC_SURFACES_EXPORT Surface {
public:
+ using DrawCallback = base::Callback<void(bool)>;
+
Surface(SurfaceId id, SurfaceFactory* factory);
~Surface();
SurfaceId surface_id() const { return surface_id_; }
void QueueFrame(scoped_ptr<CompositorFrame> frame,
- const base::Closure& draw_callback);
+ const DrawCallback& draw_callback);
void RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> copy_request);
// Adds each CopyOutputRequest in the current frame to copy_requests. The
// caller takes ownership of them.
@@ -79,7 +81,7 @@
int frame_index_;
std::vector<SurfaceSequence> destruction_dependencies_;
- base::Closure draw_callback_;
+ DrawCallback draw_callback_;
DISALLOW_COPY_AND_ASSIGN(Surface);
};
diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc
index 2334d14..4c44084 100644
--- a/cc/surfaces/surface_aggregator.cc
+++ b/cc/surfaces/surface_aggregator.cc
@@ -438,4 +438,13 @@
return frame.Pass();
}
+void SurfaceAggregator::ReleaseResources(SurfaceId surface_id) {
+ SurfaceToResourceChildIdMap::iterator it =
+ surface_id_to_resource_child_id_.find(surface_id);
+ if (it != surface_id_to_resource_child_id_.end()) {
+ provider_->DestroyChild(it->second);
+ surface_id_to_resource_child_id_.erase(it);
+ }
+}
+
} // namespace cc
diff --git a/cc/surfaces/surface_aggregator.h b/cc/surfaces/surface_aggregator.h
index 1e68643..9cb0578 100644
--- a/cc/surfaces/surface_aggregator.h
+++ b/cc/surfaces/surface_aggregator.h
@@ -32,6 +32,7 @@
~SurfaceAggregator();
scoped_ptr<CompositorFrame> Aggregate(SurfaceId surface_id);
+ void ReleaseResources(SurfaceId surface_id);
SurfaceIndexMap& previous_contained_surfaces() {
return previous_contained_surfaces_;
}
diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc
index 3e48311..7f6943c 100644
--- a/cc/surfaces/surface_aggregator_unittest.cc
+++ b/cc/surfaces/surface_aggregator_unittest.cc
@@ -123,7 +123,8 @@
scoped_ptr<CompositorFrame> frame(new CompositorFrame);
frame->delegated_frame_data = frame_data.Pass();
- factory_.SubmitFrame(surface_id, frame.Pass(), base::Closure());
+ factory_.SubmitFrame(surface_id, frame.Pass(),
+ SurfaceFactory::DrawCallback());
}
void QueuePassAsFrame(scoped_ptr<RenderPass> pass, SurfaceId surface_id) {
@@ -133,7 +134,8 @@
scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
child_frame->delegated_frame_data = delegated_frame_data.Pass();
- factory_.SubmitFrame(surface_id, child_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(surface_id, child_frame.Pass(),
+ SurfaceFactory::DrawCallback());
}
protected:
@@ -380,7 +382,8 @@
scoped_ptr<CompositorFrame> frame(new CompositorFrame);
frame->delegated_frame_data = frame_data.Pass();
- factory_.SubmitFrame(root_surface_id_, frame.Pass(), base::Closure());
+ factory_.SubmitFrame(root_surface_id_, frame.Pass(),
+ SurfaceFactory::DrawCallback());
}
scoped_ptr<CompositorFrame> aggregated_frame =
@@ -937,7 +940,8 @@
scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
child_frame->delegated_frame_data = child_frame_data.Pass();
- factory_.SubmitFrame(child_surface_id, child_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(child_surface_id, child_frame.Pass(),
+ SurfaceFactory::DrawCallback());
test::Quad root_quads[] = {test::Quad::SolidColorQuad(1),
test::Quad::SurfaceQuad(child_surface_id, 1.f)};
@@ -962,7 +966,8 @@
scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
root_frame->delegated_frame_data = root_frame_data.Pass();
- factory_.SubmitFrame(root_surface_id_, root_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(root_surface_id_, root_frame.Pass(),
+ SurfaceFactory::DrawCallback());
scoped_ptr<CompositorFrame> aggregated_frame =
aggregator_.Aggregate(root_surface_id_);
@@ -1061,7 +1066,8 @@
scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
child_frame->delegated_frame_data = child_frame_data.Pass();
- factory_.SubmitFrame(child_surface_id, child_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(child_surface_id, child_frame.Pass(),
+ SurfaceFactory::DrawCallback());
test::Quad root_quads[] = {test::Quad::SurfaceQuad(child_surface_id, 1.f)};
test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
@@ -1083,7 +1089,8 @@
scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
root_frame->delegated_frame_data = root_frame_data.Pass();
- factory_.SubmitFrame(root_surface_id_, root_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(root_surface_id_, root_frame.Pass(),
+ SurfaceFactory::DrawCallback());
scoped_ptr<CompositorFrame> aggregated_frame =
aggregator_.Aggregate(root_surface_id_);
@@ -1119,7 +1126,8 @@
scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
child_frame->delegated_frame_data = child_frame_data.Pass();
- factory_.SubmitFrame(child_surface_id, child_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(child_surface_id, child_frame.Pass(),
+ SurfaceFactory::DrawCallback());
scoped_ptr<CompositorFrame> aggregated_frame =
aggregator_.Aggregate(root_surface_id_);
@@ -1158,7 +1166,8 @@
scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
root_frame->delegated_frame_data = root_frame_data.Pass();
- factory_.SubmitFrame(root_surface_id_, root_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(root_surface_id_, root_frame.Pass(),
+ SurfaceFactory::DrawCallback());
}
{
@@ -1179,7 +1188,8 @@
scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
root_frame->delegated_frame_data = root_frame_data.Pass();
- factory_.SubmitFrame(root_surface_id_, root_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(root_surface_id_, root_frame.Pass(),
+ SurfaceFactory::DrawCallback());
scoped_ptr<CompositorFrame> aggregated_frame =
aggregator_.Aggregate(root_surface_id_);
@@ -1295,7 +1305,8 @@
frame_data->render_pass_list.push_back(pass.Pass());
scoped_ptr<CompositorFrame> frame(new CompositorFrame);
frame->delegated_frame_data = frame_data.Pass();
- factory->SubmitFrame(surface_id, frame.Pass(), base::Closure());
+ factory->SubmitFrame(surface_id, frame.Pass(),
+ SurfaceFactory::DrawCallback());
}
TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) {
diff --git a/cc/surfaces/surface_factory.cc b/cc/surfaces/surface_factory.cc
index fd5a6d4..7af7cb7 100644
--- a/cc/surfaces/surface_factory.cc
+++ b/cc/surfaces/surface_factory.cc
@@ -46,7 +46,7 @@
void SurfaceFactory::SubmitFrame(SurfaceId surface_id,
scoped_ptr<CompositorFrame> frame,
- const base::Closure& callback) {
+ const DrawCallback& callback) {
OwningSurfaceMap::iterator it = surface_map_.find(surface_id);
DCHECK(it != surface_map_.end());
DCHECK(it->second->factory().get() == this);
diff --git a/cc/surfaces/surface_factory.h b/cc/surfaces/surface_factory.h
index eba32d2..7abd929 100644
--- a/cc/surfaces/surface_factory.h
+++ b/cc/surfaces/surface_factory.h
@@ -35,6 +35,10 @@
class CC_SURFACES_EXPORT SurfaceFactory
: public base::SupportsWeakPtr<SurfaceFactory> {
public:
+ // This callback is called with true if the frame was drawn, or false if it
+ // was discarded.
+ using DrawCallback = base::Callback<void(bool)>;
+
SurfaceFactory(SurfaceManager* manager, SurfaceFactoryClient* client);
~SurfaceFactory();
@@ -43,10 +47,11 @@
void DestroyAll();
// A frame can only be submitted to a surface created by this factory,
// although the frame may reference surfaces created by other factories.
- // The callback is called the first time this frame is used to draw.
+ // The callback is called the first time this frame is used to draw, or if
+ // the frame is discarded.
void SubmitFrame(SurfaceId surface_id,
scoped_ptr<CompositorFrame> frame,
- const base::Closure& callback);
+ const DrawCallback& callback);
void RequestCopyOfSurface(SurfaceId surface_id,
scoped_ptr<CopyOutputRequest> copy_request);
diff --git a/cc/surfaces/surface_factory_unittest.cc b/cc/surfaces/surface_factory_unittest.cc
index 84dcc5e..1a87c0f 100644
--- a/cc/surfaces/surface_factory_unittest.cc
+++ b/cc/surfaces/surface_factory_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/bind.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/delegated_frame_data.h"
#include "cc/surfaces/surface.h"
@@ -58,7 +59,8 @@
}
scoped_ptr<CompositorFrame> frame(new CompositorFrame);
frame->delegated_frame_data = frame_data.Pass();
- factory_.SubmitFrame(surface_id_, frame.Pass(), base::Closure());
+ factory_.SubmitFrame(surface_id_, frame.Pass(),
+ SurfaceFactory::DrawCallback());
}
void UnrefResources(ResourceProvider::ResourceId* ids_to_unref,
@@ -358,6 +360,11 @@
}
}
+void DrawCallback(bool* executed, bool* result, bool drawn) {
+ *executed = true;
+ *result = drawn;
+}
+
// Tests doing a DestroyAll before shutting down the factory;
TEST_F(SurfaceFactoryTest, DestroyAll) {
SurfaceId id(7);
@@ -370,10 +377,17 @@
frame_data->resource_list.push_back(resource);
scoped_ptr<CompositorFrame> frame(new CompositorFrame);
frame->delegated_frame_data = frame_data.Pass();
- factory_.SubmitFrame(id, frame.Pass(), base::Closure());
+ bool executed = false;
+ bool drawn = false;
+
+ factory_.SubmitFrame(id, frame.Pass(),
+ base::Bind(&DrawCallback, &executed, &drawn));
surface_id_ = SurfaceId();
+ EXPECT_FALSE(executed);
factory_.DestroyAll();
+ EXPECT_TRUE(executed);
+ EXPECT_FALSE(drawn);
}
TEST_F(SurfaceFactoryTest, DestroySequence) {
@@ -391,7 +405,8 @@
frame->metadata.satisfies_sequences.push_back(4);
frame->delegated_frame_data = frame_data.Pass();
DCHECK(manager_.GetSurfaceForId(id2));
- factory_.SubmitFrame(surface_id_, frame.Pass(), base::Closure());
+ factory_.SubmitFrame(surface_id_, frame.Pass(),
+ SurfaceFactory::DrawCallback());
DCHECK(!manager_.GetSurfaceForId(id2));
// Check that waiting after the sequence is satisfied works.
diff --git a/cc/surfaces/surfaces_pixeltest.cc b/cc/surfaces/surfaces_pixeltest.cc
index bf9d483..528684b 100644
--- a/cc/surfaces/surfaces_pixeltest.cc
+++ b/cc/surfaces/surfaces_pixeltest.cc
@@ -86,7 +86,8 @@
SurfaceId root_surface_id = allocator_.GenerateId();
factory_.Create(root_surface_id);
- factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(root_surface_id, root_frame.Pass(),
+ SurfaceFactory::DrawCallback());
SurfaceAggregator aggregator(&manager_, resource_provider_.get());
scoped_ptr<CompositorFrame> aggregated_frame =
@@ -140,7 +141,8 @@
scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
root_frame->delegated_frame_data = delegated_frame_data.Pass();
- factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(root_surface_id, root_frame.Pass(),
+ SurfaceFactory::DrawCallback());
}
{
@@ -167,7 +169,8 @@
scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
child_frame->delegated_frame_data = delegated_frame_data.Pass();
- factory_.SubmitFrame(child_surface_id, child_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(child_surface_id, child_frame.Pass(),
+ SurfaceFactory::DrawCallback());
}
SurfaceAggregator aggregator(&manager_, resource_provider_.get());
@@ -237,7 +240,8 @@
scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
root_frame->delegated_frame_data = delegated_frame_data.Pass();
- factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(root_surface_id, root_frame.Pass(),
+ SurfaceFactory::DrawCallback());
}
{
@@ -272,7 +276,8 @@
scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
child_frame->delegated_frame_data = delegated_frame_data.Pass();
- factory_.SubmitFrame(left_child_id, child_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(left_child_id, child_frame.Pass(),
+ SurfaceFactory::DrawCallback());
}
{
@@ -307,7 +312,8 @@
scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
child_frame->delegated_frame_data = delegated_frame_data.Pass();
- factory_.SubmitFrame(right_child_id, child_frame.Pass(), base::Closure());
+ factory_.SubmitFrame(right_child_id, child_frame.Pass(),
+ SurfaceFactory::DrawCallback());
}
SurfaceAggregator aggregator(&manager_, resource_provider_.get());
diff --git a/cc/test/failure_output_surface.cc b/cc/test/failure_output_surface.cc
new file mode 100644
index 0000000..2c87853
--- /dev/null
+++ b/cc/test/failure_output_surface.cc
@@ -0,0 +1,19 @@
+// 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 "cc/test/failure_output_surface.h"
+
+namespace cc {
+
+FailureOutputSurface::FailureOutputSurface(bool is_delegating)
+ : FakeOutputSurface(nullptr, nullptr, is_delegating) {
+}
+
+bool FailureOutputSurface::BindToClient(OutputSurfaceClient* client) {
+ // This will force this output surface to not initialize in LTHI
+ // and eventually get back to LTH::DidFailToInitializeOutputSurface;
+ return false;
+}
+
+} // namespace cc
diff --git a/cc/test/failure_output_surface.h b/cc/test/failure_output_surface.h
new file mode 100644
index 0000000..4878ea5
--- /dev/null
+++ b/cc/test/failure_output_surface.h
@@ -0,0 +1,24 @@
+// 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 CC_TEST_FAILURE_OUTPUT_SURFACE_H_
+#define CC_TEST_FAILURE_OUTPUT_SURFACE_H_
+
+#include "cc/test/fake_output_surface.h"
+
+namespace cc {
+
+class FailureOutputSurface : public FakeOutputSurface {
+ public:
+ explicit FailureOutputSurface(bool is_delegating);
+
+ bool BindToClient(OutputSurfaceClient* client) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FailureOutputSurface);
+};
+
+} // namespace cc
+
+#endif // CC_TEST_FAILURE_OUTPUT_SURFACE_H_
diff --git a/cc/test/fake_layer_tree_host_client.cc b/cc/test/fake_layer_tree_host_client.cc
index 17ed10c..a4a5d7e 100644
--- a/cc/test/fake_layer_tree_host_client.cc
+++ b/cc/test/fake_layer_tree_host_client.cc
@@ -21,7 +21,7 @@
FakeLayerTreeHostClient::~FakeLayerTreeHostClient() {}
-void FakeLayerTreeHostClient::RequestNewOutputSurface(bool fallback) {
+void FakeLayerTreeHostClient::RequestNewOutputSurface() {
DCHECK(host_);
scoped_ptr<OutputSurface> surface;
if (use_software_rendering_) {
@@ -40,4 +40,8 @@
host_->SetOutputSurface(surface.Pass());
}
+void FakeLayerTreeHostClient::DidFailToInitializeOutputSurface() {
+ RequestNewOutputSurface();
+}
+
} // namespace cc
diff --git a/cc/test/fake_layer_tree_host_client.h b/cc/test/fake_layer_tree_host_client.h
index 6f24116..f256ab1 100644
--- a/cc/test/fake_layer_tree_host_client.h
+++ b/cc/test/fake_layer_tree_host_client.h
@@ -43,8 +43,9 @@
float page_scale,
float top_controls_delta) override {}
- void RequestNewOutputSurface(bool fallback) override;
+ void RequestNewOutputSurface() override;
void DidInitializeOutputSurface() override {}
+ void DidFailToInitializeOutputSurface() override;
void WillCommit() override {}
void DidCommit() override {}
void DidCommitAndDrawFrame() override {}
diff --git a/cc/test/fake_picture_layer_impl.cc b/cc/test/fake_picture_layer_impl.cc
index 13b20ad..8153442 100644
--- a/cc/test/fake_picture_layer_impl.cc
+++ b/cc/test/fake_picture_layer_impl.cc
@@ -13,36 +13,40 @@
FakePictureLayerImpl::FakePictureLayerImpl(
LayerTreeImpl* tree_impl,
int id,
- scoped_refptr<RasterSource> raster_source)
- : PictureLayerImpl(tree_impl, id),
+ scoped_refptr<RasterSource> raster_source,
+ bool is_mask)
+ : PictureLayerImpl(tree_impl, id, is_mask),
append_quads_count_(0),
did_become_active_call_count_(0),
has_valid_tile_priorities_(false),
use_set_valid_tile_priorities_flag_(false),
release_resources_count_(0) {
- raster_source_ = raster_source;
- SetBounds(raster_source_->GetSize());
- SetContentBounds(raster_source_->GetSize());
+ SetBounds(raster_source->GetSize());
+ SetContentBounds(raster_source->GetSize());
+ SetRasterSourceOnPending(raster_source, Region());
}
FakePictureLayerImpl::FakePictureLayerImpl(
LayerTreeImpl* tree_impl,
int id,
scoped_refptr<RasterSource> raster_source,
+ bool is_mask,
const gfx::Size& layer_bounds)
- : PictureLayerImpl(tree_impl, id),
+ : PictureLayerImpl(tree_impl, id, is_mask),
append_quads_count_(0),
did_become_active_call_count_(0),
has_valid_tile_priorities_(false),
use_set_valid_tile_priorities_flag_(false),
release_resources_count_(0) {
- raster_source_ = raster_source;
SetBounds(layer_bounds);
SetContentBounds(layer_bounds);
+ SetRasterSourceOnPending(raster_source, Region());
}
-FakePictureLayerImpl::FakePictureLayerImpl(LayerTreeImpl* tree_impl, int id)
- : PictureLayerImpl(tree_impl, id),
+FakePictureLayerImpl::FakePictureLayerImpl(LayerTreeImpl* tree_impl,
+ int id,
+ bool is_mask)
+ : PictureLayerImpl(tree_impl, id, is_mask),
append_quads_count_(0),
did_become_active_call_count_(0),
has_valid_tile_priorities_(false),
@@ -52,7 +56,14 @@
scoped_ptr<LayerImpl> FakePictureLayerImpl::CreateLayerImpl(
LayerTreeImpl* tree_impl) {
- return make_scoped_ptr(new FakePictureLayerImpl(tree_impl, id()));
+ return make_scoped_ptr(new FakePictureLayerImpl(tree_impl, id(), is_mask_));
+}
+
+void FakePictureLayerImpl::PushPropertiesTo(LayerImpl* layer_impl) {
+ FakePictureLayerImpl* picture_layer_impl =
+ static_cast<FakePictureLayerImpl*>(layer_impl);
+ picture_layer_impl->fixed_tile_size_ = fixed_tile_size_;
+ PictureLayerImpl::PushPropertiesTo(layer_impl);
}
void FakePictureLayerImpl::AppendQuads(
@@ -99,15 +110,13 @@
return result;
}
-void FakePictureLayerImpl::SetRasterSource(
- scoped_refptr<RasterSource> raster_source) {
- raster_source_.swap(raster_source);
- if (tilings()) {
- for (size_t i = 0; i < num_tilings(); ++i) {
- tilings()->tiling_at(i)->UpdateTilesToCurrentRasterSource(
- raster_source_.get(), Region(), raster_source_->GetSize());
- }
- }
+void FakePictureLayerImpl::SetRasterSourceOnPending(
+ scoped_refptr<RasterSource> raster_source,
+ const Region& invalidation) {
+ DCHECK(layer_tree_impl()->IsPendingTree());
+ Region invalidation_temp = invalidation;
+ const PictureLayerTilingSet* pending_set = nullptr;
+ UpdateRasterSource(raster_source, &invalidation_temp, pending_set);
}
void FakePictureLayerImpl::SetAllTilesVisible() {
diff --git a/cc/test/fake_picture_layer_impl.h b/cc/test/fake_picture_layer_impl.h
index b10b357..d633051 100644
--- a/cc/test/fake_picture_layer_impl.h
+++ b/cc/test/fake_picture_layer_impl.h
@@ -14,7 +14,8 @@
public:
static scoped_ptr<FakePictureLayerImpl> Create(
LayerTreeImpl* tree_impl, int id) {
- return make_scoped_ptr(new FakePictureLayerImpl(tree_impl, id));
+ bool is_mask = false;
+ return make_scoped_ptr(new FakePictureLayerImpl(tree_impl, id, is_mask));
}
// Create layer from a raster source that covers the entire layer.
@@ -22,8 +23,9 @@
LayerTreeImpl* tree_impl,
int id,
scoped_refptr<RasterSource> raster_source) {
+ bool is_mask = false;
return make_scoped_ptr(
- new FakePictureLayerImpl(tree_impl, id, raster_source));
+ new FakePictureLayerImpl(tree_impl, id, raster_source, is_mask));
}
// Create layer from a raster source that only covers part of the layer.
@@ -32,11 +34,24 @@
int id,
scoped_refptr<RasterSource> raster_source,
const gfx::Size& layer_bounds) {
+ bool is_mask = false;
+ return make_scoped_ptr(new FakePictureLayerImpl(
+ tree_impl, id, raster_source, is_mask, layer_bounds));
+ }
+
+ // Create layer from a raster source that covers the entire layer and is a
+ // mask.
+ static scoped_ptr<FakePictureLayerImpl> CreateMaskWithRasterSource(
+ LayerTreeImpl* tree_impl,
+ int id,
+ scoped_refptr<RasterSource> raster_source) {
+ bool is_mask = true;
return make_scoped_ptr(
- new FakePictureLayerImpl(tree_impl, id, raster_source, layer_bounds));
+ new FakePictureLayerImpl(tree_impl, id, raster_source, is_mask));
}
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
+ void PushPropertiesTo(LayerImpl* layer_impl) override;
void AppendQuads(RenderPass* render_pass,
const Occlusion& occlusion_in_content_space,
AppendQuadsData* append_quads_data) override;
@@ -91,7 +106,8 @@
PictureLayerTilingSet* tilings() { return tilings_.get(); }
RasterSource* raster_source() { return raster_source_.get(); }
- void SetRasterSource(scoped_refptr<RasterSource> raster_source);
+ void SetRasterSourceOnPending(scoped_refptr<RasterSource> raster_source,
+ const Region& invalidation);
size_t append_quads_count() { return append_quads_count_; }
const Region& invalidation() const { return invalidation_; }
@@ -103,7 +119,9 @@
void set_fixed_tile_size(const gfx::Size& size) { fixed_tile_size_ = size; }
+ // TODO(danakj): Remove this darn thing.
void CreateDefaultTilingsAndTiles();
+
void SetAllTilesVisible();
void SetAllTilesReady();
void SetAllTilesReadyInTiling(PictureLayerTiling* tiling);
@@ -123,12 +141,14 @@
protected:
FakePictureLayerImpl(LayerTreeImpl* tree_impl,
int id,
- scoped_refptr<RasterSource> raster_source);
+ scoped_refptr<RasterSource> raster_source,
+ bool is_mask);
FakePictureLayerImpl(LayerTreeImpl* tree_impl,
int id,
scoped_refptr<RasterSource> raster_source,
+ bool is_mask,
const gfx::Size& layer_bounds);
- FakePictureLayerImpl(LayerTreeImpl* tree_impl, int id);
+ FakePictureLayerImpl(LayerTreeImpl* tree_impl, int id, bool is_mask);
private:
gfx::Size fixed_tile_size_;
diff --git a/cc/test/fake_picture_layer_tiling_client.cc b/cc/test/fake_picture_layer_tiling_client.cc
index b21e011..6c1dc98 100644
--- a/cc/test/fake_picture_layer_tiling_client.cc
+++ b/cc/test/fake_picture_layer_tiling_client.cc
@@ -17,10 +17,7 @@
twin_tiling_(NULL),
recycled_twin_tiling_(NULL),
allow_create_tile_(true),
- max_tile_priority_bin_(TilePriority::NOW),
- max_tiles_for_interest_area_(10000),
- skewport_target_time_in_seconds_(1.0f),
- skewport_extrapolation_limit_in_content_pixels_(2000) {
+ max_tile_priority_bin_(TilePriority::NOW) {
}
FakePictureLayerTilingClient::FakePictureLayerTilingClient(
@@ -33,9 +30,7 @@
twin_tiling_(NULL),
recycled_twin_tiling_(NULL),
allow_create_tile_(true),
- max_tile_priority_bin_(TilePriority::NOW),
- max_tiles_for_interest_area_(10000),
- skewport_target_time_in_seconds_(1.0f) {
+ max_tile_priority_bin_(TilePriority::NOW) {
}
FakePictureLayerTilingClient::~FakePictureLayerTilingClient() {
@@ -63,19 +58,6 @@
return max_tile_priority_bin_;
}
-size_t FakePictureLayerTilingClient::GetMaxTilesForInterestArea() const {
- return max_tiles_for_interest_area_;
-}
-
-float FakePictureLayerTilingClient::GetSkewportTargetTimeInSeconds() const {
- return skewport_target_time_in_seconds_;
-}
-
-int FakePictureLayerTilingClient::GetSkewportExtrapolationLimitInContentPixels()
- const {
- return skewport_extrapolation_limit_in_content_pixels_;
-}
-
const Region* FakePictureLayerTilingClient::GetPendingInvalidation() {
return &invalidation_;
}
diff --git a/cc/test/fake_picture_layer_tiling_client.h b/cc/test/fake_picture_layer_tiling_client.h
index acf26d0..935765b 100644
--- a/cc/test/fake_picture_layer_tiling_client.h
+++ b/cc/test/fake_picture_layer_tiling_client.h
@@ -25,10 +25,6 @@
const gfx::Rect& rect) override;
gfx::Size CalculateTileSize(const gfx::Size& content_bounds) const override;
TilePriority::PriorityBin GetMaxTilePriorityBin() const override;
- size_t GetMaxTilesForInterestArea() const override;
- float GetSkewportTargetTimeInSeconds() const override;
- int GetSkewportExtrapolationLimitInContentPixels() const override;
- bool RequiresHighResToDraw() const override;
void SetTileSize(const gfx::Size& tile_size);
gfx::Size TileSize() const { return tile_size_; }
@@ -38,6 +34,7 @@
const PictureLayerTiling* tiling) const override;
PictureLayerTiling* GetRecycledTwinTiling(
const PictureLayerTiling* tiling) override;
+ bool RequiresHighResToDraw() const override;
WhichTree GetTree() const override;
void set_twin_tiling(PictureLayerTiling* tiling) { twin_tiling_ = tiling; }
@@ -50,15 +47,6 @@
void set_max_tile_priority_bin(TilePriority::PriorityBin bin) {
max_tile_priority_bin_ = bin;
}
- void set_max_tiles_for_interest_area(size_t area) {
- max_tiles_for_interest_area_ = area;
- }
- void set_skewport_target_time_in_seconds(float time) {
- skewport_target_time_in_seconds_ = time;
- }
- void set_skewport_extrapolation_limit_in_content_pixels(int limit) {
- skewport_extrapolation_limit_in_content_pixels_ = limit;
- }
void set_tree(WhichTree tree) { tree_ = tree; }
RasterSource* raster_source() { return pile_.get(); }
@@ -78,9 +66,6 @@
bool allow_create_tile_;
Region invalidation_;
TilePriority::PriorityBin max_tile_priority_bin_;
- size_t max_tiles_for_interest_area_;
- float skewport_target_time_in_seconds_;
- int skewport_extrapolation_limit_in_content_pixels_;
WhichTree tree_;
};
diff --git a/cc/test/fake_tile_manager.cc b/cc/test/fake_tile_manager.cc
index f85946a..bb23aa8 100644
--- a/cc/test/fake_tile_manager.cc
+++ b/cc/test/fake_tile_manager.cc
@@ -67,7 +67,6 @@
base::MessageLoopProxy::current(),
NULL,
g_fake_tile_task_runner.Pointer(),
- NULL,
std::numeric_limits<size_t>::max()) {
}
@@ -77,7 +76,6 @@
base::MessageLoopProxy::current(),
resource_pool,
g_fake_tile_task_runner.Pointer(),
- NULL,
std::numeric_limits<size_t>::max()) {
}
diff --git a/cc/test/layer_tree_pixel_resource_test.cc b/cc/test/layer_tree_pixel_resource_test.cc
index e2b768a..83a338e 100644
--- a/cc/test/layer_tree_pixel_resource_test.cc
+++ b/cc/test/layer_tree_pixel_resource_test.cc
@@ -217,6 +217,9 @@
if (!IsTestCaseSupported(test_case_))
return;
RunPixelTest(test_type_, content_root, file_name);
+
+ if (layer_tree_host())
+ EXPECT_TRUE(layer_tree_host()->settings().impl_side_painting);
}
ParameterizedPixelResourceTest::ParameterizedPixelResourceTest()
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc
index 23bfcf2..8a053fa 100644
--- a/cc/test/layer_tree_pixel_test.cc
+++ b/cc/test/layer_tree_pixel_test.cc
@@ -35,8 +35,7 @@
LayerTreePixelTest::~LayerTreePixelTest() {}
-scoped_ptr<OutputSurface> LayerTreePixelTest::CreateOutputSurface(
- bool fallback) {
+scoped_ptr<OutputSurface> LayerTreePixelTest::CreateOutputSurface() {
gfx::Size surface_expansion_size(40, 60);
scoped_ptr<PixelTestOutputSurface> output_surface;
diff --git a/cc/test/layer_tree_pixel_test.h b/cc/test/layer_tree_pixel_test.h
index c3c324a..60ea727 100644
--- a/cc/test/layer_tree_pixel_test.h
+++ b/cc/test/layer_tree_pixel_test.h
@@ -40,7 +40,7 @@
LayerTreePixelTest();
virtual ~LayerTreePixelTest();
- scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) override;
+ scoped_ptr<OutputSurface> CreateOutputSurface() override;
void CommitCompleteOnThread(LayerTreeHostImpl* impl) override;
virtual scoped_ptr<CopyOutputRequest> CreateCopyOutputRequest();
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index d6411ec..e5a5687 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -377,8 +377,8 @@
top_controls_delta);
}
- void RequestNewOutputSurface(bool fallback) override {
- test_hooks_->RequestNewOutputSurface(fallback);
+ void RequestNewOutputSurface() override {
+ test_hooks_->RequestNewOutputSurface();
}
void DidInitializeOutputSurface() override {
@@ -391,6 +391,7 @@
void DidFailToInitializeOutputSurface() override {
test_hooks_->DidFailToInitializeOutputSurface();
+ RequestNewOutputSurface();
}
void WillCommit() override { test_hooks_->WillCommit(); }
@@ -785,17 +786,14 @@
RunTest(true, false, true);
}
-void LayerTreeTest::RequestNewOutputSurface(bool fallback) {
- layer_tree_host_->SetOutputSurface(CreateOutputSurface(fallback));
+void LayerTreeTest::RequestNewOutputSurface() {
+ layer_tree_host_->SetOutputSurface(CreateOutputSurface());
}
-scoped_ptr<OutputSurface> LayerTreeTest::CreateOutputSurface(bool fallback) {
- scoped_ptr<FakeOutputSurface> output_surface =
- CreateFakeOutputSurface(fallback);
- if (output_surface) {
- DCHECK_EQ(delegating_renderer_,
- output_surface->capabilities().delegated_rendering);
- }
+scoped_ptr<OutputSurface> LayerTreeTest::CreateOutputSurface() {
+ scoped_ptr<FakeOutputSurface> output_surface = CreateFakeOutputSurface();
+ DCHECK_EQ(delegating_renderer_,
+ output_surface->capabilities().delegated_rendering);
output_surface_ = output_surface.get();
if (settings_.use_external_begin_frame_source &&
@@ -806,8 +804,7 @@
return output_surface.Pass();
}
-scoped_ptr<FakeOutputSurface> LayerTreeTest::CreateFakeOutputSurface(
- bool fallback) {
+scoped_ptr<FakeOutputSurface> LayerTreeTest::CreateFakeOutputSurface() {
if (delegating_renderer_)
return FakeOutputSurface::CreateDelegating3d();
else
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h
index 4176265..02f18b7 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -110,7 +110,7 @@
Animation::TargetProperty target_property,
int group) override {}
- virtual void RequestNewOutputSurface(bool fallback) = 0;
+ virtual void RequestNewOutputSurface() = 0;
};
class BeginTask;
@@ -202,11 +202,11 @@
void DestroyLayerTreeHost();
// By default, output surface recreation is synchronous.
- void RequestNewOutputSurface(bool fallback) override;
+ void RequestNewOutputSurface() override;
// Override this for pixel tests, where you need a real output surface.
- virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback);
+ virtual scoped_ptr<OutputSurface> CreateOutputSurface();
// Override this for unit tests, which should not produce pixel output.
- virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback);
+ virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface();
TestWebGraphicsContext3D* TestContext();
diff --git a/cc/test/render_pass_test_common.cc b/cc/test/render_pass_test_common.cc
index b79fc1f..7237ce1 100644
--- a/cc/test/render_pass_test_common.cc
+++ b/cc/test/render_pass_test_common.cc
@@ -198,6 +198,7 @@
resource2,
gfx::RectF(0, 0, 50, 50),
gfx::Size(50, 50),
+ false,
false);
SharedQuadState* transformed_state = this->CreateAndAppendSharedQuadState();
@@ -215,6 +216,7 @@
resource3,
gfx::RectF(0, 0, 100, 100),
gfx::Size(100, 100),
+ false,
false);
SharedQuadState* shared_state2 = this->CreateAndAppendSharedQuadState();
@@ -235,6 +237,7 @@
resource4,
gfx::RectF(0, 0, 100, 100),
gfx::Size(100, 100),
+ false,
false);
ResourceProvider::ResourceId plane_resources[4];
diff --git a/cc/test/test_context_provider.cc b/cc/test/test_context_provider.cc
index e7697f1..2a2b6f6 100644
--- a/cc/test/test_context_provider.cc
+++ b/cc/test/test_context_provider.cc
@@ -12,6 +12,8 @@
#include "base/logging.h"
#include "cc/test/test_gles2_interface.h"
#include "cc/test/test_web_graphics_context_3d.h"
+#include "third_party/skia/include/gpu/GrContext.h"
+#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
namespace cc {
@@ -90,8 +92,14 @@
DCHECK(bound_);
DCHECK(context_thread_checker_.CalledOnValidThread());
- // TODO(danakj): Make a test GrContext that works with a test Context3d.
- return NULL;
+ if (gr_context_)
+ return gr_context_.get();
+
+ auto null_interface = skia::AdoptRef(GrGLCreateNullInterface());
+ gr_context_ = skia::AdoptRef(GrContext::Create(
+ kOpenGL_GrBackend,
+ reinterpret_cast<GrBackendContext>(null_interface.get())));
+ return gr_context_.get();
}
bool TestContextProvider::IsContextLost() {
diff --git a/cc/test/test_context_provider.h b/cc/test/test_context_provider.h
index 66ae998..3be8b43 100644
--- a/cc/test/test_context_provider.h
+++ b/cc/test/test_context_provider.h
@@ -13,6 +13,7 @@
#include "cc/output/context_provider.h"
#include "cc/test/test_context_support.h"
#include "gpu/command_buffer/client/gles2_interface_stub.h"
+#include "skia/ext/refptr.h"
namespace cc {
class TestWebGraphicsContext3D;
@@ -75,6 +76,7 @@
LostContextCallback lost_context_callback_;
MemoryPolicyChangedCallback memory_policy_changed_callback_;
+ skia::RefPtr<class GrContext> gr_context_;
base::WeakPtrFactory<TestContextProvider> weak_ptr_factory_;
diff --git a/cc/test/test_shared_bitmap_manager.cc b/cc/test/test_shared_bitmap_manager.cc
index 933dcd2..7e14b2f 100644
--- a/cc/test/test_shared_bitmap_manager.cc
+++ b/cc/test/test_shared_bitmap_manager.cc
@@ -18,26 +18,10 @@
~OwnedSharedBitmap() override {}
- base::SharedMemory* memory() override { return shared_memory_.get(); }
-
private:
scoped_ptr<base::SharedMemory> shared_memory_;
};
-class UnownedSharedBitmap : public SharedBitmap {
- public:
- UnownedSharedBitmap(base::SharedMemory* shared_memory,
- const SharedBitmapId& id)
- : SharedBitmap(static_cast<uint8*>(shared_memory->memory()), id),
- shared_memory_(shared_memory) {}
-
- ~UnownedSharedBitmap() override {}
-
- base::SharedMemory* memory() override { return shared_memory_; }
-
- private:
- base::SharedMemory* shared_memory_;
-};
} // namespace
TestSharedBitmapManager::TestSharedBitmapManager() {}
@@ -60,15 +44,8 @@
base::AutoLock lock(lock_);
if (bitmap_map_.find(id) == bitmap_map_.end())
return nullptr;
- return make_scoped_ptr(new UnownedSharedBitmap(bitmap_map_[id], id));
-}
-
-scoped_ptr<SharedBitmap> TestSharedBitmapManager::GetBitmapForSharedMemory(
- base::SharedMemory* memory) {
- base::AutoLock lock(lock_);
- SharedBitmapId id = SharedBitmap::GenerateId();
- bitmap_map_[id] = memory;
- return make_scoped_ptr(new UnownedSharedBitmap(memory, id));
+ uint8* pixels = static_cast<uint8*>(bitmap_map_[id]->memory());
+ return make_scoped_ptr(new SharedBitmap(pixels, id));
}
} // namespace cc
diff --git a/cc/test/test_shared_bitmap_manager.h b/cc/test/test_shared_bitmap_manager.h
index 9163c79..acba096 100644
--- a/cc/test/test_shared_bitmap_manager.h
+++ b/cc/test/test_shared_bitmap_manager.h
@@ -10,6 +10,10 @@
#include "base/synchronization/lock.h"
#include "cc/resources/shared_bitmap_manager.h"
+namespace base {
+class SharedMemory;
+} // namespace base
+
namespace cc {
class TestSharedBitmapManager : public SharedBitmapManager {
@@ -23,9 +27,6 @@
const gfx::Size&,
const SharedBitmapId& id) override;
- scoped_ptr<SharedBitmap> GetBitmapForSharedMemory(
- base::SharedMemory* memory) override;
-
private:
base::Lock lock_;
std::map<SharedBitmapId, base::SharedMemory*> bitmap_map_;
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 4d03449..d192a9a 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -114,7 +114,6 @@
source_frame_number_(0),
rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
output_surface_lost_(true),
- num_failed_recreate_attempts_(0),
settings_(settings),
debug_state_(settings.initial_debug_state),
top_controls_shrink_blink_size_(false),
@@ -217,40 +216,6 @@
layer->OnOutputSurfaceCreated();
}
-void LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success) {
- DCHECK(output_surface_lost_);
- TRACE_EVENT1("cc",
- "LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted",
- "success",
- success);
-
- if (!success) {
- // Tolerate a certain number of recreation failures to work around races
- // in the output-surface-lost machinery.
- ++num_failed_recreate_attempts_;
- if (num_failed_recreate_attempts_ >= 5)
- LOG(FATAL) << "Failed to create a fallback OutputSurface.";
- client_->DidFailToInitializeOutputSurface();
- return;
- }
-
- output_surface_lost_ = false;
-
- if (!contents_texture_manager_ && !settings_.impl_side_painting) {
- contents_texture_manager_ =
- PrioritizedResourceManager::Create(proxy_.get());
- surface_memory_placeholder_ =
- contents_texture_manager_->CreateTexture(gfx::Size(), RGBA_8888);
- }
-
- if (root_layer()) {
- LayerTreeHostCommon::CallFunctionForSubtree(
- root_layer(), base::Bind(&LayerTreeHostOnOutputSurfaceCreatedCallback));
- }
-
- client_->DidInitializeOutputSurface();
-}
-
void LayerTreeHost::DeleteContentsTexturesOnImplThread(
ResourceProvider* resource_provider) {
DCHECK(proxy_->IsImplThread());
@@ -328,12 +293,6 @@
sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
root_layer(), sync_tree->DetachLayerTree(), sync_tree));
}
-
- {
- TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
- TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer());
- }
-
sync_tree->set_needs_full_tree_sync(needs_full_tree_sync_);
needs_full_tree_sync_ = false;
@@ -355,6 +314,7 @@
page_scale_layer_->id(), inner_viewport_scroll_layer_->id(),
outer_viewport_scroll_layer_.get() ? outer_viewport_scroll_layer_->id()
: Layer::INVALID_ID);
+ DCHECK(inner_viewport_scroll_layer_->IsContainerForFixedPositionLayers());
} else {
sync_tree->ClearViewportLayers();
}
@@ -415,6 +375,11 @@
sync_tree->set_has_ever_been_drawn(false);
+ {
+ TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
+ TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer());
+ }
+
micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl);
}
@@ -441,11 +406,38 @@
}
void LayerTreeHost::SetOutputSurface(scoped_ptr<OutputSurface> surface) {
+ TRACE_EVENT0("cc", "LayerTreeHost::SetOutputSurface");
+ DCHECK(output_surface_lost_);
+ DCHECK(surface);
+
proxy_->SetOutputSurface(surface.Pass());
}
void LayerTreeHost::RequestNewOutputSurface() {
- client_->RequestNewOutputSurface(num_failed_recreate_attempts_ >= 4);
+ client_->RequestNewOutputSurface();
+}
+
+void LayerTreeHost::DidInitializeOutputSurface() {
+ output_surface_lost_ = false;
+
+ if (!contents_texture_manager_ && !settings_.impl_side_painting) {
+ contents_texture_manager_ =
+ PrioritizedResourceManager::Create(proxy_.get());
+ surface_memory_placeholder_ =
+ contents_texture_manager_->CreateTexture(gfx::Size(), RGBA_8888);
+ }
+
+ if (root_layer()) {
+ LayerTreeHostCommon::CallFunctionForSubtree(
+ root_layer(), base::Bind(&LayerTreeHostOnOutputSurfaceCreatedCallback));
+ }
+
+ client_->DidInitializeOutputSurface();
+}
+
+void LayerTreeHost::DidFailToInitializeOutputSurface() {
+ DCHECK(output_surface_lost_);
+ client_->DidFailToInitializeOutputSurface();
}
scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl(
@@ -478,7 +470,6 @@
if (output_surface_lost_)
return;
- num_failed_recreate_attempts_ = 0;
output_surface_lost_ = true;
SetNeedsCommit();
}
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index 75165ad..e60f96e 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -125,11 +125,12 @@
void CommitComplete();
void SetOutputSurface(scoped_ptr<OutputSurface> output_surface);
void RequestNewOutputSurface();
+ void DidInitializeOutputSurface();
+ void DidFailToInitializeOutputSurface();
virtual scoped_ptr<LayerTreeHostImpl> CreateLayerTreeHostImpl(
LayerTreeHostImplClient* client);
void DidLoseOutputSurface();
bool output_surface_lost() const { return output_surface_lost_; }
- virtual void OnCreateAndInitializeOutputSurfaceAttempted(bool success);
void DidCommitAndDrawFrame() { client_->DidCommitAndDrawFrame(); }
void DidCompleteSwapBuffers() { client_->DidCompleteSwapBuffers(); }
void DeleteContentsTexturesOnImplThread(ResourceProvider* resource_provider);
@@ -402,7 +403,6 @@
scoped_ptr<RenderingStatsInstrumentation> rendering_stats_instrumentation_;
bool output_surface_lost_;
- int num_failed_recreate_attempts_;
scoped_refptr<Layer> root_layer_;
scoped_refptr<HeadsUpDisplayLayer> hud_layer_;
diff --git a/cc/trees/layer_tree_host_client.h b/cc/trees/layer_tree_host_client.h
index 5846343..a09693f 100644
--- a/cc/trees/layer_tree_host_client.h
+++ b/cc/trees/layer_tree_host_client.h
@@ -38,11 +38,12 @@
float page_scale,
float top_controls_delta) = 0;
// Request an OutputSurface from the client. When the client has one it should
- // call LayerTreeHost::SetOutputSurface. If fallback is true, it should
- // attempt to create an OutputSurface that is guaranteed to initialize
- // correctly.
- virtual void RequestNewOutputSurface(bool fallback) = 0;
+ // call LayerTreeHost::SetOutputSurface. This will result in either
+ // DidFailToInitializeOutputSurface or DidInitializeOutputSurface being
+ // called.
+ virtual void RequestNewOutputSurface() = 0;
virtual void DidInitializeOutputSurface() = 0;
+ virtual void DidFailToInitializeOutputSurface() = 0;
virtual void WillCommit() = 0;
virtual void DidCommit() = 0;
virtual void DidCommitAndDrawFrame() = 0;
@@ -58,9 +59,6 @@
// a TextureLayer that calls SetRateLimitContext(true).
virtual void RateLimitSharedMainThreadContext() {}
- // This hook is for testing.
- virtual void DidFailToInitializeOutputSurface() {}
-
protected:
virtual ~LayerTreeHostClient() {}
};
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index dd485ba..ea8a29f 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1589,11 +1589,13 @@
if (use_gpu == use_gpu_rasterization_)
return;
+ // Note that this must happen first, in case the rest of the calls want to
+ // query the new state of |use_gpu_rasterization_|.
use_gpu_rasterization_ = use_gpu;
- ReleaseTreeResources();
- // Replace existing tile manager with another one that uses appropriate
- // rasterizer.
+ // Clean up and replace existing tile manager with another one that uses
+ // appropriate rasterizer.
+ ReleaseTreeResources();
if (tile_manager_) {
DestroyTileManager();
CreateAndSetTileManager();
@@ -1964,8 +1966,7 @@
: settings_.scheduled_raster_task_limit;
tile_manager_ = TileManager::Create(
this, task_runner, resource_pool_.get(),
- tile_task_worker_pool_->AsTileTaskRunner(),
- rendering_stats_instrumentation_, scheduled_raster_task_limit);
+ tile_task_worker_pool_->AsTileTaskRunner(), scheduled_raster_task_limit);
UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy());
}
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 9049a84..61bda89 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -4181,6 +4181,7 @@
resource_id_,
gfx::RectF(0.f, 0.f, 1.f, 1.f),
gfx::Size(1, 1),
+ false,
false);
test_blending_draw_quad->visible_rect = quad_visible_rect_;
EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending());
@@ -7768,7 +7769,7 @@
TEST_F(LayerTreeHostImplTest, GetPictureLayerImplPairs) {
host_impl_->CreatePendingTree();
host_impl_->pending_tree()->SetRootLayer(
- PictureLayerImpl::Create(host_impl_->pending_tree(), 10));
+ PictureLayerImpl::Create(host_impl_->pending_tree(), 10, false));
LayerTreeImpl* pending_tree = host_impl_->pending_tree();
LayerImpl* pending_layer = pending_tree->root_layer();
@@ -7809,7 +7810,7 @@
// should get two pairs.
host_impl_->CreatePendingTree();
host_impl_->pending_tree()->root_layer()->AddChild(
- PictureLayerImpl::Create(host_impl_->pending_tree(), 11));
+ PictureLayerImpl::Create(host_impl_->pending_tree(), 11, false));
LayerImpl* new_pending_layer = pending_tree->root_layer()->children()[0];
diff --git a/cc/trees/layer_tree_host_pixeltest_blending.cc b/cc/trees/layer_tree_host_pixeltest_blending.cc
index 6b6b2af..b31d3e8 100644
--- a/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "cc/layers/image_layer.h"
+#include "cc/layers/picture_image_layer.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/test/layer_tree_pixel_resource_test.h"
#include "cc/test/pixel_comparator.h"
@@ -137,7 +137,7 @@
canvas.drawRect(
SkRect::MakeXYWH(0, i * kLaneHeight, kLaneWidth, kLaneHeight), paint);
}
- scoped_refptr<ImageLayer> layer = ImageLayer::Create();
+ scoped_refptr<PictureImageLayer> layer = PictureImageLayer::Create();
layer->SetIsDrawable(true);
layer->SetBounds(gfx::Size(width, height));
layer->SetBitmap(backing_store);
@@ -147,7 +147,7 @@
void SetupMaskLayer(scoped_refptr<Layer> layer) {
const int kMaskOffset = 2;
gfx::Size bounds = layer->bounds();
- scoped_refptr<ImageLayer> mask = ImageLayer::Create();
+ scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create();
mask->SetIsDrawable(true);
mask->SetIsMask(true);
mask->SetBounds(bounds);
@@ -237,7 +237,6 @@
CreateBlendingColorLayers(kLaneWidth, kLaneHeight, background.get(), flags);
- this->impl_side_painting_ = false;
this->force_antialiasing_ = (flags & kUseAntialiasing);
this->force_blending_with_shaders_ = (flags & kForceShaders);
@@ -437,6 +436,13 @@
}
TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersWithMask_GL_TextureRect) {
+ RunBlendingWithRenderPass(GL_ZERO_COPY_RECT_DRAW,
+ FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+ kUseMasks | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
BlendingWithRenderPassShadersWithMaskAA_GL) {
RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
FILE_PATH_LITERAL("blending_render_pass_mask.png"),
@@ -444,6 +450,13 @@
}
TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersWithMaskAA_GL_TextureRect) {
+ RunBlendingWithRenderPass(GL_ZERO_COPY_RECT_DRAW,
+ FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+ kUseMasks | kUseAntialiasing | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
BlendingWithRenderPassShadersColorMatrix_GL) {
RunBlendingWithRenderPass(GL_ASYNC_UPLOAD_2D_DRAW,
FILE_PATH_LITERAL("blending_render_pass.png"),
@@ -465,6 +478,13 @@
}
TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersWithMaskColorMatrix_GL_TextureRect) {
+ RunBlendingWithRenderPass(GL_ZERO_COPY_RECT_DRAW,
+ FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+ kUseMasks | kUseColorMatrix | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
BlendingWithRenderPassShadersWithMaskColorMatrixAA_GL) {
RunBlendingWithRenderPass(
GL_ASYNC_UPLOAD_2D_DRAW,
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 06c522a..eee6275 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -2090,7 +2090,6 @@
settings.max_partial_texture_updates = 10;
LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
- host.OnCreateAndInitializeOutputSurfaceAttempted(true);
EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
}
@@ -2108,7 +2107,6 @@
settings.max_partial_texture_updates = 10;
LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
- host.OnCreateAndInitializeOutputSurfaceAttempted(true);
EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
}
@@ -2126,7 +2124,6 @@
settings.max_partial_texture_updates = 10;
LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
- host.OnCreateAndInitializeOutputSurfaceAttempted(true);
EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
}
@@ -2688,8 +2685,7 @@
class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
protected:
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
- bool fallback) override {
+ scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
new MockIOSurfaceWebGraphicsContext3D);
mock_context_ = mock_context_owned.get();
@@ -2883,8 +2879,7 @@
PostSetNeedsCommitToMainThread();
}
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
- bool fallback) override {
+ scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
scoped_ptr<TestWebGraphicsContext3D> context3d(
TestWebGraphicsContext3D::Create());
@@ -4380,8 +4375,7 @@
settings->use_one_copy = false;
}
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
- bool fallback) override {
+ scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
scoped_refptr<TestContextProvider> context_provider =
TestContextProvider::Create();
context_provider->SetMaxTransferBufferUsageBytes(512 * 512);
@@ -4522,8 +4516,7 @@
: first_output_surface_memory_limit_(4321234),
second_output_surface_memory_limit_(1234321) {}
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
- bool fallback) override {
+ scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
if (!first_context_provider_.get()) {
first_context_provider_ = TestContextProvider::Create();
} else {
@@ -5108,7 +5101,7 @@
class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
protected:
void InitializeSettings(LayerTreeSettings* settings) override {
- settings->impl_side_painting = true;
+ ASSERT_TRUE(settings->impl_side_painting);
EXPECT_FALSE(settings->gpu_rasterization_forced);
settings->gpu_rasterization_forced = true;
@@ -5169,7 +5162,7 @@
FakeContentLayerClient layer_client_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationForced);
+SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestGpuRasterizationForced);
class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
public:
@@ -5714,8 +5707,7 @@
settings->use_one_copy = true;
}
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
- bool fallback) override {
+ scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
scoped_ptr<TestWebGraphicsContext3D> context3d =
TestWebGraphicsContext3D::Create();
context3d->set_support_image(true);
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index b646e6a..cc4f28f 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -17,6 +17,7 @@
#include "cc/layers/texture_layer_impl.h"
#include "cc/output/filter_operations.h"
#include "cc/resources/single_release_callback.h"
+#include "cc/test/failure_output_surface.h"
#include "cc/test/fake_content_layer.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_content_layer_impl.h"
@@ -74,12 +75,11 @@
return TestWebGraphicsContext3D::Create();
}
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
- bool fallback) override {
+ scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
if (times_to_fail_create_) {
--times_to_fail_create_;
ExpectCreateToFail();
- return nullptr;
+ return make_scoped_ptr(new FailureOutputSurface(delegating_renderer()));
}
scoped_ptr<TestWebGraphicsContext3D> context3d = CreateContext3d();
@@ -167,22 +167,22 @@
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
- void RequestNewOutputSurface(bool fallback) override {
+ void RequestNewOutputSurface() override {
if (async_output_surface_creation_) {
MainThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&LayerTreeHostContextTestLostContextSucceeds::
- CreateAndSetOutputSurface,
- base::Unretained(this),
- fallback));
+ FROM_HERE, base::Bind(&LayerTreeHostContextTestLostContextSucceeds::
+ CreateAndSetOutputSurface,
+ base::Unretained(this)));
} else {
- CreateAndSetOutputSurface(fallback);
+ CreateAndSetOutputSurface();
}
}
- void CreateAndSetOutputSurface(bool fallback) {
- layer_tree_host()->SetOutputSurface(
- LayerTreeHostContextTest::CreateOutputSurface(fallback));
+ void CreateAndSetOutputSurface() {
+ scoped_ptr<OutputSurface> surface(
+ LayerTreeHostContextTest::CreateOutputSurface());
+ CHECK(surface);
+ layer_tree_host()->SetOutputSurface(surface.Pass());
}
void DidInitializeOutputSurface() override {
@@ -357,7 +357,7 @@
EndTest();
}
- scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) override {
+ scoped_ptr<OutputSurface> CreateOutputSurface() override {
EXPECT_TRUE(false);
return nullptr;
}
@@ -380,7 +380,7 @@
settings->single_thread_proxy_scheduler = false;
}
- void RequestNewOutputSurface(bool fallback) override {
+ void RequestNewOutputSurface() override {
EXPECT_GE(1, ++request_count_);
EndTest();
}
@@ -390,7 +390,7 @@
layer_tree_host()->Composite(base::TimeTicks());
}
- scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) override {
+ scoped_ptr<OutputSurface> CreateOutputSurface() override {
EXPECT_TRUE(false);
return nullptr;
}
@@ -414,13 +414,12 @@
settings->single_thread_proxy_scheduler = false;
}
- void RequestNewOutputSurface(bool fallback) override {
+ void RequestNewOutputSurface() override {
if (request_count_ == 0) {
ExpectCreateToFail();
- layer_tree_host()->SetOutputSurface(nullptr);
+ layer_tree_host()->SetOutputSurface(
+ make_scoped_ptr(new FailureOutputSurface(false)));
}
- EXPECT_GE(2, ++request_count_);
- EndTest();
}
void BeginTest() override {
@@ -428,13 +427,14 @@
layer_tree_host()->Composite(base::TimeTicks());
}
- scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) override {
- EXPECT_TRUE(false);
- return nullptr;
- }
-
void DidInitializeOutputSurface() override { EXPECT_TRUE(false); }
+ void DidFailToInitializeOutputSurface() override {
+ LayerTreeHostContextTest::DidFailToInitializeOutputSurface();
+ EXPECT_GE(2, ++request_count_);
+ EndTest();
+ }
+
void AfterTest() override {}
int request_count_;
@@ -452,19 +452,18 @@
settings->single_thread_proxy_scheduler = false;
}
- void RequestNewOutputSurface(bool fallback) override {
+ void RequestNewOutputSurface() override {
MainThreadTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&LayerTreeHostContextTestCommitAfterDelayedOutputSurface::
CreateAndSetOutputSurface,
- base::Unretained(this),
- fallback));
+ base::Unretained(this)));
}
- void CreateAndSetOutputSurface(bool fallback) {
+ void CreateAndSetOutputSurface() {
creating_output_ = true;
layer_tree_host()->SetOutputSurface(
- LayerTreeHostContextTest::CreateOutputSurface(fallback));
+ LayerTreeHostContextTest::CreateOutputSurface());
}
void BeginTest() override { layer_tree_host()->Composite(base::TimeTicks()); }
@@ -492,9 +491,9 @@
settings->single_thread_proxy_scheduler = false;
}
- void RequestNewOutputSurface(bool fallback) override {
+ void RequestNewOutputSurface() override {
layer_tree_host()->SetOutputSurface(
- LayerTreeHostContextTest::CreateOutputSurface(fallback));
+ LayerTreeHostContextTest::CreateOutputSurface());
EndTest();
}
@@ -572,35 +571,16 @@
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostContextTestLostContextSucceedsWithContent);
-class LayerTreeHostContextTestCreateOutputSurfaceFails
+class LayerTreeHostContextTestCreateOutputSurfaceFailsOnce
: public LayerTreeHostContextTest {
public:
- // Run a test that initially fails OutputSurface creation |times_to_fail|
- // times. If |expect_fallback_attempt| is |true|, an attempt to create a
- // fallback/software OutputSurface is expected to occur.
- LayerTreeHostContextTestCreateOutputSurfaceFails(int times_to_fail,
- bool expect_fallback_attempt)
- : times_to_fail_(times_to_fail),
- expect_fallback_attempt_(expect_fallback_attempt),
- did_attempt_fallback_(false),
- times_initialized_(0) {
+ LayerTreeHostContextTestCreateOutputSurfaceFailsOnce()
+ : times_to_fail_(1), times_initialized_(0) {
times_to_fail_create_ = times_to_fail_;
}
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
- bool fallback) override {
- scoped_ptr<FakeOutputSurface> surface =
- LayerTreeHostContextTest::CreateFakeOutputSurface(fallback);
-
- if (surface)
- EXPECT_EQ(times_to_fail_, times_create_failed_);
-
- did_attempt_fallback_ = fallback;
- return surface.Pass();
- }
-
void DidInitializeOutputSurface() override { times_initialized_++; }
void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { EndTest(); }
@@ -608,38 +588,16 @@
void AfterTest() override {
EXPECT_EQ(times_to_fail_, times_create_failed_);
EXPECT_NE(0, times_initialized_);
- EXPECT_EQ(expect_fallback_attempt_, did_attempt_fallback_);
}
private:
int times_to_fail_;
- bool expect_fallback_attempt_;
- bool did_attempt_fallback_;
int times_initialized_;
};
-class LayerTreeHostContextTestCreateOutputSurfaceFailsOnce
- : public LayerTreeHostContextTestCreateOutputSurfaceFails {
- public:
- LayerTreeHostContextTestCreateOutputSurfaceFailsOnce()
- : LayerTreeHostContextTestCreateOutputSurfaceFails(1, false) {}
-};
-
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostContextTestCreateOutputSurfaceFailsOnce);
-// After 4 failures we expect an attempt to create a fallback/software
-// OutputSurface.
-class LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback
- : public LayerTreeHostContextTestCreateOutputSurfaceFails {
- public:
- LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback()
- : LayerTreeHostContextTestCreateOutputSurfaceFails(4, true) {}
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback);
-
class LayerTreeHostContextTestLostContextAndEvictTextures
: public LayerTreeHostContextTest {
public:
@@ -1118,15 +1076,14 @@
return draw_result;
}
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
- bool fallback) override {
+ scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
// This will get called twice:
// First when we create the initial output surface...
if (layer_tree_host()->source_frame_number() > 0) {
// ... and then again after we forced the context to be lost.
lost_context_ = true;
}
- return LayerTreeHostContextTest::CreateFakeOutputSurface(fallback);
+ return LayerTreeHostContextTest::CreateFakeOutputSurface();
}
void DidCommitAndDrawFrame() override {
diff --git a/cc/trees/layer_tree_host_unittest_copyrequest.cc b/cc/trees/layer_tree_host_unittest_copyrequest.cc
index 1b68cca..de20b6c 100644
--- a/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -103,8 +103,7 @@
void AfterTest() override { EXPECT_EQ(4u, callbacks_.size()); }
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
- bool fallback) override {
+ scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
if (use_gl_renderer_)
return FakeOutputSurface::Create3d();
return FakeOutputSurface::CreateSoftware(
@@ -534,8 +533,7 @@
class LayerTreeHostCopyRequestTestLostOutputSurface
: public LayerTreeHostCopyRequestTest {
protected:
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
- bool fallback) override {
+ scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
if (!first_context_provider_.get()) {
first_context_provider_ = TestContextProvider::Create();
return FakeOutputSurface::Create3d(first_context_provider_);
@@ -663,8 +661,7 @@
class LayerTreeHostCopyRequestTestCountTextures
: public LayerTreeHostCopyRequestTest {
protected:
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
- bool fallback) override {
+ scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
context_provider_ = TestContextProvider::Create();
return FakeOutputSurface::Create3d(context_provider_);
}
diff --git a/cc/trees/layer_tree_host_unittest_no_message_loop.cc b/cc/trees/layer_tree_host_unittest_no_message_loop.cc
index 1e04ad9..9e6611a 100644
--- a/cc/trees/layer_tree_host_unittest_no_message_loop.cc
+++ b/cc/trees/layer_tree_host_unittest_no_message_loop.cc
@@ -66,13 +66,14 @@
void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
float page_scale,
float top_controls_delta) override {}
- void RequestNewOutputSurface(bool fallback) override {
+ void RequestNewOutputSurface() override {
layer_tree_host_->SetOutputSurface(
make_scoped_ptr<OutputSurface>(new NoMessageLoopOutputSurface));
}
void DidInitializeOutputSurface() override {
did_initialize_output_surface_ = true;
}
+ void DidFailToInitializeOutputSurface() override {}
void WillCommit() override {}
void DidCommit() override { did_commit_ = true; }
void DidCommitAndDrawFrame() override { did_commit_and_draw_frame_ = true; }
diff --git a/cc/trees/layer_tree_host_unittest_picture.cc b/cc/trees/layer_tree_host_unittest_picture.cc
index 2d485b4..773798a 100644
--- a/cc/trees/layer_tree_host_unittest_picture.cc
+++ b/cc/trees/layer_tree_host_unittest_picture.cc
@@ -16,20 +16,25 @@
// These tests deal with picture layers.
class LayerTreeHostPictureTest : public LayerTreeTest {
protected:
- void InitializeSettings(LayerTreeSettings* settings) override {
- // PictureLayer can only be used with impl side painting enabled.
- settings->impl_side_painting = true;
+ void SetupTreeWithSinglePictureLayer(const gfx::Size& size) {
+ scoped_refptr<Layer> root = Layer::Create();
+ root->SetBounds(size);
+
+ root_picture_layer_ = FakePictureLayer::Create(&client_);
+ root_picture_layer_->SetBounds(size);
+ root->AddChild(root_picture_layer_);
+
+ layer_tree_host()->SetRootLayer(root);
}
+
+ scoped_refptr<FakePictureLayer> root_picture_layer_;
+ FakeContentLayerClient client_;
};
class LayerTreeHostPictureTestTwinLayer
: public LayerTreeHostPictureTest {
void SetupTree() override {
- LayerTreeHostPictureTest::SetupTree();
-
- scoped_refptr<FakePictureLayer> picture =
- FakePictureLayer::Create(&client_);
- layer_tree_host()->root_layer()->AddChild(picture);
+ SetupTreeWithSinglePictureLayer(gfx::Size(1, 1));
}
void BeginTest() override {
@@ -117,11 +122,200 @@
void AfterTest() override {}
- FakeContentLayerClient client_;
int activates_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostPictureTestTwinLayer);
+SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostPictureTestTwinLayer);
+
+class LayerTreeHostPictureTestResizeViewportWithGpuRaster
+ : public LayerTreeHostPictureTest {
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->gpu_rasterization_forced = true;
+ }
+
+ void SetupTree() override {
+ scoped_refptr<Layer> root = Layer::Create();
+ root->SetBounds(gfx::Size(768, 960));
+
+ client_.set_fill_with_nonsolid_color(true);
+ picture_ = FakePictureLayer::Create(&client_);
+ picture_->SetBounds(gfx::Size(768, 960));
+ root->AddChild(picture_);
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeHostPictureTest::SetupTree();
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
+ LayerImpl* child = impl->sync_tree()->root_layer()->children()[0];
+ FakePictureLayerImpl* picture_impl =
+ static_cast<FakePictureLayerImpl*>(child);
+ gfx::Size tile_size =
+ picture_impl->HighResTiling()->TileAt(0, 0)->content_rect().size();
+
+ switch (impl->sync_tree()->source_frame_number()) {
+ case 0:
+ tile_size_ = tile_size;
+ // GPU Raster picks a tile size based on the viewport size.
+ EXPECT_EQ(gfx::Size(768, 256), tile_size);
+ break;
+ case 1:
+ // When the viewport changed size, the new frame's tiles should change
+ // along with it.
+ EXPECT_NE(gfx::Size(768, 256), tile_size);
+ }
+ }
+
+ void DidCommit() override {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1:
+ // Change the picture layer's size along with the viewport, so it will
+ // consider picking a new tile size.
+ picture_->SetBounds(gfx::Size(768, 1056));
+ layer_tree_host()->SetViewportSize(gfx::Size(768, 1056));
+ break;
+ case 2:
+ EndTest();
+ }
+ }
+
+ void AfterTest() override {}
+
+ gfx::Size tile_size_;
+ FakeContentLayerClient client_;
+ scoped_refptr<FakePictureLayer> picture_;
+};
+
+SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
+ LayerTreeHostPictureTestResizeViewportWithGpuRaster);
+
+class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree
+ : public LayerTreeHostPictureTest {
+ void SetupTree() override {
+ frame_ = 0;
+ did_post_commit_ = false;
+
+ scoped_refptr<Layer> root = Layer::Create();
+ root->SetBounds(gfx::Size(100, 100));
+
+ // The layer is big enough that the live tiles rect won't cover the full
+ // layer.
+ client_.set_fill_with_nonsolid_color(true);
+ picture_ = FakePictureLayer::Create(&client_);
+ picture_->SetBounds(gfx::Size(100, 100000));
+ root->AddChild(picture_);
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeHostPictureTest::SetupTree();
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
+ LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
+ FakePictureLayerImpl* picture_impl =
+ static_cast<FakePictureLayerImpl*>(child);
+ FakePictureLayerImpl* recycled_impl = static_cast<FakePictureLayerImpl*>(
+ picture_impl->GetRecycledTwinLayer());
+
+ switch (++frame_) {
+ case 1: {
+ PictureLayerTiling* tiling = picture_impl->HighResTiling();
+ PictureLayerTiling* recycled_tiling = recycled_impl->HighResTiling();
+ int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y();
+
+ // There should be tiles at the top of the picture layer but not at the
+ // bottom.
+ EXPECT_TRUE(tiling->TileAt(0, 0));
+ EXPECT_FALSE(tiling->TileAt(0, num_tiles_y));
+
+ // The recycled tiling matches it.
+ EXPECT_TRUE(recycled_tiling->TileAt(0, 0));
+ EXPECT_FALSE(recycled_tiling->TileAt(0, num_tiles_y));
+
+ // The live tiles rect matches on the recycled tree.
+ EXPECT_EQ(tiling->live_tiles_rect(),
+ recycled_tiling->live_tiles_rect());
+
+ // Make the bottom of the layer visible.
+ picture_impl->SetPosition(gfx::PointF(0.f, -100000.f + 100.f));
+ impl->SetNeedsRedraw();
+ break;
+ }
+ case 2: {
+ PictureLayerTiling* tiling = picture_impl->HighResTiling();
+ PictureLayerTiling* recycled_tiling = recycled_impl->HighResTiling();
+
+ // There not be tiles at the top of the layer now.
+ EXPECT_FALSE(tiling->TileAt(0, 0));
+
+ // The recycled twin tiling should not have unshared tiles at the top
+ // either.
+ EXPECT_FALSE(recycled_tiling->TileAt(0, 0));
+
+ // The live tiles rect matches on the recycled tree.
+ EXPECT_EQ(tiling->live_tiles_rect(),
+ recycled_tiling->live_tiles_rect());
+
+ // Make the top of the layer visible again.
+ picture_impl->SetPosition(gfx::PointF());
+ impl->SetNeedsRedraw();
+ break;
+ }
+ case 3: {
+ PictureLayerTiling* tiling = picture_impl->HighResTiling();
+ PictureLayerTiling* recycled_tiling = recycled_impl->HighResTiling();
+ int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y();
+
+ // There should be tiles at the top of the picture layer again.
+ EXPECT_TRUE(tiling->TileAt(0, 0));
+ EXPECT_FALSE(tiling->TileAt(0, num_tiles_y));
+
+ // The recycled tiling should also have tiles at the top.
+ EXPECT_TRUE(recycled_tiling->TileAt(0, 0));
+ EXPECT_FALSE(recycled_tiling->TileAt(0, num_tiles_y));
+
+ // The live tiles rect matches on the recycled tree.
+ EXPECT_EQ(tiling->live_tiles_rect(),
+ recycled_tiling->live_tiles_rect());
+
+ // Make a new main frame without changing the picture layer at all, so
+ // it won't need to update or push properties.
+ did_post_commit_ = true;
+ PostSetNeedsCommitToMainThread();
+ break;
+ }
+ }
+ }
+
+ void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
+ LayerImpl* child = impl->sync_tree()->root_layer()->children()[0];
+ FakePictureLayerImpl* picture_impl =
+ static_cast<FakePictureLayerImpl*>(child);
+ PictureLayerTiling* tiling = picture_impl->HighResTiling();
+ int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y();
+
+ // The pending layer should always have tiles at the top of it each commit.
+ // The tile is part of the required for activation set so it should exist.
+ EXPECT_TRUE(tiling->TileAt(0, 0));
+ EXPECT_FALSE(tiling->TileAt(0, num_tiles_y));
+
+ if (did_post_commit_)
+ EndTest();
+ }
+
+ void AfterTest() override {}
+
+ int frame_;
+ bool did_post_commit_;
+ FakeContentLayerClient client_;
+ scoped_refptr<FakePictureLayer> picture_;
+};
+
+SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
+ LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree);
} // namespace
} // namespace cc
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
index b1248e0..6498f0e 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -129,8 +129,8 @@
output_surface_creation_requested_ = false;
renderer_capabilities_for_main_thread_ = RendererCapabilities();
- bool success = !!output_surface;
- if (success) {
+ bool success;
+ {
DebugScopedSetMainThreadBlocked main_thread_blocked(this);
DebugScopedSetImplThread impl(this);
layer_tree_host_->DeleteContentsTexturesOnImplThread(
@@ -138,15 +138,14 @@
success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
}
- layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success);
-
if (success) {
+ layer_tree_host_->DidInitializeOutputSurface();
if (scheduler_on_impl_thread_)
scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
else if (!inside_synchronous_composite_)
SetNeedsCommit();
- } else if (Proxy::MainThreadTaskRunner()) {
- ScheduleRequestNewOutputSurface();
+ } else {
+ layer_tree_host_->DidFailToInitializeOutputSurface();
}
}
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index e6ab017..73bf79e 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -215,16 +215,10 @@
}
void ThreadProxy::SetOutputSurface(scoped_ptr<OutputSurface> output_surface) {
- if (output_surface) {
- Proxy::ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread,
- impl_thread_weak_ptr_,
- base::Passed(&output_surface)));
- return;
- }
-
- DidInitializeOutputSurface(false, RendererCapabilities());
+ Proxy::ImplThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread,
+ impl_thread_weak_ptr_, base::Passed(&output_surface)));
}
void ThreadProxy::DidInitializeOutputSurface(
@@ -232,15 +226,13 @@
const RendererCapabilities& capabilities) {
TRACE_EVENT0("cc", "ThreadProxy::DidInitializeOutputSurface");
DCHECK(IsMainThread());
- main().renderer_capabilities_main_thread_copy = capabilities;
- layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(success);
if (!success) {
- Proxy::MainThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ThreadProxy::RequestNewOutputSurface,
- main_thread_weak_ptr_));
+ layer_tree_host()->DidFailToInitializeOutputSurface();
+ return;
}
+ main().renderer_capabilities_main_thread_copy = capabilities;
+ layer_tree_host()->DidInitializeOutputSurface();
}
void ThreadProxy::SetRendererCapabilitiesMainThreadCopy(
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h
index d35de42..5a506df 100644
--- a/gpu/GLES2/gl2chromium_autogen.h
+++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -19,7 +19,9 @@
#define glBindBuffer GLES2_GET_FUN(BindBuffer)
#define glBindFramebuffer GLES2_GET_FUN(BindFramebuffer)
#define glBindRenderbuffer GLES2_GET_FUN(BindRenderbuffer)
+#define glBindSampler GLES2_GET_FUN(BindSampler)
#define glBindTexture GLES2_GET_FUN(BindTexture)
+#define glBindTransformFeedback GLES2_GET_FUN(BindTransformFeedback)
#define glBlendColor GLES2_GET_FUN(BlendColor)
#define glBlendEquation GLES2_GET_FUN(BlendEquation)
#define glBlendEquationSeparate GLES2_GET_FUN(BlendEquationSeparate)
@@ -46,8 +48,10 @@
#define glDeleteFramebuffers GLES2_GET_FUN(DeleteFramebuffers)
#define glDeleteProgram GLES2_GET_FUN(DeleteProgram)
#define glDeleteRenderbuffers GLES2_GET_FUN(DeleteRenderbuffers)
+#define glDeleteSamplers GLES2_GET_FUN(DeleteSamplers)
#define glDeleteShader GLES2_GET_FUN(DeleteShader)
#define glDeleteTextures GLES2_GET_FUN(DeleteTextures)
+#define glDeleteTransformFeedbacks GLES2_GET_FUN(DeleteTransformFeedbacks)
#define glDepthFunc GLES2_GET_FUN(DepthFunc)
#define glDepthMask GLES2_GET_FUN(DepthMask)
#define glDepthRangef GLES2_GET_FUN(DepthRangef)
@@ -68,7 +72,9 @@
#define glGenerateMipmap GLES2_GET_FUN(GenerateMipmap)
#define glGenFramebuffers GLES2_GET_FUN(GenFramebuffers)
#define glGenRenderbuffers GLES2_GET_FUN(GenRenderbuffers)
+#define glGenSamplers GLES2_GET_FUN(GenSamplers)
#define glGenTextures GLES2_GET_FUN(GenTextures)
+#define glGenTransformFeedbacks GLES2_GET_FUN(GenTransformFeedbacks)
#define glGetActiveAttrib GLES2_GET_FUN(GetActiveAttrib)
#define glGetActiveUniform GLES2_GET_FUN(GetActiveUniform)
#define glGetAttachedShaders GLES2_GET_FUN(GetAttachedShaders)
@@ -84,6 +90,8 @@
#define glGetProgramiv GLES2_GET_FUN(GetProgramiv)
#define glGetProgramInfoLog GLES2_GET_FUN(GetProgramInfoLog)
#define glGetRenderbufferParameteriv GLES2_GET_FUN(GetRenderbufferParameteriv)
+#define glGetSamplerParameterfv GLES2_GET_FUN(GetSamplerParameterfv)
+#define glGetSamplerParameteriv GLES2_GET_FUN(GetSamplerParameteriv)
#define glGetShaderiv GLES2_GET_FUN(GetShaderiv)
#define glGetShaderInfoLog GLES2_GET_FUN(GetShaderInfoLog)
#define glGetShaderPrecisionFormat GLES2_GET_FUN(GetShaderPrecisionFormat)
@@ -105,17 +113,25 @@
#define glIsFramebuffer GLES2_GET_FUN(IsFramebuffer)
#define glIsProgram GLES2_GET_FUN(IsProgram)
#define glIsRenderbuffer GLES2_GET_FUN(IsRenderbuffer)
+#define glIsSampler GLES2_GET_FUN(IsSampler)
#define glIsShader GLES2_GET_FUN(IsShader)
#define glIsTexture GLES2_GET_FUN(IsTexture)
+#define glIsTransformFeedback GLES2_GET_FUN(IsTransformFeedback)
#define glLineWidth GLES2_GET_FUN(LineWidth)
#define glLinkProgram GLES2_GET_FUN(LinkProgram)
+#define glPauseTransformFeedback GLES2_GET_FUN(PauseTransformFeedback)
#define glPixelStorei GLES2_GET_FUN(PixelStorei)
#define glPolygonOffset GLES2_GET_FUN(PolygonOffset)
#define glReadBuffer GLES2_GET_FUN(ReadBuffer)
#define glReadPixels GLES2_GET_FUN(ReadPixels)
#define glReleaseShaderCompiler GLES2_GET_FUN(ReleaseShaderCompiler)
#define glRenderbufferStorage GLES2_GET_FUN(RenderbufferStorage)
+#define glResumeTransformFeedback GLES2_GET_FUN(ResumeTransformFeedback)
#define glSampleCoverage GLES2_GET_FUN(SampleCoverage)
+#define glSamplerParameterf GLES2_GET_FUN(SamplerParameterf)
+#define glSamplerParameterfv GLES2_GET_FUN(SamplerParameterfv)
+#define glSamplerParameteri GLES2_GET_FUN(SamplerParameteri)
+#define glSamplerParameteriv GLES2_GET_FUN(SamplerParameteriv)
#define glScissor GLES2_GET_FUN(Scissor)
#define glShaderBinary GLES2_GET_FUN(ShaderBinary)
#define glShaderSource GLES2_GET_FUN(ShaderSource)
@@ -196,7 +212,9 @@
#define glDeleteQueriesEXT GLES2_GET_FUN(DeleteQueriesEXT)
#define glIsQueryEXT GLES2_GET_FUN(IsQueryEXT)
#define glBeginQueryEXT GLES2_GET_FUN(BeginQueryEXT)
+#define glBeginTransformFeedback GLES2_GET_FUN(BeginTransformFeedback)
#define glEndQueryEXT GLES2_GET_FUN(EndQueryEXT)
+#define glEndTransformFeedback GLES2_GET_FUN(EndTransformFeedback)
#define glGetQueryivEXT GLES2_GET_FUN(GetQueryivEXT)
#define glGetQueryObjectuivEXT GLES2_GET_FUN(GetQueryObjectuivEXT)
#define glInsertEventMarkerEXT GLES2_GET_FUN(InsertEventMarkerEXT)
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 0b86db6..418612a 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -10,6 +10,7 @@
import os.path
import sys
import re
+import platform
from optparse import OptionParser
from subprocess import call
@@ -709,6 +710,26 @@
'GL_TEXTURE_3D',
],
},
+ 'TransformFeedbackBindTarget': {
+ 'type': 'GLenum',
+ 'valid': [
+ 'GL_TRANSFORM_FEEDBACK',
+ ],
+ 'invalid': [
+ 'GL_TEXTURE_2D',
+ ],
+ },
+ 'TransformFeedbackPrimitiveMode': {
+ 'type': 'GLenum',
+ 'valid': [
+ 'GL_POINTS',
+ 'GL_LINES',
+ 'GL_TRIANGLES',
+ ],
+ 'invalid': [
+ 'GL_LINE_LOOP',
+ ],
+ },
'ShaderType': {
'type': 'GLenum',
'valid': [
@@ -939,6 +960,23 @@
'GL_RENDERBUFFER_INTERNAL_FORMAT',
],
},
+ 'SamplerParameter': {
+ 'type': 'GLenum',
+ 'valid': [
+ 'GL_TEXTURE_MAG_FILTER',
+ 'GL_TEXTURE_MIN_FILTER',
+ 'GL_TEXTURE_MIN_LOD',
+ 'GL_TEXTURE_MAX_LOD',
+ 'GL_TEXTURE_WRAP_S',
+ 'GL_TEXTURE_WRAP_T',
+ 'GL_TEXTURE_WRAP_R',
+ 'GL_TEXTURE_COMPARE_MODE',
+ 'GL_TEXTURE_COMPARE_FUNC',
+ ],
+ 'invalid': [
+ 'GL_GENERATE_MIPMAP',
+ ],
+ },
'ShaderParameter': {
'type': 'GLenum',
'valid': [
@@ -1327,7 +1365,7 @@
# command.
# impl_decl: Whether or not to generate the GLES2Implementation declaration
# for this command.
-# needs_size: If true a data_size field is added to the command.
+# needs_size: If True a data_size field is added to the command.
# count: The number of units per element. For PUTn or PUT types.
# unit_test: If False no service side unit test will be generated.
# client_test: If False no client side unit test will be generated.
@@ -1359,6 +1397,8 @@
# not_shared: For GENn types, True if objects can't be shared between contexts
# unsafe: True = no validation is implemented on the service side and the
# command is only available with --enable-unsafe-es3-apis.
+# id_mapping: A list of resource type names whose client side IDs need to be
+# mapped to service side IDs. This is only used for unsafe APIs.
_FUNCTION_INFO = {
'ActiveTexture': {
@@ -1391,6 +1431,11 @@
'gl_test_func': 'glBindRenderbufferEXT',
'gen_func': 'GenRenderbuffersEXT',
},
+ 'BindSampler': {
+ 'type': 'Bind',
+ 'id_mapping': [ 'Sampler' ],
+ 'unsafe': True,
+ },
'BindTexture': {
'type': 'Bind',
'decoder_func': 'DoBindTexture',
@@ -1399,6 +1444,11 @@
'client_test': False,
'trace_level': 1,
},
+ 'BindTransformFeedback': {
+ 'type': 'Bind',
+ 'id_mapping': [ 'TransformFeedback' ],
+ 'unsafe': True,
+ },
'BlitFramebufferCHROMIUM': {
'decoder_func': 'DoBlitFramebufferCHROMIUM',
'unit_test': False,
@@ -1690,12 +1740,24 @@
'resource_type': 'Renderbuffer',
'resource_types': 'Renderbuffers',
},
+ 'DeleteSamplers': {
+ 'type': 'DELn',
+ 'resource_type': 'Sampler',
+ 'resource_types': 'Samplers',
+ 'unsafe': True,
+ },
'DeleteShader': {'type': 'Delete', 'decoder_func': 'DoDeleteShader'},
'DeleteTextures': {
'type': 'DELn',
'resource_type': 'Texture',
'resource_types': 'Textures',
},
+ 'DeleteTransformFeedbacks': {
+ 'type': 'DELn',
+ 'resource_type': 'TransformFeedback',
+ 'resource_types': 'TransformFeedbacks',
+ 'unsafe': True,
+ },
'DepthRangef': {
'decoder_func': 'DoDepthRangef',
'gl_test_func': 'glDepthRange',
@@ -1797,12 +1859,26 @@
'resource_type': 'Renderbuffer',
'resource_types': 'Renderbuffers',
},
+ 'GenSamplers': {
+ 'type': 'GENn',
+ 'gl_test_func': 'glGenSamplers',
+ 'resource_type': 'Sampler',
+ 'resource_types': 'Samplers',
+ 'unsafe': True,
+ },
'GenTextures': {
'type': 'GENn',
'gl_test_func': 'glGenTextures',
'resource_type': 'Texture',
'resource_types': 'Textures',
},
+ 'GenTransformFeedbacks': {
+ 'type': 'GENn',
+ 'gl_test_func': 'glGenTransformFeedbacks',
+ 'resource_type': 'TransformFeedback',
+ 'resource_types': 'TransformFeedbacks',
+ 'unsafe': True,
+ },
'GetActiveAttrib': {
'type': 'Custom',
'data_transfer_methods': ['shm'],
@@ -1924,6 +2000,18 @@
'gl_test_func': 'glGetRenderbufferParameterivEXT',
'result': ['SizedResult<GLint>'],
},
+ 'GetSamplerParameterfv': {
+ 'type': 'GETn',
+ 'result': ['SizedResult<GLfloat>'],
+ 'id_mapping': [ 'Sampler' ],
+ 'unsafe': True,
+ },
+ 'GetSamplerParameteriv': {
+ 'type': 'GETn',
+ 'result': ['SizedResult<GLint>'],
+ 'id_mapping': [ 'Sampler' ],
+ 'unsafe': True,
+ },
'GetShaderiv': {
'type': 'GETn',
'decoder_func': 'DoGetShaderiv',
@@ -2062,11 +2150,21 @@
'decoder_func': 'DoIsShader',
'expectation': False,
},
+ 'IsSampler': {
+ 'type': 'Is',
+ 'id_mapping': [ 'Sampler' ],
+ 'unsafe': True,
+ },
'IsTexture': {
'type': 'Is',
'decoder_func': 'DoIsTexture',
'expectation': False,
},
+ 'IsTransformFeedback': {
+ 'type': 'Is',
+ 'id_mapping': [ 'TransformFeedback' ],
+ 'unsafe': True,
+ },
'LinkProgram': {
'decoder_func': 'DoLinkProgram',
'impl_func': False,
@@ -2091,6 +2189,9 @@
'client_test': False,
'pepper_interface': 'ChromiumMapSub',
},
+ 'PauseTransformFeedback': {
+ 'unsafe': True,
+ },
'PixelStorei': {'type': 'Manual'},
'PostSubBufferCHROMIUM': {
'type': 'Custom',
@@ -2172,6 +2273,42 @@
'decoder_func': 'DoReleaseShaderCompiler',
'unit_test': False,
},
+ 'ResumeTransformFeedback': {
+ 'unsafe': True,
+ },
+ 'SamplerParameterf': {
+ 'valid_args': {
+ '2': 'GL_NEAREST'
+ },
+ 'id_mapping': [ 'Sampler' ],
+ 'unsafe': True,
+ },
+ 'SamplerParameterfv': {
+ 'type': 'PUT',
+ 'data_value': 'GL_NEAREST',
+ 'count': 1,
+ 'gl_test_func': 'glSamplerParameterf',
+ 'decoder_func': 'DoSamplerParameterfv',
+ 'first_element_only': True,
+ 'id_mapping': [ 'Sampler' ],
+ 'unsafe': True,
+ },
+ 'SamplerParameteri': {
+ 'valid_args': {
+ '2': 'GL_NEAREST'
+ },
+ 'id_mapping': [ 'Sampler' ],
+ 'unsafe': True,
+ },
+ 'SamplerParameteriv': {
+ 'type': 'PUT',
+ 'data_value': 'GL_NEAREST',
+ 'count': 1,
+ 'gl_test_func': 'glSamplerParameteri',
+ 'decoder_func': 'DoSamplerParameteriv',
+ 'first_element_only': True,
+ 'unsafe': True,
+ },
'ShaderBinary': {
'type': 'Custom',
'client_test': False,
@@ -2599,6 +2736,9 @@
'gl_test_func': 'glBeginQuery',
'pepper_interface': 'Query',
},
+ 'BeginTransformFeedback': {
+ 'unsafe': True,
+ },
'EndQueryEXT': {
'type': 'Manual',
'cmd_args': 'GLenumQueryTarget target, GLuint submit_count',
@@ -2606,6 +2746,9 @@
'client_test': False,
'pepper_interface': 'Query',
},
+ 'EndTransformFeedback': {
+ 'unsafe': True,
+ },
'GetQueryivEXT': {
'gen_cmd': False,
'client_test': False,
@@ -3061,6 +3204,10 @@
def WriteHandlerImplementation(self, func, file):
"""Writes the handler implementation for this command."""
+ if func.IsUnsafe() and func.GetInfo('id_mapping'):
+ for id_type in func.GetInfo('id_mapping'):
+ file.Write(" group_->Get%sServiceId(%s, &%s);\n" %
+ (id_type, id_type.lower(), id_type.lower()))
file.Write(" %s(%s);\n" %
(func.GetGLFunctionName(), func.MakeOriginalArgString("")))
@@ -3110,6 +3257,10 @@
def WriteImmediateHandlerImplementation (self, func, file):
"""Writes the handler impl for the immediate version of a command."""
+ if func.IsUnsafe() and func.GetInfo('id_mapping'):
+ for id_type in func.GetInfo('id_mapping'):
+ file.Write(" group_->Get%sServiceId(%s, &%s);\n" %
+ (id_type, id_type.lower(), id_type.lower()))
file.Write(" %s(%s);\n" %
(func.GetGLFunctionName(), func.MakeOriginalArgString("")))
@@ -3233,6 +3384,8 @@
def WriteInvalidUnitTest(self, func, file, test, *extras):
"""Writes an invalid unit test for the service implementation."""
+ if func.IsUnsafe():
+ return
for invalid_arg_index, invalid_arg in enumerate(func.GetOriginalArgs()):
# Service implementation does not test constants, as they are not part of
# the call in the service side.
@@ -3270,7 +3423,7 @@
'all_but_last_args': ", ".join(arg_strings[:-1]),
'gl_args': ", ".join(gl_arg_strings),
'parse_result': parse_result,
- 'gl_error_test': gl_error_test,
+ 'gl_error_test': gl_error_test,
}
for extra in extras:
vars.update(extra)
@@ -4154,7 +4307,18 @@
EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
SpecializedSetup<cmds::%(name)s, 0>(true);
cmds::%(name)s cmd;
- cmd.Init(%(args)s);
+ cmd.Init(%(args)s);"""
+ if func.IsUnsafe():
+ valid_test += """
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+"""
+ else:
+ valid_test += """
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
@@ -4183,7 +4347,18 @@
EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
SpecializedSetup<cmds::%(name)s, 0>(true);
cmds::%(name)s cmd;
- cmd.Init(%(args)s);
+ cmd.Init(%(args)s);"""
+ if func.IsUnsafe():
+ valid_test += """
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+"""
+ else:
+ valid_test += """
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
@@ -4239,7 +4414,14 @@
for arg in func.GetOriginalArgs():
arg.WriteClientSideValidationCode(file, func)
- code = """ if (Is%(type)sReservedId(%(id)s)) {
+ if func.IsUnsafe():
+ code = """ helper_->%(name)s(%(arg_string)s);
+ CheckGLError();
+}
+
+"""
+ else:
+ code = """ if (Is%(type)sReservedId(%(id)s)) {
SetGLError(GL_INVALID_OPERATION, "%(name)s\", \"%(id)s reserved id");
return;
}
@@ -4278,10 +4460,13 @@
expected.cmd.Init(%(cmd_args)s);
gl_->%(name)s(%(args)s);
- EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));"""
+ if not func.IsUnsafe():
+ code += """
ClearCommands();
gl_->%(name)s(%(args)s);
- EXPECT_TRUE(NoCommandsWritten());
+ EXPECT_TRUE(NoCommandsWritten());"""
+ code += """
}
"""
cmd_arg_strings = [
@@ -4326,10 +4511,25 @@
def WriteImmediateHandlerImplementation(self, func, file):
"""Overrriden from TypeHandler."""
- file.Write(" if (!%sHelper(n, %s)) {\n"
- " return error::kInvalidArguments;\n"
- " }\n" %
- (func.original_name, func.GetLastOriginalArg().name))
+ if func.IsUnsafe():
+ file.Write(""" for (GLsizei ii = 0; ii < n; ++ii) {
+ if (group_->Get%(resource_name)sServiceId(%(last_arg_name)s[ii], NULL)) {
+ return error::kInvalidArguments;
+ }
+ }
+ scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
+ gl%(func_name)s(n, service_ids.get());
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ group_->Add%(resource_name)sId(%(last_arg_name)s[ii], service_ids[ii]);
+ }
+""" % { 'func_name': func.original_name,
+ 'last_arg_name': func.GetLastOriginalArg().name,
+ 'resource_name': func.GetInfo('resource_type') })
+ else:
+ file.Write(" if (!%sHelper(n, %s)) {\n"
+ " return error::kInvalidArguments;\n"
+ " }\n" %
+ (func.original_name, func.GetLastOriginalArg().name))
def WriteGLES2Implementation(self, func, file):
"""Overrriden from TypeHandler."""
@@ -4415,8 +4615,17 @@
cmds::%(name)s cmd;
cmd.Init(%(args)s);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_TRUE(Get%(resource_name)s(kNewClientId) != NULL);
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());"""
+ if func.IsUnsafe():
+ valid_test += """
+ GLuint service_id;
+ EXPECT_TRUE(Get%(resource_name)sServiceId(kNewClientId, &service_id));
+ EXPECT_EQ(kNewServiceId, service_id)
+}
+"""
+ else:
+ valid_test += """
+ EXPECT_TRUE(Get%(resource_name)s(kNewClientId, &service_id) != NULL);
}
"""
self.WriteValidUnitTest(func, file, valid_test, {
@@ -4444,11 +4653,27 @@
.WillOnce(SetArgumentPointee<1>(kNewServiceId));
cmds::%(name)s* cmd = GetImmediateAs<cmds::%(name)s>();
GLuint temp = kNewClientId;
- SpecializedSetup<cmds::%(name)s, 0>(true);
+ SpecializedSetup<cmds::%(name)s, 0>(true);"""
+ if func.IsUnsafe():
+ valid_test += """
+ decoder_->set_unsafe_es3_apis_enabled(true);"""
+ valid_test += """
cmd->Init(1, &temp);
EXPECT_EQ(error::kNoError,
ExecuteImmediateCmd(*cmd, sizeof(temp)));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());"""
+ if func.IsUnsafe():
+ valid_test += """
+ GLuint service_id;
+ EXPECT_TRUE(Get%(resource_name)sServiceId(kNewClientId, &service_id));
+ EXPECT_EQ(kNewServiceId, service_id);
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand,
+ ExecuteImmediateCmd(*cmd, sizeof(temp)));
+}
+"""
+ else:
+ valid_test += """
EXPECT_TRUE(Get%(resource_name)s(kNewClientId) != NULL);
}
"""
@@ -4460,7 +4685,17 @@
EXPECT_CALL(*gl_, %(gl_func_name)s(_, _)).Times(0);
cmds::%(name)s* cmd = GetImmediateAs<cmds::%(name)s>();
SpecializedSetup<cmds::%(name)s, 0>(false);
- cmd->Init(1, &client_%(resource_name)s_id_);
+ cmd->Init(1, &client_%(resource_name)s_id_);"""
+ if func.IsUnsafe():
+ invalid_test += """
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kInvalidArguments,
+ ExecuteImmediateCmd(*cmd, sizeof(&client_%(resource_name)s_id_)));
+ decoder_->set_unsafe_es3_apis_enabled(false);
+}
+"""
+ else:
+ invalid_test += """
EXPECT_EQ(error::kInvalidArguments,
ExecuteImmediateCmd(*cmd, sizeof(&client_%(resource_name)s_id_)));
}
@@ -4744,10 +4979,25 @@
.Times(1);
cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
SpecializedSetup<cmds::%(name)s, 0>(true);
- cmd.Init(1, &client_%(resource_name)s_id_);
+ cmd.Init(1, &client_%(resource_name)s_id_);"""
+ if func.IsUnsafe():
+ valid_test += """
+ decoder_->set_unsafe_es3_apis_enabled(true);"""
+ valid_test += """
EXPECT_EQ(error::kNoError,
ExecuteImmediateCmd(cmd, sizeof(client_%(resource_name)s_id_)));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());"""
+ if func.IsUnsafe():
+ valid_test += """
+ EXPECT_FALSE(Get%(upper_resource_name)sServiceId(
+ client_%(resource_name)s_id_, NULL));
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand,
+ ExecuteImmediateCmd(cmd, sizeof(client_%(resource_name)s_id_)));
+}
+"""
+ else:
+ valid_test += """
EXPECT_TRUE(
Get%(upper_resource_name)s(client_%(resource_name)s_id_) == NULL);
}
@@ -4761,7 +5011,19 @@
cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
SpecializedSetup<cmds::%(name)s, 0>(false);
GLuint temp = kInvalidClientId;
- cmd.Init(1, &temp);
+ cmd.Init(1, &temp);"""
+ if func.IsUnsafe():
+ invalid_test += """
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError,
+ ExecuteImmediateCmd(cmd, sizeof(temp)));
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand,
+ ExecuteImmediateCmd(cmd, sizeof(temp)));
+}
+"""
+ else:
+ invalid_test += """
EXPECT_EQ(error::kNoError,
ExecuteImmediateCmd(cmd, sizeof(temp)));
}
@@ -4775,8 +5037,20 @@
def WriteImmediateHandlerImplementation (self, func, file):
"""Overrriden from TypeHandler."""
- file.Write(" %sHelper(n, %s);\n" %
- (func.original_name, func.GetLastOriginalArg().name))
+ if func.IsUnsafe():
+ file.Write(""" for (GLsizei ii = 0; ii < n; ++ii) {
+ GLuint service_id = 0;
+ if (group_->Get%(resource_type)sServiceId(
+ %(last_arg_name)s[ii], &service_id)) {
+ glDelete%(resource_type)ss(1, &service_id);
+ group_->Remove%(resource_type)sId(%(last_arg_name)s[ii]);
+ }
+ }
+""" % { 'resource_type': func.GetInfo('resource_type'),
+ 'last_arg_name': func.GetLastOriginalArg().name })
+ else:
+ file.Write(" %sHelper(n, %s);\n" %
+ (func.original_name, func.GetLastOriginalArg().name))
def WriteGLES2Implementation(self, func, file):
"""Overrriden from TypeHandler."""
@@ -5230,13 +5504,32 @@
invalid_test = """
TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
- cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
+ cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();"""
+ if func.IsUnsafe():
+ invalid_test += """
+ EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_any_args)s, _)).Times(1);
+"""
+ else:
+ invalid_test += """
EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_any_args)s, _)).Times(0);
+"""
+ invalid_test += """
SpecializedSetup<cmds::%(name)s, 0>(false);
%(data_type)s temp[%(data_count)s] = { %(data_value)s, };
- cmd.Init(%(all_but_last_args)s, &temp[0]);
+ cmd.Init(%(all_but_last_args)s, &temp[0]);"""
+ if func.IsUnsafe():
+ invalid_test += """
+ decoder_->set_unsafe_es3_apis_enabled(true);
EXPECT_EQ(error::%(parse_result)s,
- ExecuteImmediateCmd(cmd, sizeof(temp)));%(gl_error_test)s
+ ExecuteImmediateCmd(cmd, sizeof(temp)));
+ decoder_->set_unsafe_es3_apis_enabled(false);
+}
+"""
+ else:
+ invalid_test += """
+ EXPECT_EQ(error::%(parse_result)s,
+ ExecuteImmediateCmd(cmd, sizeof(temp)));
+ %(gl_error_test)s
}
"""
self.WriteInvalidUnitTest(func, file, invalid_test, extra, *extras)
@@ -6026,9 +6319,18 @@
EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
SpecializedSetup<cmds::%(name)s, 0>(true);
cmds::%(name)s cmd;
- cmd.Init(%(args)s%(comma)sshared_memory_id_, shared_memory_offset_);
+ cmd.Init(%(args)s%(comma)sshared_memory_id_, shared_memory_offset_);"""
+ if func.IsUnsafe():
+ valid_test += """
+ decoder_->set_unsafe_es3_apis_enabled(true);"""
+ valid_test += """
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());"""
+ if func.IsUnsafe():
+ valid_test += """
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));"""
+ valid_test += """
}
"""
comma = ""
@@ -6054,12 +6356,20 @@
invalid_test = """
TEST_P(%(test_name)s, %(name)sInvalidArgsBadSharedMemoryId) {
EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
- SpecializedSetup<cmds::%(name)s, 0>(false);
+ SpecializedSetup<cmds::%(name)s, 0>(false);"""
+ if func.IsUnsafe():
+ invalid_test += """
+ decoder_->set_unsafe_es3_apis_enabled(true);"""
+ invalid_test += """
cmds::%(name)s cmd;
cmd.Init(%(args)s%(comma)skInvalidSharedMemoryId, shared_memory_offset_);
EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
cmd.Init(%(args)s%(comma)sshared_memory_id_, kInvalidSharedMemoryOffset);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));"""
+ if func.IsUnsafe():
+ invalid_test += """
+ decoder_->set_unsafe_es3_apis_enabled(true);"""
+ invalid_test += """
}
"""
self.WriteValidUnitTest(func, file, invalid_test, {
@@ -6082,6 +6392,10 @@
"""
file.Write(code % {'func_name': func.name})
func.WriteHandlerValidation(file)
+ if func.IsUnsafe() and func.GetInfo('id_mapping'):
+ for id_type in func.GetInfo('id_mapping'):
+ file.Write(" group_->Get%sServiceId(%s, &%s);\n" %
+ (id_type, id_type.lower(), id_type.lower()))
file.Write(" *result_dst = %s(%s);\n" %
(func.GetGLFunctionName(), func.MakeOriginalArgString("")))
file.Write(" return error::kNoError;\n")
@@ -8803,8 +9117,11 @@
self.generated_cpp_filenames.append(file.filename)
def Format(generated_files):
+ formatter = "clang-format"
+ if platform.system() == "Windows":
+ formatter += ".bat"
for filename in generated_files:
- call(["clang-format", "-i", "-style=chromium", filename])
+ call([formatter, "-i", "-style=chromium", filename])
def main(argv):
"""This is the main function."""
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index 766ce56..bd41c8f 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -30,9 +30,15 @@
void GLES2BindRenderbuffer(GLenum target, GLuint renderbuffer) {
gles2::GetGLContext()->BindRenderbuffer(target, renderbuffer);
}
+void GLES2BindSampler(GLuint unit, GLuint sampler) {
+ gles2::GetGLContext()->BindSampler(unit, sampler);
+}
void GLES2BindTexture(GLenum target, GLuint texture) {
gles2::GetGLContext()->BindTexture(target, texture);
}
+void GLES2BindTransformFeedback(GLenum target, GLuint transformfeedback) {
+ gles2::GetGLContext()->BindTransformFeedback(target, transformfeedback);
+}
void GLES2BlendColor(GLclampf red,
GLclampf green,
GLclampf blue,
@@ -167,12 +173,18 @@
void GLES2DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) {
gles2::GetGLContext()->DeleteRenderbuffers(n, renderbuffers);
}
+void GLES2DeleteSamplers(GLsizei n, const GLuint* samplers) {
+ gles2::GetGLContext()->DeleteSamplers(n, samplers);
+}
void GLES2DeleteShader(GLuint shader) {
gles2::GetGLContext()->DeleteShader(shader);
}
void GLES2DeleteTextures(GLsizei n, const GLuint* textures) {
gles2::GetGLContext()->DeleteTextures(n, textures);
}
+void GLES2DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) {
+ gles2::GetGLContext()->DeleteTransformFeedbacks(n, ids);
+}
void GLES2DepthFunc(GLenum func) {
gles2::GetGLContext()->DepthFunc(func);
}
@@ -250,9 +262,15 @@
void GLES2GenRenderbuffers(GLsizei n, GLuint* renderbuffers) {
gles2::GetGLContext()->GenRenderbuffers(n, renderbuffers);
}
+void GLES2GenSamplers(GLsizei n, GLuint* samplers) {
+ gles2::GetGLContext()->GenSamplers(n, samplers);
+}
void GLES2GenTextures(GLsizei n, GLuint* textures) {
gles2::GetGLContext()->GenTextures(n, textures);
}
+void GLES2GenTransformFeedbacks(GLsizei n, GLuint* ids) {
+ gles2::GetGLContext()->GenTransformFeedbacks(n, ids);
+}
void GLES2GetActiveAttrib(GLuint program,
GLuint index,
GLsizei bufsize,
@@ -326,6 +344,12 @@
GLint* params) {
gles2::GetGLContext()->GetRenderbufferParameteriv(target, pname, params);
}
+void GLES2GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) {
+ gles2::GetGLContext()->GetSamplerParameterfv(sampler, pname, params);
+}
+void GLES2GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) {
+ gles2::GetGLContext()->GetSamplerParameteriv(sampler, pname, params);
+}
void GLES2GetShaderiv(GLuint shader, GLenum pname, GLint* params) {
gles2::GetGLContext()->GetShaderiv(shader, pname, params);
}
@@ -408,18 +432,27 @@
GLboolean GLES2IsRenderbuffer(GLuint renderbuffer) {
return gles2::GetGLContext()->IsRenderbuffer(renderbuffer);
}
+GLboolean GLES2IsSampler(GLuint sampler) {
+ return gles2::GetGLContext()->IsSampler(sampler);
+}
GLboolean GLES2IsShader(GLuint shader) {
return gles2::GetGLContext()->IsShader(shader);
}
GLboolean GLES2IsTexture(GLuint texture) {
return gles2::GetGLContext()->IsTexture(texture);
}
+GLboolean GLES2IsTransformFeedback(GLuint transformfeedback) {
+ return gles2::GetGLContext()->IsTransformFeedback(transformfeedback);
+}
void GLES2LineWidth(GLfloat width) {
gles2::GetGLContext()->LineWidth(width);
}
void GLES2LinkProgram(GLuint program) {
gles2::GetGLContext()->LinkProgram(program);
}
+void GLES2PauseTransformFeedback() {
+ gles2::GetGLContext()->PauseTransformFeedback();
+}
void GLES2PixelStorei(GLenum pname, GLint param) {
gles2::GetGLContext()->PixelStorei(pname, param);
}
@@ -448,9 +481,28 @@
gles2::GetGLContext()->RenderbufferStorage(target, internalformat, width,
height);
}
+void GLES2ResumeTransformFeedback() {
+ gles2::GetGLContext()->ResumeTransformFeedback();
+}
void GLES2SampleCoverage(GLclampf value, GLboolean invert) {
gles2::GetGLContext()->SampleCoverage(value, invert);
}
+void GLES2SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) {
+ gles2::GetGLContext()->SamplerParameterf(sampler, pname, param);
+}
+void GLES2SamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ const GLfloat* params) {
+ gles2::GetGLContext()->SamplerParameterfv(sampler, pname, params);
+}
+void GLES2SamplerParameteri(GLuint sampler, GLenum pname, GLint param) {
+ gles2::GetGLContext()->SamplerParameteri(sampler, pname, param);
+}
+void GLES2SamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ const GLint* params) {
+ gles2::GetGLContext()->SamplerParameteriv(sampler, pname, params);
+}
void GLES2Scissor(GLint x, GLint y, GLsizei width, GLsizei height) {
gles2::GetGLContext()->Scissor(x, y, width, height);
}
@@ -799,9 +851,15 @@
void GLES2BeginQueryEXT(GLenum target, GLuint id) {
gles2::GetGLContext()->BeginQueryEXT(target, id);
}
+void GLES2BeginTransformFeedback(GLenum primitivemode) {
+ gles2::GetGLContext()->BeginTransformFeedback(primitivemode);
+}
void GLES2EndQueryEXT(GLenum target) {
gles2::GetGLContext()->EndQueryEXT(target);
}
+void GLES2EndTransformFeedback() {
+ gles2::GetGLContext()->EndTransformFeedback();
+}
void GLES2GetQueryivEXT(GLenum target, GLenum pname, GLint* params) {
gles2::GetGLContext()->GetQueryivEXT(target, pname, params);
}
@@ -1124,10 +1182,18 @@
reinterpret_cast<GLES2FunctionPointer>(glBindRenderbuffer),
},
{
+ "glBindSampler",
+ reinterpret_cast<GLES2FunctionPointer>(glBindSampler),
+ },
+ {
"glBindTexture",
reinterpret_cast<GLES2FunctionPointer>(glBindTexture),
},
{
+ "glBindTransformFeedback",
+ reinterpret_cast<GLES2FunctionPointer>(glBindTransformFeedback),
+ },
+ {
"glBlendColor",
reinterpret_cast<GLES2FunctionPointer>(glBlendColor),
},
@@ -1232,6 +1298,10 @@
reinterpret_cast<GLES2FunctionPointer>(glDeleteRenderbuffers),
},
{
+ "glDeleteSamplers",
+ reinterpret_cast<GLES2FunctionPointer>(glDeleteSamplers),
+ },
+ {
"glDeleteShader",
reinterpret_cast<GLES2FunctionPointer>(glDeleteShader),
},
@@ -1240,6 +1310,10 @@
reinterpret_cast<GLES2FunctionPointer>(glDeleteTextures),
},
{
+ "glDeleteTransformFeedbacks",
+ reinterpret_cast<GLES2FunctionPointer>(glDeleteTransformFeedbacks),
+ },
+ {
"glDepthFunc",
reinterpret_cast<GLES2FunctionPointer>(glDepthFunc),
},
@@ -1320,10 +1394,18 @@
reinterpret_cast<GLES2FunctionPointer>(glGenRenderbuffers),
},
{
+ "glGenSamplers",
+ reinterpret_cast<GLES2FunctionPointer>(glGenSamplers),
+ },
+ {
"glGenTextures",
reinterpret_cast<GLES2FunctionPointer>(glGenTextures),
},
{
+ "glGenTransformFeedbacks",
+ reinterpret_cast<GLES2FunctionPointer>(glGenTransformFeedbacks),
+ },
+ {
"glGetActiveAttrib",
reinterpret_cast<GLES2FunctionPointer>(glGetActiveAttrib),
},
@@ -1381,6 +1463,14 @@
reinterpret_cast<GLES2FunctionPointer>(glGetRenderbufferParameteriv),
},
{
+ "glGetSamplerParameterfv",
+ reinterpret_cast<GLES2FunctionPointer>(glGetSamplerParameterfv),
+ },
+ {
+ "glGetSamplerParameteriv",
+ reinterpret_cast<GLES2FunctionPointer>(glGetSamplerParameteriv),
+ },
+ {
"glGetShaderiv",
reinterpret_cast<GLES2FunctionPointer>(glGetShaderiv),
},
@@ -1465,6 +1555,10 @@
reinterpret_cast<GLES2FunctionPointer>(glIsRenderbuffer),
},
{
+ "glIsSampler",
+ reinterpret_cast<GLES2FunctionPointer>(glIsSampler),
+ },
+ {
"glIsShader",
reinterpret_cast<GLES2FunctionPointer>(glIsShader),
},
@@ -1473,6 +1567,10 @@
reinterpret_cast<GLES2FunctionPointer>(glIsTexture),
},
{
+ "glIsTransformFeedback",
+ reinterpret_cast<GLES2FunctionPointer>(glIsTransformFeedback),
+ },
+ {
"glLineWidth",
reinterpret_cast<GLES2FunctionPointer>(glLineWidth),
},
@@ -1481,6 +1579,10 @@
reinterpret_cast<GLES2FunctionPointer>(glLinkProgram),
},
{
+ "glPauseTransformFeedback",
+ reinterpret_cast<GLES2FunctionPointer>(glPauseTransformFeedback),
+ },
+ {
"glPixelStorei",
reinterpret_cast<GLES2FunctionPointer>(glPixelStorei),
},
@@ -1505,10 +1607,30 @@
reinterpret_cast<GLES2FunctionPointer>(glRenderbufferStorage),
},
{
+ "glResumeTransformFeedback",
+ reinterpret_cast<GLES2FunctionPointer>(glResumeTransformFeedback),
+ },
+ {
"glSampleCoverage",
reinterpret_cast<GLES2FunctionPointer>(glSampleCoverage),
},
{
+ "glSamplerParameterf",
+ reinterpret_cast<GLES2FunctionPointer>(glSamplerParameterf),
+ },
+ {
+ "glSamplerParameterfv",
+ reinterpret_cast<GLES2FunctionPointer>(glSamplerParameterfv),
+ },
+ {
+ "glSamplerParameteri",
+ reinterpret_cast<GLES2FunctionPointer>(glSamplerParameteri),
+ },
+ {
+ "glSamplerParameteriv",
+ reinterpret_cast<GLES2FunctionPointer>(glSamplerParameteriv),
+ },
+ {
"glScissor",
reinterpret_cast<GLES2FunctionPointer>(glScissor),
},
@@ -1820,10 +1942,18 @@
reinterpret_cast<GLES2FunctionPointer>(glBeginQueryEXT),
},
{
+ "glBeginTransformFeedback",
+ reinterpret_cast<GLES2FunctionPointer>(glBeginTransformFeedback),
+ },
+ {
"glEndQueryEXT",
reinterpret_cast<GLES2FunctionPointer>(glEndQueryEXT),
},
{
+ "glEndTransformFeedback",
+ reinterpret_cast<GLES2FunctionPointer>(glEndTransformFeedback),
+ },
+ {
"glGetQueryivEXT",
reinterpret_cast<GLES2FunctionPointer>(glGetQueryivEXT),
},
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index 7b2faae..8d4553a 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -57,6 +57,13 @@
}
}
+void BindSampler(GLuint unit, GLuint sampler) {
+ gles2::cmds::BindSampler* c = GetCmdSpace<gles2::cmds::BindSampler>();
+ if (c) {
+ c->Init(unit, sampler);
+ }
+}
+
void BindTexture(GLenum target, GLuint texture) {
gles2::cmds::BindTexture* c = GetCmdSpace<gles2::cmds::BindTexture>();
if (c) {
@@ -64,6 +71,14 @@
}
}
+void BindTransformFeedback(GLenum target, GLuint transformfeedback) {
+ gles2::cmds::BindTransformFeedback* c =
+ GetCmdSpace<gles2::cmds::BindTransformFeedback>();
+ if (c) {
+ c->Init(target, transformfeedback);
+ }
+}
+
void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
gles2::cmds::BlendColor* c = GetCmdSpace<gles2::cmds::BlendColor>();
if (c) {
@@ -342,6 +357,15 @@
}
}
+void DeleteSamplersImmediate(GLsizei n, const GLuint* samplers) {
+ const uint32_t size = gles2::cmds::DeleteSamplersImmediate::ComputeSize(n);
+ gles2::cmds::DeleteSamplersImmediate* c =
+ GetImmediateCmdSpaceTotalSize<gles2::cmds::DeleteSamplersImmediate>(size);
+ if (c) {
+ c->Init(n, samplers);
+ }
+}
+
void DeleteShader(GLuint shader) {
gles2::cmds::DeleteShader* c = GetCmdSpace<gles2::cmds::DeleteShader>();
if (c) {
@@ -358,6 +382,17 @@
}
}
+void DeleteTransformFeedbacksImmediate(GLsizei n, const GLuint* ids) {
+ const uint32_t size =
+ gles2::cmds::DeleteTransformFeedbacksImmediate::ComputeSize(n);
+ gles2::cmds::DeleteTransformFeedbacksImmediate* c =
+ GetImmediateCmdSpaceTotalSize<
+ gles2::cmds::DeleteTransformFeedbacksImmediate>(size);
+ if (c) {
+ c->Init(n, ids);
+ }
+}
+
void DepthFunc(GLenum func) {
gles2::cmds::DepthFunc* c = GetCmdSpace<gles2::cmds::DepthFunc>();
if (c) {
@@ -524,6 +559,15 @@
}
}
+void GenSamplersImmediate(GLsizei n, GLuint* samplers) {
+ const uint32_t size = gles2::cmds::GenSamplersImmediate::ComputeSize(n);
+ gles2::cmds::GenSamplersImmediate* c =
+ GetImmediateCmdSpaceTotalSize<gles2::cmds::GenSamplersImmediate>(size);
+ if (c) {
+ c->Init(n, samplers);
+ }
+}
+
void GenTexturesImmediate(GLsizei n, GLuint* textures) {
const uint32_t size = gles2::cmds::GenTexturesImmediate::ComputeSize(n);
gles2::cmds::GenTexturesImmediate* c =
@@ -533,6 +577,17 @@
}
}
+void GenTransformFeedbacksImmediate(GLsizei n, GLuint* ids) {
+ const uint32_t size =
+ gles2::cmds::GenTransformFeedbacksImmediate::ComputeSize(n);
+ gles2::cmds::GenTransformFeedbacksImmediate* c =
+ GetImmediateCmdSpaceTotalSize<
+ gles2::cmds::GenTransformFeedbacksImmediate>(size);
+ if (c) {
+ c->Init(n, ids);
+ }
+}
+
void GetActiveAttrib(GLuint program,
GLuint index,
uint32_t name_bucket_id,
@@ -677,6 +732,28 @@
}
}
+void GetSamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ uint32_t params_shm_id,
+ uint32_t params_shm_offset) {
+ gles2::cmds::GetSamplerParameterfv* c =
+ GetCmdSpace<gles2::cmds::GetSamplerParameterfv>();
+ if (c) {
+ c->Init(sampler, pname, params_shm_id, params_shm_offset);
+ }
+}
+
+void GetSamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ uint32_t params_shm_id,
+ uint32_t params_shm_offset) {
+ gles2::cmds::GetSamplerParameteriv* c =
+ GetCmdSpace<gles2::cmds::GetSamplerParameteriv>();
+ if (c) {
+ c->Init(sampler, pname, params_shm_id, params_shm_offset);
+ }
+}
+
void GetShaderiv(GLuint shader,
GLenum pname,
uint32_t params_shm_id,
@@ -886,6 +963,15 @@
}
}
+void IsSampler(GLuint sampler,
+ uint32_t result_shm_id,
+ uint32_t result_shm_offset) {
+ gles2::cmds::IsSampler* c = GetCmdSpace<gles2::cmds::IsSampler>();
+ if (c) {
+ c->Init(sampler, result_shm_id, result_shm_offset);
+ }
+}
+
void IsShader(GLuint shader,
uint32_t result_shm_id,
uint32_t result_shm_offset) {
@@ -904,6 +990,16 @@
}
}
+void IsTransformFeedback(GLuint transformfeedback,
+ uint32_t result_shm_id,
+ uint32_t result_shm_offset) {
+ gles2::cmds::IsTransformFeedback* c =
+ GetCmdSpace<gles2::cmds::IsTransformFeedback>();
+ if (c) {
+ c->Init(transformfeedback, result_shm_id, result_shm_offset);
+ }
+}
+
void LineWidth(GLfloat width) {
gles2::cmds::LineWidth* c = GetCmdSpace<gles2::cmds::LineWidth>();
if (c) {
@@ -918,6 +1014,14 @@
}
}
+void PauseTransformFeedback() {
+ gles2::cmds::PauseTransformFeedback* c =
+ GetCmdSpace<gles2::cmds::PauseTransformFeedback>();
+ if (c) {
+ c->Init();
+ }
+}
+
void PixelStorei(GLenum pname, GLint param) {
gles2::cmds::PixelStorei* c = GetCmdSpace<gles2::cmds::PixelStorei>();
if (c) {
@@ -976,6 +1080,14 @@
}
}
+void ResumeTransformFeedback() {
+ gles2::cmds::ResumeTransformFeedback* c =
+ GetCmdSpace<gles2::cmds::ResumeTransformFeedback>();
+ if (c) {
+ c->Init();
+ }
+}
+
void SampleCoverage(GLclampf value, GLboolean invert) {
gles2::cmds::SampleCoverage* c = GetCmdSpace<gles2::cmds::SampleCoverage>();
if (c) {
@@ -983,6 +1095,46 @@
}
}
+void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) {
+ gles2::cmds::SamplerParameterf* c =
+ GetCmdSpace<gles2::cmds::SamplerParameterf>();
+ if (c) {
+ c->Init(sampler, pname, param);
+ }
+}
+
+void SamplerParameterfvImmediate(GLuint sampler,
+ GLenum pname,
+ const GLfloat* params) {
+ const uint32_t size = gles2::cmds::SamplerParameterfvImmediate::ComputeSize();
+ gles2::cmds::SamplerParameterfvImmediate* c =
+ GetImmediateCmdSpaceTotalSize<gles2::cmds::SamplerParameterfvImmediate>(
+ size);
+ if (c) {
+ c->Init(sampler, pname, params);
+ }
+}
+
+void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) {
+ gles2::cmds::SamplerParameteri* c =
+ GetCmdSpace<gles2::cmds::SamplerParameteri>();
+ if (c) {
+ c->Init(sampler, pname, param);
+ }
+}
+
+void SamplerParameterivImmediate(GLuint sampler,
+ GLenum pname,
+ const GLint* params) {
+ const uint32_t size = gles2::cmds::SamplerParameterivImmediate::ComputeSize();
+ gles2::cmds::SamplerParameterivImmediate* c =
+ GetImmediateCmdSpaceTotalSize<gles2::cmds::SamplerParameterivImmediate>(
+ size);
+ if (c) {
+ c->Init(sampler, pname, params);
+ }
+}
+
void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) {
gles2::cmds::Scissor* c = GetCmdSpace<gles2::cmds::Scissor>();
if (c) {
@@ -1689,6 +1841,14 @@
}
}
+void BeginTransformFeedback(GLenum primitivemode) {
+ gles2::cmds::BeginTransformFeedback* c =
+ GetCmdSpace<gles2::cmds::BeginTransformFeedback>();
+ if (c) {
+ c->Init(primitivemode);
+ }
+}
+
void EndQueryEXT(GLenum target, GLuint submit_count) {
gles2::cmds::EndQueryEXT* c = GetCmdSpace<gles2::cmds::EndQueryEXT>();
if (c) {
@@ -1696,6 +1856,14 @@
}
}
+void EndTransformFeedback() {
+ gles2::cmds::EndTransformFeedback* c =
+ GetCmdSpace<gles2::cmds::EndTransformFeedback>();
+ if (c) {
+ c->Init();
+ }
+}
+
void InsertEventMarkerEXT(GLuint bucket_id) {
gles2::cmds::InsertEventMarkerEXT* c =
GetCmdSpace<gles2::cmds::InsertEventMarkerEXT>();
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 19a005f..88b9c72 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -2314,6 +2314,14 @@
const GLuint* /* valuebuffers */) {
}
+void GLES2Implementation::GenSamplersHelper(
+ GLsizei /* n */, const GLuint* /* samplers */) {
+}
+
+void GLES2Implementation::GenTransformFeedbacksHelper(
+ GLsizei /* n */, const GLuint* /* transformfeedbacks */) {
+}
+
// NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id
// generates a new resource. On newer versions of OpenGL they don't. The code
// related to binding below will need to change if we switch to the new OpenGL
@@ -2684,6 +2692,39 @@
}
}
+void GLES2Implementation::DeleteSamplersStub(
+ GLsizei n, const GLuint* samplers) {
+ helper_->DeleteSamplersImmediate(n, samplers);
+}
+
+void GLES2Implementation::DeleteSamplersHelper(
+ GLsizei n, const GLuint* samplers) {
+ if (!GetIdHandler(id_namespaces::kSamplers)->FreeIds(
+ this, n, samplers, &GLES2Implementation::DeleteSamplersStub)) {
+ SetGLError(
+ GL_INVALID_VALUE,
+ "glDeleteSamplers", "id not created by this context.");
+ return;
+ }
+}
+
+void GLES2Implementation::DeleteTransformFeedbacksStub(
+ GLsizei n, const GLuint* transformfeedbacks) {
+ helper_->DeleteTransformFeedbacksImmediate(n, transformfeedbacks);
+}
+
+void GLES2Implementation::DeleteTransformFeedbacksHelper(
+ GLsizei n, const GLuint* transformfeedbacks) {
+ if (!GetIdHandler(id_namespaces::kTransformFeedbacks)->FreeIds(
+ this, n, transformfeedbacks,
+ &GLES2Implementation::DeleteTransformFeedbacksStub)) {
+ SetGLError(
+ GL_INVALID_VALUE,
+ "glDeleteTransformFeedbacks", "id not created by this context.");
+ return;
+ }
+}
+
void GLES2Implementation::DeleteValuebuffersCHROMIUMStub(
GLsizei n,
const GLuint* valuebuffers) {
@@ -3985,6 +4026,18 @@
return true;
}
+bool GLES2Implementation::GetSamplerParameterfvHelper(
+ GLuint /* sampler */, GLenum /* pname */, GLfloat* /* params */) {
+ // TODO(zmo): Implement client side caching.
+ return false;
+}
+
+bool GLES2Implementation::GetSamplerParameterivHelper(
+ GLuint /* sampler */, GLenum /* pname */, GLint* /* params */) {
+ // TODO(zmo): Implement client side caching.
+ return false;
+}
+
// Include the auto-generated part of this file. We split this because it means
// we can easily edit the non-auto generated parts right here in this file
// instead of having to edit some template or the code generator.
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index e473006..7d17d64 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -431,6 +431,8 @@
bool IsVertexArrayReservedId(GLuint id) { return false; }
bool IsProgramReservedId(GLuint id) { return false; }
bool IsValuebufferReservedId(GLuint id) { return false; }
+ bool IsSamplerReservedId(GLuint id) { return false; }
+ bool IsTransformFeedbackReservedId(GLuint id) { return false; }
void BindBufferHelper(GLenum target, GLuint buffer);
void BindFramebufferHelper(GLenum target, GLuint framebuffer);
@@ -453,6 +455,8 @@
void GenVertexArraysOESHelper(GLsizei n, const GLuint* arrays);
void GenQueriesEXTHelper(GLsizei n, const GLuint* queries);
void GenValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* valuebuffers);
+ void GenSamplersHelper(GLsizei n, const GLuint* samplers);
+ void GenTransformFeedbacksHelper(GLsizei n, const GLuint* transformfeedbacks);
void DeleteBuffersHelper(GLsizei n, const GLuint* buffers);
void DeleteFramebuffersHelper(GLsizei n, const GLuint* framebuffers);
@@ -463,6 +467,9 @@
void DeleteQueriesEXTHelper(GLsizei n, const GLuint* queries);
void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* arrays);
void DeleteValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* valuebuffers);
+ void DeleteSamplersHelper(GLsizei n, const GLuint* samplers);
+ void DeleteTransformFeedbacksHelper(
+ GLsizei n, const GLuint* transformfeedbacks);
void DeleteBuffersStub(GLsizei n, const GLuint* buffers);
void DeleteFramebuffersStub(GLsizei n, const GLuint* framebuffers);
@@ -472,6 +479,9 @@
void DeleteShaderStub(GLsizei n, const GLuint* shaders);
void DeleteVertexArraysOESStub(GLsizei n, const GLuint* arrays);
void DeleteValuebuffersCHROMIUMStub(GLsizei n, const GLuint* valuebuffers);
+ void DeleteSamplersStub(GLsizei n, const GLuint* samplers);
+ void DeleteTransformFeedbacksStub(
+ GLsizei n, const GLuint* transformfeedbacks);
void BufferDataHelper(
GLenum target, GLsizeiptr size, const void* data, GLenum usage);
@@ -520,6 +530,10 @@
GLenum target, GLenum format, GLenum pname, GLsizei bufSize,
GLint* params);
bool GetProgramivHelper(GLuint program, GLenum pname, GLint* params);
+ bool GetSamplerParameterfvHelper(
+ GLuint sampler, GLenum pname, GLfloat* params);
+ bool GetSamplerParameterivHelper(
+ GLuint sampler, GLenum pname, GLint* params);
bool GetRenderbufferParameterivHelper(
GLenum target, GLenum pname, GLint* params);
bool GetShaderivHelper(GLuint shader, GLenum pname, GLint* params);
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 7d03d88..3a5253a 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -27,8 +27,12 @@
void BindRenderbuffer(GLenum target, GLuint renderbuffer) override;
+void BindSampler(GLuint unit, GLuint sampler) override;
+
void BindTexture(GLenum target, GLuint texture) override;
+void BindTransformFeedback(GLenum target, GLuint transformfeedback) override;
+
void BlendColor(GLclampf red,
GLclampf green,
GLclampf blue,
@@ -132,10 +136,14 @@
void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) override;
+void DeleteSamplers(GLsizei n, const GLuint* samplers) override;
+
void DeleteShader(GLuint shader) override;
void DeleteTextures(GLsizei n, const GLuint* textures) override;
+void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) override;
+
void DepthFunc(GLenum func) override;
void DepthMask(GLboolean flag) override;
@@ -186,8 +194,12 @@
void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override;
+void GenSamplers(GLsizei n, GLuint* samplers) override;
+
void GenTextures(GLsizei n, GLuint* textures) override;
+void GenTransformFeedbacks(GLsizei n, GLuint* ids) override;
+
void GetActiveAttrib(GLuint program,
GLuint index,
GLsizei bufsize,
@@ -243,6 +255,14 @@
GLenum pname,
GLint* params) override;
+void GetSamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ GLfloat* params) override;
+
+void GetSamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ GLint* params) override;
+
void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override;
void GetShaderInfoLog(GLuint shader,
@@ -300,14 +320,20 @@
GLboolean IsRenderbuffer(GLuint renderbuffer) override;
+GLboolean IsSampler(GLuint sampler) override;
+
GLboolean IsShader(GLuint shader) override;
GLboolean IsTexture(GLuint texture) override;
+GLboolean IsTransformFeedback(GLuint transformfeedback) override;
+
void LineWidth(GLfloat width) override;
void LinkProgram(GLuint program) override;
+void PauseTransformFeedback() override;
+
void PixelStorei(GLenum pname, GLint param) override;
void PolygonOffset(GLfloat factor, GLfloat units) override;
@@ -329,8 +355,22 @@
GLsizei width,
GLsizei height) override;
+void ResumeTransformFeedback() override;
+
void SampleCoverage(GLclampf value, GLboolean invert) override;
+void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) override;
+
+void SamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ const GLfloat* params) override;
+
+void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) override;
+
+void SamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ const GLint* params) override;
+
void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override;
void ShaderBinary(GLsizei n,
@@ -599,8 +639,12 @@
void BeginQueryEXT(GLenum target, GLuint id) override;
+void BeginTransformFeedback(GLenum primitivemode) override;
+
void EndQueryEXT(GLenum target) override;
+void EndTransformFeedback() override;
+
void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) override;
void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) override;
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
index d7a45ce..e7ef769 100644
--- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -62,6 +62,14 @@
CheckGLError();
}
+void GLES2Implementation::BindSampler(GLuint unit, GLuint sampler) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindSampler(" << unit << ", "
+ << sampler << ")");
+ helper_->BindSampler(unit, sampler);
+ CheckGLError();
+}
+
void GLES2Implementation::BindTexture(GLenum target, GLuint texture) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindTexture("
@@ -75,6 +83,16 @@
CheckGLError();
}
+void GLES2Implementation::BindTransformFeedback(GLenum target,
+ GLuint transformfeedback) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindTransformFeedback("
+ << GLES2Util::GetStringTransformFeedbackBindTarget(target)
+ << ", " << transformfeedback << ")");
+ helper_->BindTransformFeedback(target, transformfeedback);
+ CheckGLError();
+}
+
void GLES2Implementation::BlendColor(GLclampf red,
GLclampf green,
GLclampf blue,
@@ -397,6 +415,28 @@
CheckGLError();
}
+void GLES2Implementation::DeleteSamplers(GLsizei n, const GLuint* samplers) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteSamplers(" << n << ", "
+ << static_cast<const void*>(samplers) << ")");
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (GLsizei i = 0; i < n; ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << samplers[i]);
+ }
+ });
+ GPU_CLIENT_DCHECK_CODE_BLOCK({
+ for (GLsizei i = 0; i < n; ++i) {
+ DCHECK(samplers[i] != 0);
+ }
+ });
+ if (n < 0) {
+ SetGLError(GL_INVALID_VALUE, "glDeleteSamplers", "n < 0");
+ return;
+ }
+ DeleteSamplersHelper(n, samplers);
+ CheckGLError();
+}
+
void GLES2Implementation::DeleteShader(GLuint shader) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteShader(" << shader << ")");
@@ -427,6 +467,29 @@
CheckGLError();
}
+void GLES2Implementation::DeleteTransformFeedbacks(GLsizei n,
+ const GLuint* ids) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteTransformFeedbacks(" << n
+ << ", " << static_cast<const void*>(ids) << ")");
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (GLsizei i = 0; i < n; ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << ids[i]);
+ }
+ });
+ GPU_CLIENT_DCHECK_CODE_BLOCK({
+ for (GLsizei i = 0; i < n; ++i) {
+ DCHECK(ids[i] != 0);
+ }
+ });
+ if (n < 0) {
+ SetGLError(GL_INVALID_VALUE, "glDeleteTransformFeedbacks", "n < 0");
+ return;
+ }
+ DeleteTransformFeedbacksHelper(n, ids);
+ CheckGLError();
+}
+
void GLES2Implementation::DepthFunc(GLenum func) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDepthFunc("
@@ -588,6 +651,27 @@
CheckGLError();
}
+void GLES2Implementation::GenSamplers(GLsizei n, GLuint* samplers) {
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenSamplers(" << n << ", "
+ << static_cast<const void*>(samplers) << ")");
+ if (n < 0) {
+ SetGLError(GL_INVALID_VALUE, "glGenSamplers", "n < 0");
+ return;
+ }
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GetIdHandler(id_namespaces::kSamplers)->MakeIds(this, 0, n, samplers);
+ GenSamplersHelper(n, samplers);
+ helper_->GenSamplersImmediate(n, samplers);
+ if (share_group_->bind_generates_resource())
+ helper_->CommandBufferHelper::Flush();
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (GLsizei i = 0; i < n; ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << samplers[i]);
+ }
+ });
+ CheckGLError();
+}
+
void GLES2Implementation::GenTextures(GLsizei n, GLuint* textures) {
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenTextures(" << n << ", "
<< static_cast<const void*>(textures) << ")");
@@ -609,6 +693,27 @@
CheckGLError();
}
+void GLES2Implementation::GenTransformFeedbacks(GLsizei n, GLuint* ids) {
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenTransformFeedbacks(" << n
+ << ", " << static_cast<const void*>(ids) << ")");
+ if (n < 0) {
+ SetGLError(GL_INVALID_VALUE, "glGenTransformFeedbacks", "n < 0");
+ return;
+ }
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GetIdHandler(id_namespaces::kTransformFeedbacks)->MakeIds(this, 0, n, ids);
+ GenTransformFeedbacksHelper(n, ids);
+ helper_->GenTransformFeedbacksImmediate(n, ids);
+ if (share_group_->bind_generates_resource())
+ helper_->CommandBufferHelper::Flush();
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (GLsizei i = 0; i < n; ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << ids[i]);
+ }
+ });
+ CheckGLError();
+}
+
void GLES2Implementation::GetBooleanv(GLenum pname, GLboolean* params) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLboolean, params);
@@ -874,6 +979,65 @@
});
CheckGLError();
}
+void GLES2Implementation::GetSamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ GLfloat* params) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetSamplerParameterfv("
+ << sampler << ", "
+ << GLES2Util::GetStringSamplerParameter(pname) << ", "
+ << static_cast<const void*>(params) << ")");
+ TRACE_EVENT0("gpu", "GLES2Implementation::GetSamplerParameterfv");
+ if (GetSamplerParameterfvHelper(sampler, pname, params)) {
+ return;
+ }
+ typedef cmds::GetSamplerParameterfv::Result Result;
+ Result* result = GetResultAs<Result*>();
+ if (!result) {
+ return;
+ }
+ result->SetNumResults(0);
+ helper_->GetSamplerParameterfv(sampler, pname, GetResultShmId(),
+ GetResultShmOffset());
+ WaitForCmd();
+ result->CopyResult(params);
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ }
+ });
+ CheckGLError();
+}
+void GLES2Implementation::GetSamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ GLint* params) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetSamplerParameteriv("
+ << sampler << ", "
+ << GLES2Util::GetStringSamplerParameter(pname) << ", "
+ << static_cast<const void*>(params) << ")");
+ TRACE_EVENT0("gpu", "GLES2Implementation::GetSamplerParameteriv");
+ if (GetSamplerParameterivHelper(sampler, pname, params)) {
+ return;
+ }
+ typedef cmds::GetSamplerParameteriv::Result Result;
+ Result* result = GetResultAs<Result*>();
+ if (!result) {
+ return;
+ }
+ result->SetNumResults(0);
+ helper_->GetSamplerParameteriv(sampler, pname, GetResultShmId(),
+ GetResultShmOffset());
+ WaitForCmd();
+ result->CopyResult(params);
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ }
+ });
+ CheckGLError();
+}
void GLES2Implementation::GetShaderiv(GLuint shader,
GLenum pname,
GLint* params) {
@@ -1154,6 +1318,24 @@
return result_value;
}
+GLboolean GLES2Implementation::IsSampler(GLuint sampler) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ TRACE_EVENT0("gpu", "GLES2Implementation::IsSampler");
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsSampler(" << sampler << ")");
+ typedef cmds::IsSampler::Result Result;
+ Result* result = GetResultAs<Result*>();
+ if (!result) {
+ return GL_FALSE;
+ }
+ *result = 0;
+ helper_->IsSampler(sampler, GetResultShmId(), GetResultShmOffset());
+ WaitForCmd();
+ GLboolean result_value = *result != 0;
+ GPU_CLIENT_LOG("returned " << result_value);
+ CheckGLError();
+ return result_value;
+}
+
GLboolean GLES2Implementation::IsShader(GLuint shader) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
TRACE_EVENT0("gpu", "GLES2Implementation::IsShader");
@@ -1190,6 +1372,26 @@
return result_value;
}
+GLboolean GLES2Implementation::IsTransformFeedback(GLuint transformfeedback) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ TRACE_EVENT0("gpu", "GLES2Implementation::IsTransformFeedback");
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsTransformFeedback("
+ << transformfeedback << ")");
+ typedef cmds::IsTransformFeedback::Result Result;
+ Result* result = GetResultAs<Result*>();
+ if (!result) {
+ return GL_FALSE;
+ }
+ *result = 0;
+ helper_->IsTransformFeedback(transformfeedback, GetResultShmId(),
+ GetResultShmOffset());
+ WaitForCmd();
+ GLboolean result_value = *result != 0;
+ GPU_CLIENT_LOG("returned " << result_value);
+ CheckGLError();
+ return result_value;
+}
+
void GLES2Implementation::LineWidth(GLfloat width) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glLineWidth(" << width << ")");
@@ -1197,6 +1399,14 @@
CheckGLError();
}
+void GLES2Implementation::PauseTransformFeedback() {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPauseTransformFeedback("
+ << ")");
+ helper_->PauseTransformFeedback();
+ CheckGLError();
+}
+
void GLES2Implementation::PolygonOffset(GLfloat factor, GLfloat units) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPolygonOffset(" << factor << ", "
@@ -1242,6 +1452,14 @@
CheckGLError();
}
+void GLES2Implementation::ResumeTransformFeedback() {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glResumeTransformFeedback("
+ << ")");
+ helper_->ResumeTransformFeedback();
+ CheckGLError();
+}
+
void GLES2Implementation::SampleCoverage(GLclampf value, GLboolean invert) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSampleCoverage(" << value << ", "
@@ -1250,6 +1468,52 @@
CheckGLError();
}
+void GLES2Implementation::SamplerParameterf(GLuint sampler,
+ GLenum pname,
+ GLfloat param) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSamplerParameterf(" << sampler
+ << ", " << GLES2Util::GetStringSamplerParameter(pname)
+ << ", " << param << ")");
+ helper_->SamplerParameterf(sampler, pname, param);
+ CheckGLError();
+}
+
+void GLES2Implementation::SamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ const GLfloat* params) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSamplerParameterfv(" << sampler
+ << ", " << GLES2Util::GetStringSamplerParameter(pname)
+ << ", " << static_cast<const void*>(params) << ")");
+ GPU_CLIENT_LOG("values: " << params[0]);
+ helper_->SamplerParameterfvImmediate(sampler, pname, params);
+ CheckGLError();
+}
+
+void GLES2Implementation::SamplerParameteri(GLuint sampler,
+ GLenum pname,
+ GLint param) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSamplerParameteri(" << sampler
+ << ", " << GLES2Util::GetStringSamplerParameter(pname)
+ << ", " << param << ")");
+ helper_->SamplerParameteri(sampler, pname, param);
+ CheckGLError();
+}
+
+void GLES2Implementation::SamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ const GLint* params) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSamplerParameteriv(" << sampler
+ << ", " << GLES2Util::GetStringSamplerParameter(pname)
+ << ", " << static_cast<const void*>(params) << ")");
+ GPU_CLIENT_LOG("values: " << params[0]);
+ helper_->SamplerParameterivImmediate(sampler, pname, params);
+ CheckGLError();
+}
+
void GLES2Implementation::Scissor(GLint x,
GLint y,
GLsizei width,
@@ -2391,6 +2655,23 @@
CheckGLError();
}
+void GLES2Implementation::BeginTransformFeedback(GLenum primitivemode) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBeginTransformFeedback("
+ << GLES2Util::GetStringTransformFeedbackPrimitiveMode(
+ primitivemode) << ")");
+ helper_->BeginTransformFeedback(primitivemode);
+ CheckGLError();
+}
+
+void GLES2Implementation::EndTransformFeedback() {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEndTransformFeedback("
+ << ")");
+ helper_->EndTransformFeedback();
+ CheckGLError();
+}
+
void GLES2Implementation::GenVertexArraysOES(GLsizei n, GLuint* arrays) {
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenVertexArraysOES(" << n << ", "
<< static_cast<const void*>(arrays) << ")");
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
index d772b8e..3d0f1b0 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -384,7 +384,9 @@
static const GLuint kFramebuffersStartId = 1;
static const GLuint kProgramsAndShadersStartId = 1;
static const GLuint kRenderbuffersStartId = 1;
+ static const GLuint kSamplersStartId = 1;
static const GLuint kTexturesStartId = 1;
+ static const GLuint kTransformFeedbacksStartId = 1;
static const GLuint kQueriesStartId = 1;
static const GLuint kVertexArraysStartId = 1;
static const GLuint kValuebuffersStartId = 1;
@@ -754,7 +756,9 @@
const GLuint GLES2ImplementationTest::kFramebuffersStartId;
const GLuint GLES2ImplementationTest::kProgramsAndShadersStartId;
const GLuint GLES2ImplementationTest::kRenderbuffersStartId;
+const GLuint GLES2ImplementationTest::kSamplersStartId;
const GLuint GLES2ImplementationTest::kTexturesStartId;
+const GLuint GLES2ImplementationTest::kTransformFeedbacksStartId;
const GLuint GLES2ImplementationTest::kQueriesStartId;
const GLuint GLES2ImplementationTest::kVertexArraysStartId;
const GLuint GLES2ImplementationTest::kValuebuffersStartId;
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
index 3d0eaa2..f501cd9 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -67,6 +67,28 @@
EXPECT_TRUE(NoCommandsWritten());
}
+TEST_F(GLES2ImplementationTest, BindSampler) {
+ struct Cmds {
+ cmds::BindSampler cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init(1, 2);
+
+ gl_->BindSampler(1, 2);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
+TEST_F(GLES2ImplementationTest, BindTransformFeedback) {
+ struct Cmds {
+ cmds::BindTransformFeedback cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init(GL_TRANSFORM_FEEDBACK, 2);
+
+ gl_->BindTransformFeedback(GL_TRANSFORM_FEEDBACK, 2);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
TEST_F(GLES2ImplementationTest, BlendColor) {
struct Cmds {
cmds::BlendColor cmd;
@@ -312,6 +334,20 @@
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
+TEST_F(GLES2ImplementationTest, DeleteSamplers) {
+ GLuint ids[2] = {kSamplersStartId, kSamplersStartId + 1};
+ struct Cmds {
+ cmds::DeleteSamplersImmediate del;
+ GLuint data[2];
+ };
+ Cmds expected;
+ expected.del.Init(arraysize(ids), &ids[0]);
+ expected.data[0] = kSamplersStartId;
+ expected.data[1] = kSamplersStartId + 1;
+ gl_->DeleteSamplers(arraysize(ids), &ids[0]);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
TEST_F(GLES2ImplementationTest, DeleteShader) {
struct Cmds {
cmds::DeleteShader cmd;
@@ -337,6 +373,20 @@
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
+TEST_F(GLES2ImplementationTest, DeleteTransformFeedbacks) {
+ GLuint ids[2] = {kTransformFeedbacksStartId, kTransformFeedbacksStartId + 1};
+ struct Cmds {
+ cmds::DeleteTransformFeedbacksImmediate del;
+ GLuint data[2];
+ };
+ Cmds expected;
+ expected.del.Init(arraysize(ids), &ids[0]);
+ expected.data[0] = kTransformFeedbacksStartId;
+ expected.data[1] = kTransformFeedbacksStartId + 1;
+ gl_->DeleteTransformFeedbacks(arraysize(ids), &ids[0]);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
TEST_F(GLES2ImplementationTest, DepthFunc) {
struct Cmds {
cmds::DepthFunc cmd;
@@ -543,6 +593,24 @@
EXPECT_EQ(kRenderbuffersStartId + 1, ids[1]);
}
+TEST_F(GLES2ImplementationTest, GenSamplers) {
+ GLuint ids[2] = {
+ 0,
+ };
+ struct Cmds {
+ cmds::GenSamplersImmediate gen;
+ GLuint data[2];
+ };
+ Cmds expected;
+ expected.gen.Init(arraysize(ids), &ids[0]);
+ expected.data[0] = kSamplersStartId;
+ expected.data[1] = kSamplersStartId + 1;
+ gl_->GenSamplers(arraysize(ids), &ids[0]);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+ EXPECT_EQ(kSamplersStartId, ids[0]);
+ EXPECT_EQ(kSamplersStartId + 1, ids[1]);
+}
+
TEST_F(GLES2ImplementationTest, GenTextures) {
GLuint ids[2] = {
0,
@@ -560,6 +628,24 @@
EXPECT_EQ(kTexturesStartId, ids[0]);
EXPECT_EQ(kTexturesStartId + 1, ids[1]);
}
+
+TEST_F(GLES2ImplementationTest, GenTransformFeedbacks) {
+ GLuint ids[2] = {
+ 0,
+ };
+ struct Cmds {
+ cmds::GenTransformFeedbacksImmediate gen;
+ GLuint data[2];
+ };
+ Cmds expected;
+ expected.gen.Init(arraysize(ids), &ids[0]);
+ expected.data[0] = kTransformFeedbacksStartId;
+ expected.data[1] = kTransformFeedbacksStartId + 1;
+ gl_->GenTransformFeedbacks(arraysize(ids), &ids[0]);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+ EXPECT_EQ(kTransformFeedbacksStartId, ids[0]);
+ EXPECT_EQ(kTransformFeedbacksStartId + 1, ids[1]);
+}
// TODO: Implement unit test for GetActiveAttrib
// TODO: Implement unit test for GetActiveUniform
// TODO: Implement unit test for GetAttachedShaders
@@ -707,6 +793,40 @@
EXPECT_EQ(static_cast<Result::Type>(1), result);
}
+TEST_F(GLES2ImplementationTest, GetSamplerParameterfv) {
+ struct Cmds {
+ cmds::GetSamplerParameterfv cmd;
+ };
+ typedef cmds::GetSamplerParameterfv::Result Result;
+ Result::Type result = 0;
+ Cmds expected;
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
+ expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
+ .RetiresOnSaturation();
+ gl_->GetSamplerParameterfv(123, GL_TEXTURE_MAG_FILTER, &result);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+ EXPECT_EQ(static_cast<Result::Type>(1), result);
+}
+
+TEST_F(GLES2ImplementationTest, GetSamplerParameteriv) {
+ struct Cmds {
+ cmds::GetSamplerParameteriv cmd;
+ };
+ typedef cmds::GetSamplerParameteriv::Result Result;
+ Result::Type result = 0;
+ Cmds expected;
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
+ expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
+ .RetiresOnSaturation();
+ gl_->GetSamplerParameteriv(123, GL_TEXTURE_MAG_FILTER, &result);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+ EXPECT_EQ(static_cast<Result::Type>(1), result);
+}
+
TEST_F(GLES2ImplementationTest, GetShaderiv) {
struct Cmds {
cmds::GetShaderiv cmd;
@@ -941,6 +1061,25 @@
EXPECT_TRUE(result);
}
+TEST_F(GLES2ImplementationTest, IsSampler) {
+ struct Cmds {
+ cmds::IsSampler cmd;
+ };
+
+ Cmds expected;
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(cmds::IsSampler::Result));
+ expected.cmd.Init(1, result1.id, result1.offset);
+
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .RetiresOnSaturation();
+
+ GLboolean result = gl_->IsSampler(1);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+ EXPECT_TRUE(result);
+}
+
TEST_F(GLES2ImplementationTest, IsShader) {
struct Cmds {
cmds::IsShader cmd;
@@ -979,6 +1118,25 @@
EXPECT_TRUE(result);
}
+TEST_F(GLES2ImplementationTest, IsTransformFeedback) {
+ struct Cmds {
+ cmds::IsTransformFeedback cmd;
+ };
+
+ Cmds expected;
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(cmds::IsTransformFeedback::Result));
+ expected.cmd.Init(1, result1.id, result1.offset);
+
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .RetiresOnSaturation();
+
+ GLboolean result = gl_->IsTransformFeedback(1);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+ EXPECT_TRUE(result);
+}
+
TEST_F(GLES2ImplementationTest, LineWidth) {
struct Cmds {
cmds::LineWidth cmd;
@@ -1001,6 +1159,17 @@
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
+TEST_F(GLES2ImplementationTest, PauseTransformFeedback) {
+ struct Cmds {
+ cmds::PauseTransformFeedback cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init();
+
+ gl_->PauseTransformFeedback();
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
TEST_F(GLES2ImplementationTest, PixelStorei) {
struct Cmds {
cmds::PixelStorei cmd;
@@ -1056,6 +1225,17 @@
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
+TEST_F(GLES2ImplementationTest, ResumeTransformFeedback) {
+ struct Cmds {
+ cmds::ResumeTransformFeedback cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init();
+
+ gl_->ResumeTransformFeedback();
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
TEST_F(GLES2ImplementationTest, SampleCoverage) {
struct Cmds {
cmds::SampleCoverage cmd;
@@ -1067,6 +1247,60 @@
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
+TEST_F(GLES2ImplementationTest, SamplerParameterf) {
+ struct Cmds {
+ cmds::SamplerParameterf cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init(1, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ gl_->SamplerParameterf(1, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
+TEST_F(GLES2ImplementationTest, SamplerParameterfv) {
+ GLfloat data[1] = {0};
+ struct Cmds {
+ cmds::SamplerParameterfvImmediate cmd;
+ GLfloat data[1];
+ };
+
+ for (int jj = 0; jj < 1; ++jj) {
+ data[jj] = static_cast<GLfloat>(jj);
+ }
+ Cmds expected;
+ expected.cmd.Init(1, GL_TEXTURE_MAG_FILTER, &data[0]);
+ gl_->SamplerParameterfv(1, GL_TEXTURE_MAG_FILTER, &data[0]);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
+TEST_F(GLES2ImplementationTest, SamplerParameteri) {
+ struct Cmds {
+ cmds::SamplerParameteri cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init(1, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ gl_->SamplerParameteri(1, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
+TEST_F(GLES2ImplementationTest, SamplerParameteriv) {
+ GLint data[1] = {0};
+ struct Cmds {
+ cmds::SamplerParameterivImmediate cmd;
+ GLint data[1];
+ };
+
+ for (int jj = 0; jj < 1; ++jj) {
+ data[jj] = static_cast<GLint>(jj);
+ }
+ Cmds expected;
+ expected.cmd.Init(1, GL_TEXTURE_MAG_FILTER, &data[0]);
+ gl_->SamplerParameteriv(1, GL_TEXTURE_MAG_FILTER, &data[0]);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
TEST_F(GLES2ImplementationTest, Scissor) {
struct Cmds {
cmds::Scissor cmd;
@@ -2122,6 +2356,28 @@
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
// TODO: Implement unit test for BeginQueryEXT
+
+TEST_F(GLES2ImplementationTest, BeginTransformFeedback) {
+ struct Cmds {
+ cmds::BeginTransformFeedback cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init(GL_POINTS);
+
+ gl_->BeginTransformFeedback(GL_POINTS);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
+TEST_F(GLES2ImplementationTest, EndTransformFeedback) {
+ struct Cmds {
+ cmds::EndTransformFeedback cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init();
+
+ gl_->EndTransformFeedback();
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
// TODO: Implement unit test for InsertEventMarkerEXT
// TODO: Implement unit test for PushGroupMarkerEXT
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h
index f6317bb..5a5d289 100644
--- a/gpu/command_buffer/client/gles2_interface_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -21,7 +21,9 @@
virtual void BindBuffer(GLenum target, GLuint buffer) = 0;
virtual void BindFramebuffer(GLenum target, GLuint framebuffer) = 0;
virtual void BindRenderbuffer(GLenum target, GLuint renderbuffer) = 0;
+virtual void BindSampler(GLuint unit, GLuint sampler) = 0;
virtual void BindTexture(GLenum target, GLuint texture) = 0;
+virtual void BindTransformFeedback(GLenum target, GLuint transformfeedback) = 0;
virtual void BlendColor(GLclampf red,
GLclampf green,
GLclampf blue,
@@ -99,8 +101,10 @@
virtual void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) = 0;
virtual void DeleteProgram(GLuint program) = 0;
virtual void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) = 0;
+virtual void DeleteSamplers(GLsizei n, const GLuint* samplers) = 0;
virtual void DeleteShader(GLuint shader) = 0;
virtual void DeleteTextures(GLsizei n, const GLuint* textures) = 0;
+virtual void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) = 0;
virtual void DepthFunc(GLenum func) = 0;
virtual void DepthMask(GLboolean flag) = 0;
virtual void DepthRangef(GLclampf zNear, GLclampf zFar) = 0;
@@ -135,7 +139,9 @@
virtual void GenerateMipmap(GLenum target) = 0;
virtual void GenFramebuffers(GLsizei n, GLuint* framebuffers) = 0;
virtual void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) = 0;
+virtual void GenSamplers(GLsizei n, GLuint* samplers) = 0;
virtual void GenTextures(GLsizei n, GLuint* textures) = 0;
+virtual void GenTransformFeedbacks(GLsizei n, GLuint* ids) = 0;
virtual void GetActiveAttrib(GLuint program,
GLuint index,
GLsizei bufsize,
@@ -179,6 +185,12 @@
virtual void GetRenderbufferParameteriv(GLenum target,
GLenum pname,
GLint* params) = 0;
+virtual void GetSamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ GLfloat* params) = 0;
+virtual void GetSamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ GLint* params) = 0;
virtual void GetShaderiv(GLuint shader, GLenum pname, GLint* params) = 0;
virtual void GetShaderInfoLog(GLuint shader,
GLsizei bufsize,
@@ -221,10 +233,13 @@
virtual GLboolean IsFramebuffer(GLuint framebuffer) = 0;
virtual GLboolean IsProgram(GLuint program) = 0;
virtual GLboolean IsRenderbuffer(GLuint renderbuffer) = 0;
+virtual GLboolean IsSampler(GLuint sampler) = 0;
virtual GLboolean IsShader(GLuint shader) = 0;
virtual GLboolean IsTexture(GLuint texture) = 0;
+virtual GLboolean IsTransformFeedback(GLuint transformfeedback) = 0;
virtual void LineWidth(GLfloat width) = 0;
virtual void LinkProgram(GLuint program) = 0;
+virtual void PauseTransformFeedback() = 0;
virtual void PixelStorei(GLenum pname, GLint param) = 0;
virtual void PolygonOffset(GLfloat factor, GLfloat units) = 0;
virtual void ReadBuffer(GLenum src) = 0;
@@ -240,7 +255,16 @@
GLenum internalformat,
GLsizei width,
GLsizei height) = 0;
+virtual void ResumeTransformFeedback() = 0;
virtual void SampleCoverage(GLclampf value, GLboolean invert) = 0;
+virtual void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) = 0;
+virtual void SamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ const GLfloat* params) = 0;
+virtual void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) = 0;
+virtual void SamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ const GLint* params) = 0;
virtual void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) = 0;
virtual void ShaderBinary(GLsizei n,
const GLuint* shaders,
@@ -438,7 +462,9 @@
virtual void DeleteQueriesEXT(GLsizei n, const GLuint* queries) = 0;
virtual GLboolean IsQueryEXT(GLuint id) = 0;
virtual void BeginQueryEXT(GLenum target, GLuint id) = 0;
+virtual void BeginTransformFeedback(GLenum primitivemode) = 0;
virtual void EndQueryEXT(GLenum target) = 0;
+virtual void EndTransformFeedback() = 0;
virtual void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) = 0;
virtual void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) = 0;
virtual void InsertEventMarkerEXT(GLsizei length, const GLchar* marker) = 0;
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
index cbab14f..c2f4920 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -20,7 +20,9 @@
void BindBuffer(GLenum target, GLuint buffer) override;
void BindFramebuffer(GLenum target, GLuint framebuffer) override;
void BindRenderbuffer(GLenum target, GLuint renderbuffer) override;
+void BindSampler(GLuint unit, GLuint sampler) override;
void BindTexture(GLenum target, GLuint texture) override;
+void BindTransformFeedback(GLenum target, GLuint transformfeedback) override;
void BlendColor(GLclampf red,
GLclampf green,
GLclampf blue,
@@ -98,8 +100,10 @@
void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override;
void DeleteProgram(GLuint program) override;
void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) override;
+void DeleteSamplers(GLsizei n, const GLuint* samplers) override;
void DeleteShader(GLuint shader) override;
void DeleteTextures(GLsizei n, const GLuint* textures) override;
+void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) override;
void DepthFunc(GLenum func) override;
void DepthMask(GLboolean flag) override;
void DepthRangef(GLclampf zNear, GLclampf zFar) override;
@@ -134,7 +138,9 @@
void GenerateMipmap(GLenum target) override;
void GenFramebuffers(GLsizei n, GLuint* framebuffers) override;
void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override;
+void GenSamplers(GLsizei n, GLuint* samplers) override;
void GenTextures(GLsizei n, GLuint* textures) override;
+void GenTransformFeedbacks(GLsizei n, GLuint* ids) override;
void GetActiveAttrib(GLuint program,
GLuint index,
GLsizei bufsize,
@@ -176,6 +182,12 @@
void GetRenderbufferParameteriv(GLenum target,
GLenum pname,
GLint* params) override;
+void GetSamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ GLfloat* params) override;
+void GetSamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ GLint* params) override;
void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override;
void GetShaderInfoLog(GLuint shader,
GLsizei bufsize,
@@ -216,10 +228,13 @@
GLboolean IsFramebuffer(GLuint framebuffer) override;
GLboolean IsProgram(GLuint program) override;
GLboolean IsRenderbuffer(GLuint renderbuffer) override;
+GLboolean IsSampler(GLuint sampler) override;
GLboolean IsShader(GLuint shader) override;
GLboolean IsTexture(GLuint texture) override;
+GLboolean IsTransformFeedback(GLuint transformfeedback) override;
void LineWidth(GLfloat width) override;
void LinkProgram(GLuint program) override;
+void PauseTransformFeedback() override;
void PixelStorei(GLenum pname, GLint param) override;
void PolygonOffset(GLfloat factor, GLfloat units) override;
void ReadBuffer(GLenum src) override;
@@ -235,7 +250,16 @@
GLenum internalformat,
GLsizei width,
GLsizei height) override;
+void ResumeTransformFeedback() override;
void SampleCoverage(GLclampf value, GLboolean invert) override;
+void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) override;
+void SamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ const GLfloat* params) override;
+void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) override;
+void SamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ const GLint* params) override;
void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override;
void ShaderBinary(GLsizei n,
const GLuint* shaders,
@@ -427,7 +451,9 @@
void DeleteQueriesEXT(GLsizei n, const GLuint* queries) override;
GLboolean IsQueryEXT(GLuint id) override;
void BeginQueryEXT(GLenum target, GLuint id) override;
+void BeginTransformFeedback(GLenum primitivemode) override;
void EndQueryEXT(GLenum target) override;
+void EndTransformFeedback() override;
void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) override;
void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) override;
void InsertEventMarkerEXT(GLsizei length, const GLchar* marker) override;
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
index c3d2803..fcd196d 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -29,9 +29,14 @@
void GLES2InterfaceStub::BindRenderbuffer(GLenum /* target */,
GLuint /* renderbuffer */) {
}
+void GLES2InterfaceStub::BindSampler(GLuint /* unit */, GLuint /* sampler */) {
+}
void GLES2InterfaceStub::BindTexture(GLenum /* target */,
GLuint /* texture */) {
}
+void GLES2InterfaceStub::BindTransformFeedback(GLenum /* target */,
+ GLuint /* transformfeedback */) {
+}
void GLES2InterfaceStub::BlendColor(GLclampf /* red */,
GLclampf /* green */,
GLclampf /* blue */,
@@ -143,11 +148,17 @@
GLsizei /* n */,
const GLuint* /* renderbuffers */) {
}
+void GLES2InterfaceStub::DeleteSamplers(GLsizei /* n */,
+ const GLuint* /* samplers */) {
+}
void GLES2InterfaceStub::DeleteShader(GLuint /* shader */) {
}
void GLES2InterfaceStub::DeleteTextures(GLsizei /* n */,
const GLuint* /* textures */) {
}
+void GLES2InterfaceStub::DeleteTransformFeedbacks(GLsizei /* n */,
+ const GLuint* /* ids */) {
+}
void GLES2InterfaceStub::DepthFunc(GLenum /* func */) {
}
void GLES2InterfaceStub::DepthMask(GLboolean /* flag */) {
@@ -209,8 +220,13 @@
void GLES2InterfaceStub::GenRenderbuffers(GLsizei /* n */,
GLuint* /* renderbuffers */) {
}
+void GLES2InterfaceStub::GenSamplers(GLsizei /* n */, GLuint* /* samplers */) {
+}
void GLES2InterfaceStub::GenTextures(GLsizei /* n */, GLuint* /* textures */) {
}
+void GLES2InterfaceStub::GenTransformFeedbacks(GLsizei /* n */,
+ GLuint* /* ids */) {
+}
void GLES2InterfaceStub::GetActiveAttrib(GLuint /* program */,
GLuint /* index */,
GLsizei /* bufsize */,
@@ -275,6 +291,14 @@
GLenum /* pname */,
GLint* /* params */) {
}
+void GLES2InterfaceStub::GetSamplerParameterfv(GLuint /* sampler */,
+ GLenum /* pname */,
+ GLfloat* /* params */) {
+}
+void GLES2InterfaceStub::GetSamplerParameteriv(GLuint /* sampler */,
+ GLenum /* pname */,
+ GLint* /* params */) {
+}
void GLES2InterfaceStub::GetShaderiv(GLuint /* shader */,
GLenum /* pname */,
GLint* /* params */) {
@@ -360,16 +384,25 @@
GLboolean GLES2InterfaceStub::IsRenderbuffer(GLuint /* renderbuffer */) {
return 0;
}
+GLboolean GLES2InterfaceStub::IsSampler(GLuint /* sampler */) {
+ return 0;
+}
GLboolean GLES2InterfaceStub::IsShader(GLuint /* shader */) {
return 0;
}
GLboolean GLES2InterfaceStub::IsTexture(GLuint /* texture */) {
return 0;
}
+GLboolean GLES2InterfaceStub::IsTransformFeedback(
+ GLuint /* transformfeedback */) {
+ return 0;
+}
void GLES2InterfaceStub::LineWidth(GLfloat /* width */) {
}
void GLES2InterfaceStub::LinkProgram(GLuint /* program */) {
}
+void GLES2InterfaceStub::PauseTransformFeedback() {
+}
void GLES2InterfaceStub::PixelStorei(GLenum /* pname */, GLint /* param */) {
}
void GLES2InterfaceStub::PolygonOffset(GLfloat /* factor */,
@@ -392,9 +425,27 @@
GLsizei /* width */,
GLsizei /* height */) {
}
+void GLES2InterfaceStub::ResumeTransformFeedback() {
+}
void GLES2InterfaceStub::SampleCoverage(GLclampf /* value */,
GLboolean /* invert */) {
}
+void GLES2InterfaceStub::SamplerParameterf(GLuint /* sampler */,
+ GLenum /* pname */,
+ GLfloat /* param */) {
+}
+void GLES2InterfaceStub::SamplerParameterfv(GLuint /* sampler */,
+ GLenum /* pname */,
+ const GLfloat* /* params */) {
+}
+void GLES2InterfaceStub::SamplerParameteri(GLuint /* sampler */,
+ GLenum /* pname */,
+ GLint /* param */) {
+}
+void GLES2InterfaceStub::SamplerParameteriv(GLuint /* sampler */,
+ GLenum /* pname */,
+ const GLint* /* params */) {
+}
void GLES2InterfaceStub::Scissor(GLint /* x */,
GLint /* y */,
GLsizei /* width */,
@@ -743,8 +794,12 @@
}
void GLES2InterfaceStub::BeginQueryEXT(GLenum /* target */, GLuint /* id */) {
}
+void GLES2InterfaceStub::BeginTransformFeedback(GLenum /* primitivemode */) {
+}
void GLES2InterfaceStub::EndQueryEXT(GLenum /* target */) {
}
+void GLES2InterfaceStub::EndTransformFeedback() {
+}
void GLES2InterfaceStub::GetQueryivEXT(GLenum /* target */,
GLenum /* pname */,
GLint* /* params */) {
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
index f952d58..cd8ad7c 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -20,7 +20,9 @@
void BindBuffer(GLenum target, GLuint buffer) override;
void BindFramebuffer(GLenum target, GLuint framebuffer) override;
void BindRenderbuffer(GLenum target, GLuint renderbuffer) override;
+void BindSampler(GLuint unit, GLuint sampler) override;
void BindTexture(GLenum target, GLuint texture) override;
+void BindTransformFeedback(GLenum target, GLuint transformfeedback) override;
void BlendColor(GLclampf red,
GLclampf green,
GLclampf blue,
@@ -98,8 +100,10 @@
void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override;
void DeleteProgram(GLuint program) override;
void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) override;
+void DeleteSamplers(GLsizei n, const GLuint* samplers) override;
void DeleteShader(GLuint shader) override;
void DeleteTextures(GLsizei n, const GLuint* textures) override;
+void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) override;
void DepthFunc(GLenum func) override;
void DepthMask(GLboolean flag) override;
void DepthRangef(GLclampf zNear, GLclampf zFar) override;
@@ -134,7 +138,9 @@
void GenerateMipmap(GLenum target) override;
void GenFramebuffers(GLsizei n, GLuint* framebuffers) override;
void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override;
+void GenSamplers(GLsizei n, GLuint* samplers) override;
void GenTextures(GLsizei n, GLuint* textures) override;
+void GenTransformFeedbacks(GLsizei n, GLuint* ids) override;
void GetActiveAttrib(GLuint program,
GLuint index,
GLsizei bufsize,
@@ -176,6 +182,12 @@
void GetRenderbufferParameteriv(GLenum target,
GLenum pname,
GLint* params) override;
+void GetSamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ GLfloat* params) override;
+void GetSamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ GLint* params) override;
void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override;
void GetShaderInfoLog(GLuint shader,
GLsizei bufsize,
@@ -216,10 +228,13 @@
GLboolean IsFramebuffer(GLuint framebuffer) override;
GLboolean IsProgram(GLuint program) override;
GLboolean IsRenderbuffer(GLuint renderbuffer) override;
+GLboolean IsSampler(GLuint sampler) override;
GLboolean IsShader(GLuint shader) override;
GLboolean IsTexture(GLuint texture) override;
+GLboolean IsTransformFeedback(GLuint transformfeedback) override;
void LineWidth(GLfloat width) override;
void LinkProgram(GLuint program) override;
+void PauseTransformFeedback() override;
void PixelStorei(GLenum pname, GLint param) override;
void PolygonOffset(GLfloat factor, GLfloat units) override;
void ReadBuffer(GLenum src) override;
@@ -235,7 +250,16 @@
GLenum internalformat,
GLsizei width,
GLsizei height) override;
+void ResumeTransformFeedback() override;
void SampleCoverage(GLclampf value, GLboolean invert) override;
+void SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) override;
+void SamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ const GLfloat* params) override;
+void SamplerParameteri(GLuint sampler, GLenum pname, GLint param) override;
+void SamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ const GLint* params) override;
void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override;
void ShaderBinary(GLsizei n,
const GLuint* shaders,
@@ -427,7 +451,9 @@
void DeleteQueriesEXT(GLsizei n, const GLuint* queries) override;
GLboolean IsQueryEXT(GLuint id) override;
void BeginQueryEXT(GLenum target, GLuint id) override;
+void BeginTransformFeedback(GLenum primitivemode) override;
void EndQueryEXT(GLenum target) override;
+void EndTransformFeedback() override;
void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) override;
void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) override;
void InsertEventMarkerEXT(GLsizei length, const GLchar* marker) override;
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
index c9f8b93..567dace 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -46,11 +46,22 @@
gl_->BindRenderbuffer(target, renderbuffer);
}
+void GLES2TraceImplementation::BindSampler(GLuint unit, GLuint sampler) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BindSampler");
+ gl_->BindSampler(unit, sampler);
+}
+
void GLES2TraceImplementation::BindTexture(GLenum target, GLuint texture) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BindTexture");
gl_->BindTexture(target, texture);
}
+void GLES2TraceImplementation::BindTransformFeedback(GLenum target,
+ GLuint transformfeedback) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BindTransformFeedback");
+ gl_->BindTransformFeedback(target, transformfeedback);
+}
+
void GLES2TraceImplementation::BlendColor(GLclampf red,
GLclampf green,
GLclampf blue,
@@ -240,6 +251,12 @@
gl_->DeleteRenderbuffers(n, renderbuffers);
}
+void GLES2TraceImplementation::DeleteSamplers(GLsizei n,
+ const GLuint* samplers) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DeleteSamplers");
+ gl_->DeleteSamplers(n, samplers);
+}
+
void GLES2TraceImplementation::DeleteShader(GLuint shader) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DeleteShader");
gl_->DeleteShader(shader);
@@ -251,6 +268,12 @@
gl_->DeleteTextures(n, textures);
}
+void GLES2TraceImplementation::DeleteTransformFeedbacks(GLsizei n,
+ const GLuint* ids) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DeleteTransformFeedbacks");
+ gl_->DeleteTransformFeedbacks(n, ids);
+}
+
void GLES2TraceImplementation::DepthFunc(GLenum func) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DepthFunc");
gl_->DepthFunc(func);
@@ -371,11 +394,21 @@
gl_->GenRenderbuffers(n, renderbuffers);
}
+void GLES2TraceImplementation::GenSamplers(GLsizei n, GLuint* samplers) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GenSamplers");
+ gl_->GenSamplers(n, samplers);
+}
+
void GLES2TraceImplementation::GenTextures(GLsizei n, GLuint* textures) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GenTextures");
gl_->GenTextures(n, textures);
}
+void GLES2TraceImplementation::GenTransformFeedbacks(GLsizei n, GLuint* ids) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GenTransformFeedbacks");
+ gl_->GenTransformFeedbacks(n, ids);
+}
+
void GLES2TraceImplementation::GetActiveAttrib(GLuint program,
GLuint index,
GLsizei bufsize,
@@ -481,6 +514,20 @@
gl_->GetRenderbufferParameteriv(target, pname, params);
}
+void GLES2TraceImplementation::GetSamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ GLfloat* params) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetSamplerParameterfv");
+ gl_->GetSamplerParameterfv(sampler, pname, params);
+}
+
+void GLES2TraceImplementation::GetSamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ GLint* params) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetSamplerParameteriv");
+ gl_->GetSamplerParameteriv(sampler, pname, params);
+}
+
void GLES2TraceImplementation::GetShaderiv(GLuint shader,
GLenum pname,
GLint* params) {
@@ -623,6 +670,11 @@
return gl_->IsRenderbuffer(renderbuffer);
}
+GLboolean GLES2TraceImplementation::IsSampler(GLuint sampler) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::IsSampler");
+ return gl_->IsSampler(sampler);
+}
+
GLboolean GLES2TraceImplementation::IsShader(GLuint shader) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::IsShader");
return gl_->IsShader(shader);
@@ -633,6 +685,12 @@
return gl_->IsTexture(texture);
}
+GLboolean GLES2TraceImplementation::IsTransformFeedback(
+ GLuint transformfeedback) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::IsTransformFeedback");
+ return gl_->IsTransformFeedback(transformfeedback);
+}
+
void GLES2TraceImplementation::LineWidth(GLfloat width) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::LineWidth");
gl_->LineWidth(width);
@@ -643,6 +701,11 @@
gl_->LinkProgram(program);
}
+void GLES2TraceImplementation::PauseTransformFeedback() {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::PauseTransformFeedback");
+ gl_->PauseTransformFeedback();
+}
+
void GLES2TraceImplementation::PixelStorei(GLenum pname, GLint param) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::PixelStorei");
gl_->PixelStorei(pname, param);
@@ -682,12 +745,45 @@
gl_->RenderbufferStorage(target, internalformat, width, height);
}
+void GLES2TraceImplementation::ResumeTransformFeedback() {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ResumeTransformFeedback");
+ gl_->ResumeTransformFeedback();
+}
+
void GLES2TraceImplementation::SampleCoverage(GLclampf value,
GLboolean invert) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::SampleCoverage");
gl_->SampleCoverage(value, invert);
}
+void GLES2TraceImplementation::SamplerParameterf(GLuint sampler,
+ GLenum pname,
+ GLfloat param) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::SamplerParameterf");
+ gl_->SamplerParameterf(sampler, pname, param);
+}
+
+void GLES2TraceImplementation::SamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ const GLfloat* params) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::SamplerParameterfv");
+ gl_->SamplerParameterfv(sampler, pname, params);
+}
+
+void GLES2TraceImplementation::SamplerParameteri(GLuint sampler,
+ GLenum pname,
+ GLint param) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::SamplerParameteri");
+ gl_->SamplerParameteri(sampler, pname, param);
+}
+
+void GLES2TraceImplementation::SamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ const GLint* params) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::SamplerParameteriv");
+ gl_->SamplerParameteriv(sampler, pname, params);
+}
+
void GLES2TraceImplementation::Scissor(GLint x,
GLint y,
GLsizei width,
@@ -1268,11 +1364,21 @@
gl_->BeginQueryEXT(target, id);
}
+void GLES2TraceImplementation::BeginTransformFeedback(GLenum primitivemode) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BeginTransformFeedback");
+ gl_->BeginTransformFeedback(primitivemode);
+}
+
void GLES2TraceImplementation::EndQueryEXT(GLenum target) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::EndQueryEXT");
gl_->EndQueryEXT(target);
}
+void GLES2TraceImplementation::EndTransformFeedback() {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::EndTransformFeedback");
+ gl_->EndTransformFeedback();
+}
+
void GLES2TraceImplementation::GetQueryivEXT(GLenum target,
GLenum pname,
GLint* params) {
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt
index f0b1627..d046748e 100644
--- a/gpu/command_buffer/cmd_buffer_functions.txt
+++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -10,7 +10,9 @@
GL_APICALL void GL_APIENTRY glBindBuffer (GLenumBufferTarget target, GLidBindBuffer buffer);
GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenumFrameBufferTarget target, GLidBindFramebuffer framebuffer);
GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenumRenderBufferTarget target, GLidBindRenderbuffer renderbuffer);
+GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLidBindSampler sampler);
GL_APICALL void GL_APIENTRY glBindTexture (GLenumTextureBindTarget target, GLidBindTexture texture);
+GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenumTransformFeedbackBindTarget target, GLidBindTransformFeedback transformfeedback);
GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
GL_APICALL void GL_APIENTRY glBlendEquation ( GLenumEquation mode );
GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenumEquation modeRGB, GLenumEquation modeAlpha);
@@ -37,8 +39,10 @@
GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizeiNotNegative n, const GLuint* framebuffers);
GL_APICALL void GL_APIENTRY glDeleteProgram (GLidProgram program);
GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizeiNotNegative n, const GLuint* renderbuffers);
+GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizeiNotNegative n, const GLuint* samplers);
GL_APICALL void GL_APIENTRY glDeleteShader (GLidShader shader);
GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizeiNotNegative n, const GLuint* textures);
+GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizeiNotNegative n, const GLuint* ids);
GL_APICALL void GL_APIENTRY glDepthFunc (GLenumCmpFunction func);
GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag);
GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar);
@@ -59,7 +63,9 @@
GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenumTextureBindTarget target);
GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizeiNotNegative n, GLuint* framebuffers);
GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizeiNotNegative n, GLuint* renderbuffers);
+GL_APICALL void GL_APIENTRY glGenSamplers (GLsizeiNotNegative n, GLuint* samplers);
GL_APICALL void GL_APIENTRY glGenTextures (GLsizeiNotNegative n, GLuint* textures);
+GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizeiNotNegative n, GLuint* ids);
GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLidProgram program, GLuint index, GLsizeiNotNegative bufsize, GLsizeiOptional* length, GLint* size, GLenum* type, char* name);
GL_APICALL void GL_APIENTRY glGetActiveUniform (GLidProgram program, GLuint index, GLsizeiNotNegative bufsize, GLsizeiOptional* length, GLint* size, GLenum* type, char* name);
GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLidProgram program, GLsizeiNotNegative maxcount, GLsizeiOptional* count, GLuint* shaders);
@@ -74,6 +80,8 @@
GL_APICALL void GL_APIENTRY glGetProgramiv (GLidProgram program, GLenumProgramParameter pname, GLint* params);
GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLidProgram program, GLsizeiNotNegative bufsize, GLsizeiOptional* length, char* infolog);
GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenumRenderBufferTarget target, GLenumRenderBufferParameter pname, GLint* params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLidSampler sampler, GLenumSamplerParameter pname, GLfloat* params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLidSampler sampler, GLenumSamplerParameter pname, GLint* params);
GL_APICALL void GL_APIENTRY glGetShaderiv (GLidShader shader, GLenumShaderParameter pname, GLint* params);
GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLidShader shader, GLsizeiNotNegative bufsize, GLsizeiOptional* length, char* infolog);
GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenumShaderType shadertype, GLenumShaderPrecision precisiontype, GLint* range, GLint* precision);
@@ -95,17 +103,25 @@
GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLidFramebuffer framebuffer);
GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLidProgram program);
GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLidRenderbuffer renderbuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLidSampler sampler);
GL_APICALL GLboolean GL_APIENTRY glIsShader (GLidShader shader);
GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLidTexture texture);
+GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLidTransformFeedback transformfeedback);
GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
GL_APICALL void GL_APIENTRY glLinkProgram (GLidProgram program);
+GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void);
GL_APICALL void GL_APIENTRY glPixelStorei (GLenumPixelStore pname, GLintPixelStoreAlignment param);
GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
GL_APICALL void GL_APIENTRY glReadBuffer (GLenum src);
GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenumReadPixelFormat format, GLenumPixelType type, void* pixels);
GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void);
GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenumRenderBufferTarget target, GLenumRenderBufferFormat internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void);
GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert);
+GL_APICALL void GL_APIENTRY glSamplerParameterf (GLidBindSampler sampler, GLenumSamplerParameter pname, GLfloat param);
+GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLidBindSampler sampler, GLenumSamplerParameter pname, const GLfloat* params);
+GL_APICALL void GL_APIENTRY glSamplerParameteri (GLidBindSampler sampler, GLenumSamplerParameter pname, GLint param);
+GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLidBindSampler sampler, GLenumSamplerParameter pname, const GLint* params);
GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glShaderBinary (GLsizeiNotNegative n, const GLuint* shaders, GLenumShaderBinaryFormat binaryformat, const void* binary, GLsizeiNotNegative length);
GL_APICALL void GL_APIENTRY glShaderSource (GLidShader shader, GLsizeiNotNegative count, const GLchar* const* str, const GLint* length);
@@ -183,7 +199,9 @@
GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizeiNotNegative n, const GLuint* queries);
GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLidQuery id);
GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenumQueryTarget target, GLidQuery id);
+GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenumTransformFeedbackPrimitiveMode primitivemode);
GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenumQueryTarget target);
+GL_APICALL void GL_APIENTRY glEndTransformFeedback (void);
GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenumQueryTarget target, GLenumQueryParameter pname, GLint* params);
GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLidQuery id, GLenumQueryObjectParameter pname, GLuint* params);
GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar* marker);
diff --git a/gpu/command_buffer/common/gles2_cmd_format.h b/gpu/command_buffer/common/gles2_cmd_format.h
index c0bc663..8b22bc6 100644
--- a/gpu/command_buffer/common/gles2_cmd_format.h
+++ b/gpu/command_buffer/common/gles2_cmd_format.h
@@ -60,6 +60,8 @@
kQueries,
kVertexArrays,
kValuebuffers,
+ kSamplers,
+ kTransformFeedbacks,
kNumIdNamespaces
};
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index bdee4e6..c94feaa 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -232,6 +232,42 @@
COMPILE_ASSERT(offsetof(BindRenderbuffer, renderbuffer) == 8,
OffsetOf_BindRenderbuffer_renderbuffer_not_8);
+struct BindSampler {
+ typedef BindSampler ValueType;
+ static const CommandId kCmdId = kBindSampler;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLuint _unit, GLuint _sampler) {
+ SetHeader();
+ unit = _unit;
+ sampler = _sampler;
+ }
+
+ void* Set(void* cmd, GLuint _unit, GLuint _sampler) {
+ static_cast<ValueType*>(cmd)->Init(_unit, _sampler);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t unit;
+ uint32_t sampler;
+};
+
+COMPILE_ASSERT(sizeof(BindSampler) == 12, Sizeof_BindSampler_is_not_12);
+COMPILE_ASSERT(offsetof(BindSampler, header) == 0,
+ OffsetOf_BindSampler_header_not_0);
+COMPILE_ASSERT(offsetof(BindSampler, unit) == 4,
+ OffsetOf_BindSampler_unit_not_4);
+COMPILE_ASSERT(offsetof(BindSampler, sampler) == 8,
+ OffsetOf_BindSampler_sampler_not_8);
+
struct BindTexture {
typedef BindTexture ValueType;
static const CommandId kCmdId = kBindTexture;
@@ -268,6 +304,43 @@
COMPILE_ASSERT(offsetof(BindTexture, texture) == 8,
OffsetOf_BindTexture_texture_not_8);
+struct BindTransformFeedback {
+ typedef BindTransformFeedback ValueType;
+ static const CommandId kCmdId = kBindTransformFeedback;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLenum _target, GLuint _transformfeedback) {
+ SetHeader();
+ target = _target;
+ transformfeedback = _transformfeedback;
+ }
+
+ void* Set(void* cmd, GLenum _target, GLuint _transformfeedback) {
+ static_cast<ValueType*>(cmd)->Init(_target, _transformfeedback);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t target;
+ uint32_t transformfeedback;
+};
+
+COMPILE_ASSERT(sizeof(BindTransformFeedback) == 12,
+ Sizeof_BindTransformFeedback_is_not_12);
+COMPILE_ASSERT(offsetof(BindTransformFeedback, header) == 0,
+ OffsetOf_BindTransformFeedback_header_not_0);
+COMPILE_ASSERT(offsetof(BindTransformFeedback, target) == 4,
+ OffsetOf_BindTransformFeedback_target_not_4);
+COMPILE_ASSERT(offsetof(BindTransformFeedback, transformfeedback) == 8,
+ OffsetOf_BindTransformFeedback_transformfeedback_not_8);
+
struct BlendColor {
typedef BlendColor ValueType;
static const CommandId kCmdId = kBlendColor;
@@ -1631,6 +1704,48 @@
COMPILE_ASSERT(offsetof(DeleteRenderbuffersImmediate, n) == 4,
OffsetOf_DeleteRenderbuffersImmediate_n_not_4);
+struct DeleteSamplersImmediate {
+ typedef DeleteSamplersImmediate ValueType;
+ static const CommandId kCmdId = kDeleteSamplersImmediate;
+ static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeDataSize(GLsizei n) {
+ return static_cast<uint32_t>(sizeof(GLuint) * n); // NOLINT
+ }
+
+ static uint32_t ComputeSize(GLsizei n) {
+ return static_cast<uint32_t>(sizeof(ValueType) +
+ ComputeDataSize(n)); // NOLINT
+ }
+
+ void SetHeader(GLsizei n) {
+ header.SetCmdByTotalSize<ValueType>(ComputeSize(n));
+ }
+
+ void Init(GLsizei _n, const GLuint* _samplers) {
+ SetHeader(_n);
+ n = _n;
+ memcpy(ImmediateDataAddress(this), _samplers, ComputeDataSize(_n));
+ }
+
+ void* Set(void* cmd, GLsizei _n, const GLuint* _samplers) {
+ static_cast<ValueType*>(cmd)->Init(_n, _samplers);
+ const uint32_t size = ComputeSize(_n);
+ return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
+ }
+
+ gpu::CommandHeader header;
+ int32_t n;
+};
+
+COMPILE_ASSERT(sizeof(DeleteSamplersImmediate) == 8,
+ Sizeof_DeleteSamplersImmediate_is_not_8);
+COMPILE_ASSERT(offsetof(DeleteSamplersImmediate, header) == 0,
+ OffsetOf_DeleteSamplersImmediate_header_not_0);
+COMPILE_ASSERT(offsetof(DeleteSamplersImmediate, n) == 4,
+ OffsetOf_DeleteSamplersImmediate_n_not_4);
+
struct DeleteShader {
typedef DeleteShader ValueType;
static const CommandId kCmdId = kDeleteShader;
@@ -1705,6 +1820,48 @@
COMPILE_ASSERT(offsetof(DeleteTexturesImmediate, n) == 4,
OffsetOf_DeleteTexturesImmediate_n_not_4);
+struct DeleteTransformFeedbacksImmediate {
+ typedef DeleteTransformFeedbacksImmediate ValueType;
+ static const CommandId kCmdId = kDeleteTransformFeedbacksImmediate;
+ static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeDataSize(GLsizei n) {
+ return static_cast<uint32_t>(sizeof(GLuint) * n); // NOLINT
+ }
+
+ static uint32_t ComputeSize(GLsizei n) {
+ return static_cast<uint32_t>(sizeof(ValueType) +
+ ComputeDataSize(n)); // NOLINT
+ }
+
+ void SetHeader(GLsizei n) {
+ header.SetCmdByTotalSize<ValueType>(ComputeSize(n));
+ }
+
+ void Init(GLsizei _n, const GLuint* _ids) {
+ SetHeader(_n);
+ n = _n;
+ memcpy(ImmediateDataAddress(this), _ids, ComputeDataSize(_n));
+ }
+
+ void* Set(void* cmd, GLsizei _n, const GLuint* _ids) {
+ static_cast<ValueType*>(cmd)->Init(_n, _ids);
+ const uint32_t size = ComputeSize(_n);
+ return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
+ }
+
+ gpu::CommandHeader header;
+ int32_t n;
+};
+
+COMPILE_ASSERT(sizeof(DeleteTransformFeedbacksImmediate) == 8,
+ Sizeof_DeleteTransformFeedbacksImmediate_is_not_8);
+COMPILE_ASSERT(offsetof(DeleteTransformFeedbacksImmediate, header) == 0,
+ OffsetOf_DeleteTransformFeedbacksImmediate_header_not_0);
+COMPILE_ASSERT(offsetof(DeleteTransformFeedbacksImmediate, n) == 4,
+ OffsetOf_DeleteTransformFeedbacksImmediate_n_not_4);
+
struct DepthFunc {
typedef DepthFunc ValueType;
static const CommandId kCmdId = kDepthFunc;
@@ -2457,6 +2614,48 @@
COMPILE_ASSERT(offsetof(GenRenderbuffersImmediate, n) == 4,
OffsetOf_GenRenderbuffersImmediate_n_not_4);
+struct GenSamplersImmediate {
+ typedef GenSamplersImmediate ValueType;
+ static const CommandId kCmdId = kGenSamplersImmediate;
+ static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeDataSize(GLsizei n) {
+ return static_cast<uint32_t>(sizeof(GLuint) * n); // NOLINT
+ }
+
+ static uint32_t ComputeSize(GLsizei n) {
+ return static_cast<uint32_t>(sizeof(ValueType) +
+ ComputeDataSize(n)); // NOLINT
+ }
+
+ void SetHeader(GLsizei n) {
+ header.SetCmdByTotalSize<ValueType>(ComputeSize(n));
+ }
+
+ void Init(GLsizei _n, GLuint* _samplers) {
+ SetHeader(_n);
+ n = _n;
+ memcpy(ImmediateDataAddress(this), _samplers, ComputeDataSize(_n));
+ }
+
+ void* Set(void* cmd, GLsizei _n, GLuint* _samplers) {
+ static_cast<ValueType*>(cmd)->Init(_n, _samplers);
+ const uint32_t size = ComputeSize(_n);
+ return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
+ }
+
+ gpu::CommandHeader header;
+ int32_t n;
+};
+
+COMPILE_ASSERT(sizeof(GenSamplersImmediate) == 8,
+ Sizeof_GenSamplersImmediate_is_not_8);
+COMPILE_ASSERT(offsetof(GenSamplersImmediate, header) == 0,
+ OffsetOf_GenSamplersImmediate_header_not_0);
+COMPILE_ASSERT(offsetof(GenSamplersImmediate, n) == 4,
+ OffsetOf_GenSamplersImmediate_n_not_4);
+
struct GenTexturesImmediate {
typedef GenTexturesImmediate ValueType;
static const CommandId kCmdId = kGenTexturesImmediate;
@@ -2499,6 +2698,48 @@
COMPILE_ASSERT(offsetof(GenTexturesImmediate, n) == 4,
OffsetOf_GenTexturesImmediate_n_not_4);
+struct GenTransformFeedbacksImmediate {
+ typedef GenTransformFeedbacksImmediate ValueType;
+ static const CommandId kCmdId = kGenTransformFeedbacksImmediate;
+ static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeDataSize(GLsizei n) {
+ return static_cast<uint32_t>(sizeof(GLuint) * n); // NOLINT
+ }
+
+ static uint32_t ComputeSize(GLsizei n) {
+ return static_cast<uint32_t>(sizeof(ValueType) +
+ ComputeDataSize(n)); // NOLINT
+ }
+
+ void SetHeader(GLsizei n) {
+ header.SetCmdByTotalSize<ValueType>(ComputeSize(n));
+ }
+
+ void Init(GLsizei _n, GLuint* _ids) {
+ SetHeader(_n);
+ n = _n;
+ memcpy(ImmediateDataAddress(this), _ids, ComputeDataSize(_n));
+ }
+
+ void* Set(void* cmd, GLsizei _n, GLuint* _ids) {
+ static_cast<ValueType*>(cmd)->Init(_n, _ids);
+ const uint32_t size = ComputeSize(_n);
+ return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
+ }
+
+ gpu::CommandHeader header;
+ int32_t n;
+};
+
+COMPILE_ASSERT(sizeof(GenTransformFeedbacksImmediate) == 8,
+ Sizeof_GenTransformFeedbacksImmediate_is_not_8);
+COMPILE_ASSERT(offsetof(GenTransformFeedbacksImmediate, header) == 0,
+ OffsetOf_GenTransformFeedbacksImmediate_header_not_0);
+COMPILE_ASSERT(offsetof(GenTransformFeedbacksImmediate, n) == 4,
+ OffsetOf_GenTransformFeedbacksImmediate_n_not_4);
+
struct GetActiveAttrib {
typedef GetActiveAttrib ValueType;
static const CommandId kCmdId = kGetActiveAttrib;
@@ -3261,6 +3502,116 @@
COMPILE_ASSERT(offsetof(GetRenderbufferParameteriv, params_shm_offset) == 16,
OffsetOf_GetRenderbufferParameteriv_params_shm_offset_not_16);
+struct GetSamplerParameterfv {
+ typedef GetSamplerParameterfv ValueType;
+ static const CommandId kCmdId = kGetSamplerParameterfv;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ typedef SizedResult<GLfloat> Result;
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLuint _sampler,
+ GLenum _pname,
+ uint32_t _params_shm_id,
+ uint32_t _params_shm_offset) {
+ SetHeader();
+ sampler = _sampler;
+ pname = _pname;
+ params_shm_id = _params_shm_id;
+ params_shm_offset = _params_shm_offset;
+ }
+
+ void* Set(void* cmd,
+ GLuint _sampler,
+ GLenum _pname,
+ uint32_t _params_shm_id,
+ uint32_t _params_shm_offset) {
+ static_cast<ValueType*>(cmd)
+ ->Init(_sampler, _pname, _params_shm_id, _params_shm_offset);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t sampler;
+ uint32_t pname;
+ uint32_t params_shm_id;
+ uint32_t params_shm_offset;
+};
+
+COMPILE_ASSERT(sizeof(GetSamplerParameterfv) == 20,
+ Sizeof_GetSamplerParameterfv_is_not_20);
+COMPILE_ASSERT(offsetof(GetSamplerParameterfv, header) == 0,
+ OffsetOf_GetSamplerParameterfv_header_not_0);
+COMPILE_ASSERT(offsetof(GetSamplerParameterfv, sampler) == 4,
+ OffsetOf_GetSamplerParameterfv_sampler_not_4);
+COMPILE_ASSERT(offsetof(GetSamplerParameterfv, pname) == 8,
+ OffsetOf_GetSamplerParameterfv_pname_not_8);
+COMPILE_ASSERT(offsetof(GetSamplerParameterfv, params_shm_id) == 12,
+ OffsetOf_GetSamplerParameterfv_params_shm_id_not_12);
+COMPILE_ASSERT(offsetof(GetSamplerParameterfv, params_shm_offset) == 16,
+ OffsetOf_GetSamplerParameterfv_params_shm_offset_not_16);
+
+struct GetSamplerParameteriv {
+ typedef GetSamplerParameteriv ValueType;
+ static const CommandId kCmdId = kGetSamplerParameteriv;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ typedef SizedResult<GLint> Result;
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLuint _sampler,
+ GLenum _pname,
+ uint32_t _params_shm_id,
+ uint32_t _params_shm_offset) {
+ SetHeader();
+ sampler = _sampler;
+ pname = _pname;
+ params_shm_id = _params_shm_id;
+ params_shm_offset = _params_shm_offset;
+ }
+
+ void* Set(void* cmd,
+ GLuint _sampler,
+ GLenum _pname,
+ uint32_t _params_shm_id,
+ uint32_t _params_shm_offset) {
+ static_cast<ValueType*>(cmd)
+ ->Init(_sampler, _pname, _params_shm_id, _params_shm_offset);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t sampler;
+ uint32_t pname;
+ uint32_t params_shm_id;
+ uint32_t params_shm_offset;
+};
+
+COMPILE_ASSERT(sizeof(GetSamplerParameteriv) == 20,
+ Sizeof_GetSamplerParameteriv_is_not_20);
+COMPILE_ASSERT(offsetof(GetSamplerParameteriv, header) == 0,
+ OffsetOf_GetSamplerParameteriv_header_not_0);
+COMPILE_ASSERT(offsetof(GetSamplerParameteriv, sampler) == 4,
+ OffsetOf_GetSamplerParameteriv_sampler_not_4);
+COMPILE_ASSERT(offsetof(GetSamplerParameteriv, pname) == 8,
+ OffsetOf_GetSamplerParameteriv_pname_not_8);
+COMPILE_ASSERT(offsetof(GetSamplerParameteriv, params_shm_id) == 12,
+ OffsetOf_GetSamplerParameteriv_params_shm_id_not_12);
+COMPILE_ASSERT(offsetof(GetSamplerParameteriv, params_shm_offset) == 16,
+ OffsetOf_GetSamplerParameteriv_params_shm_offset_not_16);
+
struct GetShaderiv {
typedef GetShaderiv ValueType;
static const CommandId kCmdId = kGetShaderiv;
@@ -4322,6 +4673,54 @@
COMPILE_ASSERT(offsetof(IsRenderbuffer, result_shm_offset) == 12,
OffsetOf_IsRenderbuffer_result_shm_offset_not_12);
+struct IsSampler {
+ typedef IsSampler ValueType;
+ static const CommandId kCmdId = kIsSampler;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ typedef uint32_t Result;
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLuint _sampler,
+ uint32_t _result_shm_id,
+ uint32_t _result_shm_offset) {
+ SetHeader();
+ sampler = _sampler;
+ result_shm_id = _result_shm_id;
+ result_shm_offset = _result_shm_offset;
+ }
+
+ void* Set(void* cmd,
+ GLuint _sampler,
+ uint32_t _result_shm_id,
+ uint32_t _result_shm_offset) {
+ static_cast<ValueType*>(cmd)
+ ->Init(_sampler, _result_shm_id, _result_shm_offset);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t sampler;
+ uint32_t result_shm_id;
+ uint32_t result_shm_offset;
+};
+
+COMPILE_ASSERT(sizeof(IsSampler) == 16, Sizeof_IsSampler_is_not_16);
+COMPILE_ASSERT(offsetof(IsSampler, header) == 0,
+ OffsetOf_IsSampler_header_not_0);
+COMPILE_ASSERT(offsetof(IsSampler, sampler) == 4,
+ OffsetOf_IsSampler_sampler_not_4);
+COMPILE_ASSERT(offsetof(IsSampler, result_shm_id) == 8,
+ OffsetOf_IsSampler_result_shm_id_not_8);
+COMPILE_ASSERT(offsetof(IsSampler, result_shm_offset) == 12,
+ OffsetOf_IsSampler_result_shm_offset_not_12);
+
struct IsShader {
typedef IsShader ValueType;
static const CommandId kCmdId = kIsShader;
@@ -4416,6 +4815,55 @@
COMPILE_ASSERT(offsetof(IsTexture, result_shm_offset) == 12,
OffsetOf_IsTexture_result_shm_offset_not_12);
+struct IsTransformFeedback {
+ typedef IsTransformFeedback ValueType;
+ static const CommandId kCmdId = kIsTransformFeedback;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ typedef uint32_t Result;
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLuint _transformfeedback,
+ uint32_t _result_shm_id,
+ uint32_t _result_shm_offset) {
+ SetHeader();
+ transformfeedback = _transformfeedback;
+ result_shm_id = _result_shm_id;
+ result_shm_offset = _result_shm_offset;
+ }
+
+ void* Set(void* cmd,
+ GLuint _transformfeedback,
+ uint32_t _result_shm_id,
+ uint32_t _result_shm_offset) {
+ static_cast<ValueType*>(cmd)
+ ->Init(_transformfeedback, _result_shm_id, _result_shm_offset);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t transformfeedback;
+ uint32_t result_shm_id;
+ uint32_t result_shm_offset;
+};
+
+COMPILE_ASSERT(sizeof(IsTransformFeedback) == 16,
+ Sizeof_IsTransformFeedback_is_not_16);
+COMPILE_ASSERT(offsetof(IsTransformFeedback, header) == 0,
+ OffsetOf_IsTransformFeedback_header_not_0);
+COMPILE_ASSERT(offsetof(IsTransformFeedback, transformfeedback) == 4,
+ OffsetOf_IsTransformFeedback_transformfeedback_not_4);
+COMPILE_ASSERT(offsetof(IsTransformFeedback, result_shm_id) == 8,
+ OffsetOf_IsTransformFeedback_result_shm_id_not_8);
+COMPILE_ASSERT(offsetof(IsTransformFeedback, result_shm_offset) == 12,
+ OffsetOf_IsTransformFeedback_result_shm_offset_not_12);
+
struct LineWidth {
typedef LineWidth ValueType;
static const CommandId kCmdId = kLineWidth;
@@ -4479,6 +4927,33 @@
COMPILE_ASSERT(offsetof(LinkProgram, program) == 4,
OffsetOf_LinkProgram_program_not_4);
+struct PauseTransformFeedback {
+ typedef PauseTransformFeedback ValueType;
+ static const CommandId kCmdId = kPauseTransformFeedback;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init() { SetHeader(); }
+
+ void* Set(void* cmd) {
+ static_cast<ValueType*>(cmd)->Init();
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+};
+
+COMPILE_ASSERT(sizeof(PauseTransformFeedback) == 4,
+ Sizeof_PauseTransformFeedback_is_not_4);
+COMPILE_ASSERT(offsetof(PauseTransformFeedback, header) == 0,
+ OffsetOf_PauseTransformFeedback_header_not_0);
+
struct PixelStorei {
typedef PixelStorei ValueType;
static const CommandId kCmdId = kPixelStorei;
@@ -4760,6 +5235,33 @@
COMPILE_ASSERT(offsetof(RenderbufferStorage, height) == 16,
OffsetOf_RenderbufferStorage_height_not_16);
+struct ResumeTransformFeedback {
+ typedef ResumeTransformFeedback ValueType;
+ static const CommandId kCmdId = kResumeTransformFeedback;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init() { SetHeader(); }
+
+ void* Set(void* cmd) {
+ static_cast<ValueType*>(cmd)->Init();
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+};
+
+COMPILE_ASSERT(sizeof(ResumeTransformFeedback) == 4,
+ Sizeof_ResumeTransformFeedback_is_not_4);
+COMPILE_ASSERT(offsetof(ResumeTransformFeedback, header) == 0,
+ OffsetOf_ResumeTransformFeedback_header_not_0);
+
struct SampleCoverage {
typedef SampleCoverage ValueType;
static const CommandId kCmdId = kSampleCoverage;
@@ -4796,6 +5298,176 @@
COMPILE_ASSERT(offsetof(SampleCoverage, invert) == 8,
OffsetOf_SampleCoverage_invert_not_8);
+struct SamplerParameterf {
+ typedef SamplerParameterf ValueType;
+ static const CommandId kCmdId = kSamplerParameterf;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLuint _sampler, GLenum _pname, GLfloat _param) {
+ SetHeader();
+ sampler = _sampler;
+ pname = _pname;
+ param = _param;
+ }
+
+ void* Set(void* cmd, GLuint _sampler, GLenum _pname, GLfloat _param) {
+ static_cast<ValueType*>(cmd)->Init(_sampler, _pname, _param);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t sampler;
+ uint32_t pname;
+ float param;
+};
+
+COMPILE_ASSERT(sizeof(SamplerParameterf) == 16,
+ Sizeof_SamplerParameterf_is_not_16);
+COMPILE_ASSERT(offsetof(SamplerParameterf, header) == 0,
+ OffsetOf_SamplerParameterf_header_not_0);
+COMPILE_ASSERT(offsetof(SamplerParameterf, sampler) == 4,
+ OffsetOf_SamplerParameterf_sampler_not_4);
+COMPILE_ASSERT(offsetof(SamplerParameterf, pname) == 8,
+ OffsetOf_SamplerParameterf_pname_not_8);
+COMPILE_ASSERT(offsetof(SamplerParameterf, param) == 12,
+ OffsetOf_SamplerParameterf_param_not_12);
+
+struct SamplerParameterfvImmediate {
+ typedef SamplerParameterfvImmediate ValueType;
+ static const CommandId kCmdId = kSamplerParameterfvImmediate;
+ static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeDataSize() {
+ return static_cast<uint32_t>(sizeof(GLfloat) * 1); // NOLINT
+ }
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType) +
+ ComputeDataSize()); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); }
+
+ void Init(GLuint _sampler, GLenum _pname, const GLfloat* _params) {
+ SetHeader();
+ sampler = _sampler;
+ pname = _pname;
+ memcpy(ImmediateDataAddress(this), _params, ComputeDataSize());
+ }
+
+ void* Set(void* cmd, GLuint _sampler, GLenum _pname, const GLfloat* _params) {
+ static_cast<ValueType*>(cmd)->Init(_sampler, _pname, _params);
+ const uint32_t size = ComputeSize();
+ return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t sampler;
+ uint32_t pname;
+};
+
+COMPILE_ASSERT(sizeof(SamplerParameterfvImmediate) == 12,
+ Sizeof_SamplerParameterfvImmediate_is_not_12);
+COMPILE_ASSERT(offsetof(SamplerParameterfvImmediate, header) == 0,
+ OffsetOf_SamplerParameterfvImmediate_header_not_0);
+COMPILE_ASSERT(offsetof(SamplerParameterfvImmediate, sampler) == 4,
+ OffsetOf_SamplerParameterfvImmediate_sampler_not_4);
+COMPILE_ASSERT(offsetof(SamplerParameterfvImmediate, pname) == 8,
+ OffsetOf_SamplerParameterfvImmediate_pname_not_8);
+
+struct SamplerParameteri {
+ typedef SamplerParameteri ValueType;
+ static const CommandId kCmdId = kSamplerParameteri;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLuint _sampler, GLenum _pname, GLint _param) {
+ SetHeader();
+ sampler = _sampler;
+ pname = _pname;
+ param = _param;
+ }
+
+ void* Set(void* cmd, GLuint _sampler, GLenum _pname, GLint _param) {
+ static_cast<ValueType*>(cmd)->Init(_sampler, _pname, _param);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t sampler;
+ uint32_t pname;
+ int32_t param;
+};
+
+COMPILE_ASSERT(sizeof(SamplerParameteri) == 16,
+ Sizeof_SamplerParameteri_is_not_16);
+COMPILE_ASSERT(offsetof(SamplerParameteri, header) == 0,
+ OffsetOf_SamplerParameteri_header_not_0);
+COMPILE_ASSERT(offsetof(SamplerParameteri, sampler) == 4,
+ OffsetOf_SamplerParameteri_sampler_not_4);
+COMPILE_ASSERT(offsetof(SamplerParameteri, pname) == 8,
+ OffsetOf_SamplerParameteri_pname_not_8);
+COMPILE_ASSERT(offsetof(SamplerParameteri, param) == 12,
+ OffsetOf_SamplerParameteri_param_not_12);
+
+struct SamplerParameterivImmediate {
+ typedef SamplerParameterivImmediate ValueType;
+ static const CommandId kCmdId = kSamplerParameterivImmediate;
+ static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeDataSize() {
+ return static_cast<uint32_t>(sizeof(GLint) * 1); // NOLINT
+ }
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType) +
+ ComputeDataSize()); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); }
+
+ void Init(GLuint _sampler, GLenum _pname, const GLint* _params) {
+ SetHeader();
+ sampler = _sampler;
+ pname = _pname;
+ memcpy(ImmediateDataAddress(this), _params, ComputeDataSize());
+ }
+
+ void* Set(void* cmd, GLuint _sampler, GLenum _pname, const GLint* _params) {
+ static_cast<ValueType*>(cmd)->Init(_sampler, _pname, _params);
+ const uint32_t size = ComputeSize();
+ return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t sampler;
+ uint32_t pname;
+};
+
+COMPILE_ASSERT(sizeof(SamplerParameterivImmediate) == 12,
+ Sizeof_SamplerParameterivImmediate_is_not_12);
+COMPILE_ASSERT(offsetof(SamplerParameterivImmediate, header) == 0,
+ OffsetOf_SamplerParameterivImmediate_header_not_0);
+COMPILE_ASSERT(offsetof(SamplerParameterivImmediate, sampler) == 4,
+ OffsetOf_SamplerParameterivImmediate_sampler_not_4);
+COMPILE_ASSERT(offsetof(SamplerParameterivImmediate, pname) == 8,
+ OffsetOf_SamplerParameterivImmediate_pname_not_8);
+
struct Scissor {
typedef Scissor ValueType;
static const CommandId kCmdId = kScissor;
@@ -8264,6 +8936,39 @@
COMPILE_ASSERT(offsetof(BeginQueryEXT, sync_data_shm_offset) == 16,
OffsetOf_BeginQueryEXT_sync_data_shm_offset_not_16);
+struct BeginTransformFeedback {
+ typedef BeginTransformFeedback ValueType;
+ static const CommandId kCmdId = kBeginTransformFeedback;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLenum _primitivemode) {
+ SetHeader();
+ primitivemode = _primitivemode;
+ }
+
+ void* Set(void* cmd, GLenum _primitivemode) {
+ static_cast<ValueType*>(cmd)->Init(_primitivemode);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t primitivemode;
+};
+
+COMPILE_ASSERT(sizeof(BeginTransformFeedback) == 8,
+ Sizeof_BeginTransformFeedback_is_not_8);
+COMPILE_ASSERT(offsetof(BeginTransformFeedback, header) == 0,
+ OffsetOf_BeginTransformFeedback_header_not_0);
+COMPILE_ASSERT(offsetof(BeginTransformFeedback, primitivemode) == 4,
+ OffsetOf_BeginTransformFeedback_primitivemode_not_4);
+
struct EndQueryEXT {
typedef EndQueryEXT ValueType;
static const CommandId kCmdId = kEndQueryEXT;
@@ -8300,6 +9005,33 @@
COMPILE_ASSERT(offsetof(EndQueryEXT, submit_count) == 8,
OffsetOf_EndQueryEXT_submit_count_not_8);
+struct EndTransformFeedback {
+ typedef EndTransformFeedback ValueType;
+ static const CommandId kCmdId = kEndTransformFeedback;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init() { SetHeader(); }
+
+ void* Set(void* cmd) {
+ static_cast<ValueType*>(cmd)->Init();
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+};
+
+COMPILE_ASSERT(sizeof(EndTransformFeedback) == 4,
+ Sizeof_EndTransformFeedback_is_not_4);
+COMPILE_ASSERT(offsetof(EndTransformFeedback, header) == 0,
+ OffsetOf_EndTransformFeedback_header_not_0);
+
struct InsertEventMarkerEXT {
typedef InsertEventMarkerEXT ValueType;
static const CommandId kCmdId = kInsertEventMarkerEXT;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index 49c108c..ca81047 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -86,6 +86,18 @@
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, BindSampler) {
+ cmds::BindSampler& cmd = *GetBufferAs<cmds::BindSampler>();
+ void* next_cmd =
+ cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::BindSampler::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint>(11), cmd.unit);
+ EXPECT_EQ(static_cast<GLuint>(12), cmd.sampler);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, BindTexture) {
cmds::BindTexture& cmd = *GetBufferAs<cmds::BindTexture>();
void* next_cmd =
@@ -98,6 +110,19 @@
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, BindTransformFeedback) {
+ cmds::BindTransformFeedback& cmd =
+ *GetBufferAs<cmds::BindTransformFeedback>();
+ void* next_cmd =
+ cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLuint>(12));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::BindTransformFeedback::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
+ EXPECT_EQ(static_cast<GLuint>(12), cmd.transformfeedback);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, BlendColor) {
cmds::BlendColor& cmd = *GetBufferAs<cmds::BlendColor>();
void* next_cmd =
@@ -518,6 +543,24 @@
// TODO(gman): Check that ids were inserted;
}
+TEST_F(GLES2FormatTest, DeleteSamplersImmediate) {
+ static GLuint ids[] = {
+ 12, 23, 34,
+ };
+ cmds::DeleteSamplersImmediate& cmd =
+ *GetBufferAs<cmds::DeleteSamplersImmediate>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
+ EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteSamplersImmediate::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
+ cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd,
+ sizeof(cmd) + RoundSizeToMultipleOfEntries(arraysize(ids) * 4u));
+ // TODO(gman): Check that ids were inserted;
+}
+
TEST_F(GLES2FormatTest, DeleteShader) {
cmds::DeleteShader& cmd = *GetBufferAs<cmds::DeleteShader>();
void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
@@ -546,6 +589,25 @@
// TODO(gman): Check that ids were inserted;
}
+TEST_F(GLES2FormatTest, DeleteTransformFeedbacksImmediate) {
+ static GLuint ids[] = {
+ 12, 23, 34,
+ };
+ cmds::DeleteTransformFeedbacksImmediate& cmd =
+ *GetBufferAs<cmds::DeleteTransformFeedbacksImmediate>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
+ EXPECT_EQ(
+ static_cast<uint32_t>(cmds::DeleteTransformFeedbacksImmediate::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
+ cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd,
+ sizeof(cmd) + RoundSizeToMultipleOfEntries(arraysize(ids) * 4u));
+ // TODO(gman): Check that ids were inserted;
+}
+
TEST_F(GLES2FormatTest, DepthFunc) {
cmds::DepthFunc& cmd = *GetBufferAs<cmds::DepthFunc>();
void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11));
@@ -792,6 +854,23 @@
// TODO(gman): Check that ids were inserted;
}
+TEST_F(GLES2FormatTest, GenSamplersImmediate) {
+ static GLuint ids[] = {
+ 12, 23, 34,
+ };
+ cmds::GenSamplersImmediate& cmd = *GetBufferAs<cmds::GenSamplersImmediate>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
+ EXPECT_EQ(static_cast<uint32_t>(cmds::GenSamplersImmediate::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
+ cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd,
+ sizeof(cmd) + RoundSizeToMultipleOfEntries(arraysize(ids) * 4u));
+ // TODO(gman): Check that ids were inserted;
+}
+
TEST_F(GLES2FormatTest, GenTexturesImmediate) {
static GLuint ids[] = {
12, 23, 34,
@@ -809,6 +888,24 @@
// TODO(gman): Check that ids were inserted;
}
+TEST_F(GLES2FormatTest, GenTransformFeedbacksImmediate) {
+ static GLuint ids[] = {
+ 12, 23, 34,
+ };
+ cmds::GenTransformFeedbacksImmediate& cmd =
+ *GetBufferAs<cmds::GenTransformFeedbacksImmediate>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
+ EXPECT_EQ(static_cast<uint32_t>(cmds::GenTransformFeedbacksImmediate::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
+ cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd,
+ sizeof(cmd) + RoundSizeToMultipleOfEntries(arraysize(ids) * 4u));
+ // TODO(gman): Check that ids were inserted;
+}
+
TEST_F(GLES2FormatTest, GetActiveAttrib) {
cmds::GetActiveAttrib& cmd = *GetBufferAs<cmds::GetActiveAttrib>();
void* next_cmd =
@@ -1020,6 +1117,38 @@
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, GetSamplerParameterfv) {
+ cmds::GetSamplerParameterfv& cmd =
+ *GetBufferAs<cmds::GetSamplerParameterfv>();
+ void* next_cmd =
+ cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12),
+ static_cast<uint32_t>(13), static_cast<uint32_t>(14));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::GetSamplerParameterfv::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler);
+ EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
+ EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+ EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
+TEST_F(GLES2FormatTest, GetSamplerParameteriv) {
+ cmds::GetSamplerParameteriv& cmd =
+ *GetBufferAs<cmds::GetSamplerParameteriv>();
+ void* next_cmd =
+ cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12),
+ static_cast<uint32_t>(13), static_cast<uint32_t>(14));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::GetSamplerParameteriv::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler);
+ EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
+ EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+ EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, GetShaderiv) {
cmds::GetShaderiv& cmd = *GetBufferAs<cmds::GetShaderiv>();
void* next_cmd =
@@ -1338,6 +1467,19 @@
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, IsSampler) {
+ cmds::IsSampler& cmd = *GetBufferAs<cmds::IsSampler>();
+ void* next_cmd =
+ cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12),
+ static_cast<uint32_t>(13));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::IsSampler::kCmdId), cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler);
+ EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+ EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, IsShader) {
cmds::IsShader& cmd = *GetBufferAs<cmds::IsShader>();
void* next_cmd =
@@ -1364,6 +1506,20 @@
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, IsTransformFeedback) {
+ cmds::IsTransformFeedback& cmd = *GetBufferAs<cmds::IsTransformFeedback>();
+ void* next_cmd =
+ cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12),
+ static_cast<uint32_t>(13));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::IsTransformFeedback::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint>(11), cmd.transformfeedback);
+ EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+ EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, LineWidth) {
cmds::LineWidth& cmd = *GetBufferAs<cmds::LineWidth>();
void* next_cmd = cmd.Set(&cmd, static_cast<GLfloat>(11));
@@ -1383,6 +1539,16 @@
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, PauseTransformFeedback) {
+ cmds::PauseTransformFeedback& cmd =
+ *GetBufferAs<cmds::PauseTransformFeedback>();
+ void* next_cmd = cmd.Set(&cmd);
+ EXPECT_EQ(static_cast<uint32_t>(cmds::PauseTransformFeedback::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, PixelStorei) {
cmds::PixelStorei& cmd = *GetBufferAs<cmds::PixelStorei>();
void* next_cmd =
@@ -1467,6 +1633,16 @@
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, ResumeTransformFeedback) {
+ cmds::ResumeTransformFeedback& cmd =
+ *GetBufferAs<cmds::ResumeTransformFeedback>();
+ void* next_cmd = cmd.Set(&cmd);
+ EXPECT_EQ(static_cast<uint32_t>(cmds::ResumeTransformFeedback::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, SampleCoverage) {
cmds::SampleCoverage& cmd = *GetBufferAs<cmds::SampleCoverage>();
void* next_cmd =
@@ -1479,6 +1655,72 @@
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, SamplerParameterf) {
+ cmds::SamplerParameterf& cmd = *GetBufferAs<cmds::SamplerParameterf>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11),
+ static_cast<GLenum>(12), static_cast<GLfloat>(13));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::SamplerParameterf::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler);
+ EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
+ EXPECT_EQ(static_cast<GLfloat>(13), cmd.param);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
+TEST_F(GLES2FormatTest, SamplerParameterfvImmediate) {
+ const int kSomeBaseValueToTestWith = 51;
+ static GLfloat data[] = {
+ static_cast<GLfloat>(kSomeBaseValueToTestWith + 0),
+ };
+ cmds::SamplerParameterfvImmediate& cmd =
+ *GetBufferAs<cmds::SamplerParameterfvImmediate>();
+ void* next_cmd =
+ cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12), data);
+ EXPECT_EQ(static_cast<uint32_t>(cmds::SamplerParameterfvImmediate::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)),
+ cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler);
+ EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)));
+ // TODO(gman): Check that data was inserted;
+}
+
+TEST_F(GLES2FormatTest, SamplerParameteri) {
+ cmds::SamplerParameteri& cmd = *GetBufferAs<cmds::SamplerParameteri>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11),
+ static_cast<GLenum>(12), static_cast<GLint>(13));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::SamplerParameteri::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler);
+ EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
+ EXPECT_EQ(static_cast<GLint>(13), cmd.param);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
+TEST_F(GLES2FormatTest, SamplerParameterivImmediate) {
+ const int kSomeBaseValueToTestWith = 51;
+ static GLint data[] = {
+ static_cast<GLint>(kSomeBaseValueToTestWith + 0),
+ };
+ cmds::SamplerParameterivImmediate& cmd =
+ *GetBufferAs<cmds::SamplerParameterivImmediate>();
+ void* next_cmd =
+ cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12), data);
+ EXPECT_EQ(static_cast<uint32_t>(cmds::SamplerParameterivImmediate::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)),
+ cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint>(11), cmd.sampler);
+ EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)));
+ // TODO(gman): Check that data was inserted;
+}
+
TEST_F(GLES2FormatTest, Scissor) {
cmds::Scissor& cmd = *GetBufferAs<cmds::Scissor>();
void* next_cmd = cmd.Set(&cmd, static_cast<GLint>(11), static_cast<GLint>(12),
@@ -2962,6 +3204,17 @@
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, BeginTransformFeedback) {
+ cmds::BeginTransformFeedback& cmd =
+ *GetBufferAs<cmds::BeginTransformFeedback>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::BeginTransformFeedback::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLenum>(11), cmd.primitivemode);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, EndQueryEXT) {
cmds::EndQueryEXT& cmd = *GetBufferAs<cmds::EndQueryEXT>();
void* next_cmd =
@@ -2974,6 +3227,15 @@
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, EndTransformFeedback) {
+ cmds::EndTransformFeedback& cmd = *GetBufferAs<cmds::EndTransformFeedback>();
+ void* next_cmd = cmd.Set(&cmd);
+ EXPECT_EQ(static_cast<uint32_t>(cmds::EndTransformFeedback::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, InsertEventMarkerEXT) {
cmds::InsertEventMarkerEXT& cmd = *GetBufferAs<cmds::InsertEventMarkerEXT>();
void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index 4fe80f8..34957e4 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -18,232 +18,250 @@
OP(BindBuffer) /* 259 */ \
OP(BindFramebuffer) /* 260 */ \
OP(BindRenderbuffer) /* 261 */ \
- OP(BindTexture) /* 262 */ \
- OP(BlendColor) /* 263 */ \
- OP(BlendEquation) /* 264 */ \
- OP(BlendEquationSeparate) /* 265 */ \
- OP(BlendFunc) /* 266 */ \
- OP(BlendFuncSeparate) /* 267 */ \
- OP(BufferData) /* 268 */ \
- OP(BufferSubData) /* 269 */ \
- OP(CheckFramebufferStatus) /* 270 */ \
- OP(Clear) /* 271 */ \
- OP(ClearColor) /* 272 */ \
- OP(ClearDepthf) /* 273 */ \
- OP(ClearStencil) /* 274 */ \
- OP(ColorMask) /* 275 */ \
- OP(CompileShader) /* 276 */ \
- OP(CompressedTexImage2DBucket) /* 277 */ \
- OP(CompressedTexImage2D) /* 278 */ \
- OP(CompressedTexSubImage2DBucket) /* 279 */ \
- OP(CompressedTexSubImage2D) /* 280 */ \
- OP(CopyBufferSubData) /* 281 */ \
- OP(CopyTexImage2D) /* 282 */ \
- OP(CopyTexSubImage2D) /* 283 */ \
- OP(CreateProgram) /* 284 */ \
- OP(CreateShader) /* 285 */ \
- OP(CullFace) /* 286 */ \
- OP(DeleteBuffersImmediate) /* 287 */ \
- OP(DeleteFramebuffersImmediate) /* 288 */ \
- OP(DeleteProgram) /* 289 */ \
- OP(DeleteRenderbuffersImmediate) /* 290 */ \
- OP(DeleteShader) /* 291 */ \
- OP(DeleteTexturesImmediate) /* 292 */ \
- OP(DepthFunc) /* 293 */ \
- OP(DepthMask) /* 294 */ \
- OP(DepthRangef) /* 295 */ \
- OP(DetachShader) /* 296 */ \
- OP(Disable) /* 297 */ \
- OP(DisableVertexAttribArray) /* 298 */ \
- OP(DrawArrays) /* 299 */ \
- OP(DrawElements) /* 300 */ \
- OP(Enable) /* 301 */ \
- OP(EnableVertexAttribArray) /* 302 */ \
- OP(Finish) /* 303 */ \
- OP(Flush) /* 304 */ \
- OP(FramebufferRenderbuffer) /* 305 */ \
- OP(FramebufferTexture2D) /* 306 */ \
- OP(FramebufferTextureLayer) /* 307 */ \
- OP(FrontFace) /* 308 */ \
- OP(GenBuffersImmediate) /* 309 */ \
- OP(GenerateMipmap) /* 310 */ \
- OP(GenFramebuffersImmediate) /* 311 */ \
- OP(GenRenderbuffersImmediate) /* 312 */ \
- OP(GenTexturesImmediate) /* 313 */ \
- OP(GetActiveAttrib) /* 314 */ \
- OP(GetActiveUniform) /* 315 */ \
- OP(GetAttachedShaders) /* 316 */ \
- OP(GetAttribLocation) /* 317 */ \
- OP(GetBooleanv) /* 318 */ \
- OP(GetBufferParameteriv) /* 319 */ \
- OP(GetError) /* 320 */ \
- OP(GetFloatv) /* 321 */ \
- OP(GetFramebufferAttachmentParameteriv) /* 322 */ \
- OP(GetIntegerv) /* 323 */ \
- OP(GetInternalformativ) /* 324 */ \
- OP(GetProgramiv) /* 325 */ \
- OP(GetProgramInfoLog) /* 326 */ \
- OP(GetRenderbufferParameteriv) /* 327 */ \
- OP(GetShaderiv) /* 328 */ \
- OP(GetShaderInfoLog) /* 329 */ \
- OP(GetShaderPrecisionFormat) /* 330 */ \
- OP(GetShaderSource) /* 331 */ \
- OP(GetString) /* 332 */ \
- OP(GetTexParameterfv) /* 333 */ \
- OP(GetTexParameteriv) /* 334 */ \
- OP(GetUniformfv) /* 335 */ \
- OP(GetUniformiv) /* 336 */ \
- OP(GetUniformLocation) /* 337 */ \
- OP(GetVertexAttribfv) /* 338 */ \
- OP(GetVertexAttribiv) /* 339 */ \
- OP(GetVertexAttribPointerv) /* 340 */ \
- OP(Hint) /* 341 */ \
- OP(InvalidateFramebufferImmediate) /* 342 */ \
- OP(InvalidateSubFramebufferImmediate) /* 343 */ \
- OP(IsBuffer) /* 344 */ \
- OP(IsEnabled) /* 345 */ \
- OP(IsFramebuffer) /* 346 */ \
- OP(IsProgram) /* 347 */ \
- OP(IsRenderbuffer) /* 348 */ \
- OP(IsShader) /* 349 */ \
- OP(IsTexture) /* 350 */ \
- OP(LineWidth) /* 351 */ \
- OP(LinkProgram) /* 352 */ \
- OP(PixelStorei) /* 353 */ \
- OP(PolygonOffset) /* 354 */ \
- OP(ReadBuffer) /* 355 */ \
- OP(ReadPixels) /* 356 */ \
- OP(ReleaseShaderCompiler) /* 357 */ \
- OP(RenderbufferStorage) /* 358 */ \
- OP(SampleCoverage) /* 359 */ \
- OP(Scissor) /* 360 */ \
- OP(ShaderBinary) /* 361 */ \
- OP(ShaderSourceBucket) /* 362 */ \
- OP(StencilFunc) /* 363 */ \
- OP(StencilFuncSeparate) /* 364 */ \
- OP(StencilMask) /* 365 */ \
- OP(StencilMaskSeparate) /* 366 */ \
- OP(StencilOp) /* 367 */ \
- OP(StencilOpSeparate) /* 368 */ \
- OP(TexImage2D) /* 369 */ \
- OP(TexParameterf) /* 370 */ \
- OP(TexParameterfvImmediate) /* 371 */ \
- OP(TexParameteri) /* 372 */ \
- OP(TexParameterivImmediate) /* 373 */ \
- OP(TexStorage3D) /* 374 */ \
- OP(TexSubImage2D) /* 375 */ \
- OP(Uniform1f) /* 376 */ \
- OP(Uniform1fvImmediate) /* 377 */ \
- OP(Uniform1i) /* 378 */ \
- OP(Uniform1ivImmediate) /* 379 */ \
- OP(Uniform1ui) /* 380 */ \
- OP(Uniform1uivImmediate) /* 381 */ \
- OP(Uniform2f) /* 382 */ \
- OP(Uniform2fvImmediate) /* 383 */ \
- OP(Uniform2i) /* 384 */ \
- OP(Uniform2ivImmediate) /* 385 */ \
- OP(Uniform2ui) /* 386 */ \
- OP(Uniform2uivImmediate) /* 387 */ \
- OP(Uniform3f) /* 388 */ \
- OP(Uniform3fvImmediate) /* 389 */ \
- OP(Uniform3i) /* 390 */ \
- OP(Uniform3ivImmediate) /* 391 */ \
- OP(Uniform3ui) /* 392 */ \
- OP(Uniform3uivImmediate) /* 393 */ \
- OP(Uniform4f) /* 394 */ \
- OP(Uniform4fvImmediate) /* 395 */ \
- OP(Uniform4i) /* 396 */ \
- OP(Uniform4ivImmediate) /* 397 */ \
- OP(Uniform4ui) /* 398 */ \
- OP(Uniform4uivImmediate) /* 399 */ \
- OP(UniformMatrix2fvImmediate) /* 400 */ \
- OP(UniformMatrix2x3fvImmediate) /* 401 */ \
- OP(UniformMatrix2x4fvImmediate) /* 402 */ \
- OP(UniformMatrix3fvImmediate) /* 403 */ \
- OP(UniformMatrix3x2fvImmediate) /* 404 */ \
- OP(UniformMatrix3x4fvImmediate) /* 405 */ \
- OP(UniformMatrix4fvImmediate) /* 406 */ \
- OP(UniformMatrix4x2fvImmediate) /* 407 */ \
- OP(UniformMatrix4x3fvImmediate) /* 408 */ \
- OP(UseProgram) /* 409 */ \
- OP(ValidateProgram) /* 410 */ \
- OP(VertexAttrib1f) /* 411 */ \
- OP(VertexAttrib1fvImmediate) /* 412 */ \
- OP(VertexAttrib2f) /* 413 */ \
- OP(VertexAttrib2fvImmediate) /* 414 */ \
- OP(VertexAttrib3f) /* 415 */ \
- OP(VertexAttrib3fvImmediate) /* 416 */ \
- OP(VertexAttrib4f) /* 417 */ \
- OP(VertexAttrib4fvImmediate) /* 418 */ \
- OP(VertexAttribI4i) /* 419 */ \
- OP(VertexAttribI4ivImmediate) /* 420 */ \
- OP(VertexAttribI4ui) /* 421 */ \
- OP(VertexAttribI4uivImmediate) /* 422 */ \
- OP(VertexAttribIPointer) /* 423 */ \
- OP(VertexAttribPointer) /* 424 */ \
- OP(Viewport) /* 425 */ \
- OP(BlitFramebufferCHROMIUM) /* 426 */ \
- OP(RenderbufferStorageMultisampleCHROMIUM) /* 427 */ \
- OP(RenderbufferStorageMultisampleEXT) /* 428 */ \
- OP(FramebufferTexture2DMultisampleEXT) /* 429 */ \
- OP(TexStorage2DEXT) /* 430 */ \
- OP(GenQueriesEXTImmediate) /* 431 */ \
- OP(DeleteQueriesEXTImmediate) /* 432 */ \
- OP(BeginQueryEXT) /* 433 */ \
- OP(EndQueryEXT) /* 434 */ \
- OP(InsertEventMarkerEXT) /* 435 */ \
- OP(PushGroupMarkerEXT) /* 436 */ \
- OP(PopGroupMarkerEXT) /* 437 */ \
- OP(GenVertexArraysOESImmediate) /* 438 */ \
- OP(DeleteVertexArraysOESImmediate) /* 439 */ \
- OP(IsVertexArrayOES) /* 440 */ \
- OP(BindVertexArrayOES) /* 441 */ \
- OP(SwapBuffers) /* 442 */ \
- OP(GetMaxValueInBufferCHROMIUM) /* 443 */ \
- OP(EnableFeatureCHROMIUM) /* 444 */ \
- OP(ResizeCHROMIUM) /* 445 */ \
- OP(GetRequestableExtensionsCHROMIUM) /* 446 */ \
- OP(RequestExtensionCHROMIUM) /* 447 */ \
- OP(GetProgramInfoCHROMIUM) /* 448 */ \
- OP(GetTranslatedShaderSourceANGLE) /* 449 */ \
- OP(PostSubBufferCHROMIUM) /* 450 */ \
- OP(TexImageIOSurface2DCHROMIUM) /* 451 */ \
- OP(CopyTextureCHROMIUM) /* 452 */ \
- OP(DrawArraysInstancedANGLE) /* 453 */ \
- OP(DrawElementsInstancedANGLE) /* 454 */ \
- OP(VertexAttribDivisorANGLE) /* 455 */ \
- OP(GenMailboxCHROMIUM) /* 456 */ \
- OP(ProduceTextureCHROMIUMImmediate) /* 457 */ \
- OP(ProduceTextureDirectCHROMIUMImmediate) /* 458 */ \
- OP(ConsumeTextureCHROMIUMImmediate) /* 459 */ \
- OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 460 */ \
- OP(BindUniformLocationCHROMIUMBucket) /* 461 */ \
- OP(GenValuebuffersCHROMIUMImmediate) /* 462 */ \
- OP(DeleteValuebuffersCHROMIUMImmediate) /* 463 */ \
- OP(IsValuebufferCHROMIUM) /* 464 */ \
- OP(BindValuebufferCHROMIUM) /* 465 */ \
- OP(SubscribeValueCHROMIUM) /* 466 */ \
- OP(PopulateSubscribedValuesCHROMIUM) /* 467 */ \
- OP(UniformValuebufferCHROMIUM) /* 468 */ \
- OP(BindTexImage2DCHROMIUM) /* 469 */ \
- OP(ReleaseTexImage2DCHROMIUM) /* 470 */ \
- OP(TraceBeginCHROMIUM) /* 471 */ \
- OP(TraceEndCHROMIUM) /* 472 */ \
- OP(AsyncTexSubImage2DCHROMIUM) /* 473 */ \
- OP(AsyncTexImage2DCHROMIUM) /* 474 */ \
- OP(WaitAsyncTexImage2DCHROMIUM) /* 475 */ \
- OP(WaitAllAsyncTexImage2DCHROMIUM) /* 476 */ \
- OP(DiscardFramebufferEXTImmediate) /* 477 */ \
- OP(LoseContextCHROMIUM) /* 478 */ \
- OP(InsertSyncPointCHROMIUM) /* 479 */ \
- OP(WaitSyncPointCHROMIUM) /* 480 */ \
- OP(DrawBuffersEXTImmediate) /* 481 */ \
- OP(DiscardBackbufferCHROMIUM) /* 482 */ \
- OP(ScheduleOverlayPlaneCHROMIUM) /* 483 */ \
- OP(SwapInterval) /* 484 */ \
- OP(MatrixLoadfCHROMIUMImmediate) /* 485 */ \
- OP(MatrixLoadIdentityCHROMIUM) /* 486 */ \
- OP(BlendBarrierKHR) /* 487 */
+ OP(BindSampler) /* 262 */ \
+ OP(BindTexture) /* 263 */ \
+ OP(BindTransformFeedback) /* 264 */ \
+ OP(BlendColor) /* 265 */ \
+ OP(BlendEquation) /* 266 */ \
+ OP(BlendEquationSeparate) /* 267 */ \
+ OP(BlendFunc) /* 268 */ \
+ OP(BlendFuncSeparate) /* 269 */ \
+ OP(BufferData) /* 270 */ \
+ OP(BufferSubData) /* 271 */ \
+ OP(CheckFramebufferStatus) /* 272 */ \
+ OP(Clear) /* 273 */ \
+ OP(ClearColor) /* 274 */ \
+ OP(ClearDepthf) /* 275 */ \
+ OP(ClearStencil) /* 276 */ \
+ OP(ColorMask) /* 277 */ \
+ OP(CompileShader) /* 278 */ \
+ OP(CompressedTexImage2DBucket) /* 279 */ \
+ OP(CompressedTexImage2D) /* 280 */ \
+ OP(CompressedTexSubImage2DBucket) /* 281 */ \
+ OP(CompressedTexSubImage2D) /* 282 */ \
+ OP(CopyBufferSubData) /* 283 */ \
+ OP(CopyTexImage2D) /* 284 */ \
+ OP(CopyTexSubImage2D) /* 285 */ \
+ OP(CreateProgram) /* 286 */ \
+ OP(CreateShader) /* 287 */ \
+ OP(CullFace) /* 288 */ \
+ OP(DeleteBuffersImmediate) /* 289 */ \
+ OP(DeleteFramebuffersImmediate) /* 290 */ \
+ OP(DeleteProgram) /* 291 */ \
+ OP(DeleteRenderbuffersImmediate) /* 292 */ \
+ OP(DeleteSamplersImmediate) /* 293 */ \
+ OP(DeleteShader) /* 294 */ \
+ OP(DeleteTexturesImmediate) /* 295 */ \
+ OP(DeleteTransformFeedbacksImmediate) /* 296 */ \
+ OP(DepthFunc) /* 297 */ \
+ OP(DepthMask) /* 298 */ \
+ OP(DepthRangef) /* 299 */ \
+ OP(DetachShader) /* 300 */ \
+ OP(Disable) /* 301 */ \
+ OP(DisableVertexAttribArray) /* 302 */ \
+ OP(DrawArrays) /* 303 */ \
+ OP(DrawElements) /* 304 */ \
+ OP(Enable) /* 305 */ \
+ OP(EnableVertexAttribArray) /* 306 */ \
+ OP(Finish) /* 307 */ \
+ OP(Flush) /* 308 */ \
+ OP(FramebufferRenderbuffer) /* 309 */ \
+ OP(FramebufferTexture2D) /* 310 */ \
+ OP(FramebufferTextureLayer) /* 311 */ \
+ OP(FrontFace) /* 312 */ \
+ OP(GenBuffersImmediate) /* 313 */ \
+ OP(GenerateMipmap) /* 314 */ \
+ OP(GenFramebuffersImmediate) /* 315 */ \
+ OP(GenRenderbuffersImmediate) /* 316 */ \
+ OP(GenSamplersImmediate) /* 317 */ \
+ OP(GenTexturesImmediate) /* 318 */ \
+ OP(GenTransformFeedbacksImmediate) /* 319 */ \
+ OP(GetActiveAttrib) /* 320 */ \
+ OP(GetActiveUniform) /* 321 */ \
+ OP(GetAttachedShaders) /* 322 */ \
+ OP(GetAttribLocation) /* 323 */ \
+ OP(GetBooleanv) /* 324 */ \
+ OP(GetBufferParameteriv) /* 325 */ \
+ OP(GetError) /* 326 */ \
+ OP(GetFloatv) /* 327 */ \
+ OP(GetFramebufferAttachmentParameteriv) /* 328 */ \
+ OP(GetIntegerv) /* 329 */ \
+ OP(GetInternalformativ) /* 330 */ \
+ OP(GetProgramiv) /* 331 */ \
+ OP(GetProgramInfoLog) /* 332 */ \
+ OP(GetRenderbufferParameteriv) /* 333 */ \
+ OP(GetSamplerParameterfv) /* 334 */ \
+ OP(GetSamplerParameteriv) /* 335 */ \
+ OP(GetShaderiv) /* 336 */ \
+ OP(GetShaderInfoLog) /* 337 */ \
+ OP(GetShaderPrecisionFormat) /* 338 */ \
+ OP(GetShaderSource) /* 339 */ \
+ OP(GetString) /* 340 */ \
+ OP(GetTexParameterfv) /* 341 */ \
+ OP(GetTexParameteriv) /* 342 */ \
+ OP(GetUniformfv) /* 343 */ \
+ OP(GetUniformiv) /* 344 */ \
+ OP(GetUniformLocation) /* 345 */ \
+ OP(GetVertexAttribfv) /* 346 */ \
+ OP(GetVertexAttribiv) /* 347 */ \
+ OP(GetVertexAttribPointerv) /* 348 */ \
+ OP(Hint) /* 349 */ \
+ OP(InvalidateFramebufferImmediate) /* 350 */ \
+ OP(InvalidateSubFramebufferImmediate) /* 351 */ \
+ OP(IsBuffer) /* 352 */ \
+ OP(IsEnabled) /* 353 */ \
+ OP(IsFramebuffer) /* 354 */ \
+ OP(IsProgram) /* 355 */ \
+ OP(IsRenderbuffer) /* 356 */ \
+ OP(IsSampler) /* 357 */ \
+ OP(IsShader) /* 358 */ \
+ OP(IsTexture) /* 359 */ \
+ OP(IsTransformFeedback) /* 360 */ \
+ OP(LineWidth) /* 361 */ \
+ OP(LinkProgram) /* 362 */ \
+ OP(PauseTransformFeedback) /* 363 */ \
+ OP(PixelStorei) /* 364 */ \
+ OP(PolygonOffset) /* 365 */ \
+ OP(ReadBuffer) /* 366 */ \
+ OP(ReadPixels) /* 367 */ \
+ OP(ReleaseShaderCompiler) /* 368 */ \
+ OP(RenderbufferStorage) /* 369 */ \
+ OP(ResumeTransformFeedback) /* 370 */ \
+ OP(SampleCoverage) /* 371 */ \
+ OP(SamplerParameterf) /* 372 */ \
+ OP(SamplerParameterfvImmediate) /* 373 */ \
+ OP(SamplerParameteri) /* 374 */ \
+ OP(SamplerParameterivImmediate) /* 375 */ \
+ OP(Scissor) /* 376 */ \
+ OP(ShaderBinary) /* 377 */ \
+ OP(ShaderSourceBucket) /* 378 */ \
+ OP(StencilFunc) /* 379 */ \
+ OP(StencilFuncSeparate) /* 380 */ \
+ OP(StencilMask) /* 381 */ \
+ OP(StencilMaskSeparate) /* 382 */ \
+ OP(StencilOp) /* 383 */ \
+ OP(StencilOpSeparate) /* 384 */ \
+ OP(TexImage2D) /* 385 */ \
+ OP(TexParameterf) /* 386 */ \
+ OP(TexParameterfvImmediate) /* 387 */ \
+ OP(TexParameteri) /* 388 */ \
+ OP(TexParameterivImmediate) /* 389 */ \
+ OP(TexStorage3D) /* 390 */ \
+ OP(TexSubImage2D) /* 391 */ \
+ OP(Uniform1f) /* 392 */ \
+ OP(Uniform1fvImmediate) /* 393 */ \
+ OP(Uniform1i) /* 394 */ \
+ OP(Uniform1ivImmediate) /* 395 */ \
+ OP(Uniform1ui) /* 396 */ \
+ OP(Uniform1uivImmediate) /* 397 */ \
+ OP(Uniform2f) /* 398 */ \
+ OP(Uniform2fvImmediate) /* 399 */ \
+ OP(Uniform2i) /* 400 */ \
+ OP(Uniform2ivImmediate) /* 401 */ \
+ OP(Uniform2ui) /* 402 */ \
+ OP(Uniform2uivImmediate) /* 403 */ \
+ OP(Uniform3f) /* 404 */ \
+ OP(Uniform3fvImmediate) /* 405 */ \
+ OP(Uniform3i) /* 406 */ \
+ OP(Uniform3ivImmediate) /* 407 */ \
+ OP(Uniform3ui) /* 408 */ \
+ OP(Uniform3uivImmediate) /* 409 */ \
+ OP(Uniform4f) /* 410 */ \
+ OP(Uniform4fvImmediate) /* 411 */ \
+ OP(Uniform4i) /* 412 */ \
+ OP(Uniform4ivImmediate) /* 413 */ \
+ OP(Uniform4ui) /* 414 */ \
+ OP(Uniform4uivImmediate) /* 415 */ \
+ OP(UniformMatrix2fvImmediate) /* 416 */ \
+ OP(UniformMatrix2x3fvImmediate) /* 417 */ \
+ OP(UniformMatrix2x4fvImmediate) /* 418 */ \
+ OP(UniformMatrix3fvImmediate) /* 419 */ \
+ OP(UniformMatrix3x2fvImmediate) /* 420 */ \
+ OP(UniformMatrix3x4fvImmediate) /* 421 */ \
+ OP(UniformMatrix4fvImmediate) /* 422 */ \
+ OP(UniformMatrix4x2fvImmediate) /* 423 */ \
+ OP(UniformMatrix4x3fvImmediate) /* 424 */ \
+ OP(UseProgram) /* 425 */ \
+ OP(ValidateProgram) /* 426 */ \
+ OP(VertexAttrib1f) /* 427 */ \
+ OP(VertexAttrib1fvImmediate) /* 428 */ \
+ OP(VertexAttrib2f) /* 429 */ \
+ OP(VertexAttrib2fvImmediate) /* 430 */ \
+ OP(VertexAttrib3f) /* 431 */ \
+ OP(VertexAttrib3fvImmediate) /* 432 */ \
+ OP(VertexAttrib4f) /* 433 */ \
+ OP(VertexAttrib4fvImmediate) /* 434 */ \
+ OP(VertexAttribI4i) /* 435 */ \
+ OP(VertexAttribI4ivImmediate) /* 436 */ \
+ OP(VertexAttribI4ui) /* 437 */ \
+ OP(VertexAttribI4uivImmediate) /* 438 */ \
+ OP(VertexAttribIPointer) /* 439 */ \
+ OP(VertexAttribPointer) /* 440 */ \
+ OP(Viewport) /* 441 */ \
+ OP(BlitFramebufferCHROMIUM) /* 442 */ \
+ OP(RenderbufferStorageMultisampleCHROMIUM) /* 443 */ \
+ OP(RenderbufferStorageMultisampleEXT) /* 444 */ \
+ OP(FramebufferTexture2DMultisampleEXT) /* 445 */ \
+ OP(TexStorage2DEXT) /* 446 */ \
+ OP(GenQueriesEXTImmediate) /* 447 */ \
+ OP(DeleteQueriesEXTImmediate) /* 448 */ \
+ OP(BeginQueryEXT) /* 449 */ \
+ OP(BeginTransformFeedback) /* 450 */ \
+ OP(EndQueryEXT) /* 451 */ \
+ OP(EndTransformFeedback) /* 452 */ \
+ OP(InsertEventMarkerEXT) /* 453 */ \
+ OP(PushGroupMarkerEXT) /* 454 */ \
+ OP(PopGroupMarkerEXT) /* 455 */ \
+ OP(GenVertexArraysOESImmediate) /* 456 */ \
+ OP(DeleteVertexArraysOESImmediate) /* 457 */ \
+ OP(IsVertexArrayOES) /* 458 */ \
+ OP(BindVertexArrayOES) /* 459 */ \
+ OP(SwapBuffers) /* 460 */ \
+ OP(GetMaxValueInBufferCHROMIUM) /* 461 */ \
+ OP(EnableFeatureCHROMIUM) /* 462 */ \
+ OP(ResizeCHROMIUM) /* 463 */ \
+ OP(GetRequestableExtensionsCHROMIUM) /* 464 */ \
+ OP(RequestExtensionCHROMIUM) /* 465 */ \
+ OP(GetProgramInfoCHROMIUM) /* 466 */ \
+ OP(GetTranslatedShaderSourceANGLE) /* 467 */ \
+ OP(PostSubBufferCHROMIUM) /* 468 */ \
+ OP(TexImageIOSurface2DCHROMIUM) /* 469 */ \
+ OP(CopyTextureCHROMIUM) /* 470 */ \
+ OP(DrawArraysInstancedANGLE) /* 471 */ \
+ OP(DrawElementsInstancedANGLE) /* 472 */ \
+ OP(VertexAttribDivisorANGLE) /* 473 */ \
+ OP(GenMailboxCHROMIUM) /* 474 */ \
+ OP(ProduceTextureCHROMIUMImmediate) /* 475 */ \
+ OP(ProduceTextureDirectCHROMIUMImmediate) /* 476 */ \
+ OP(ConsumeTextureCHROMIUMImmediate) /* 477 */ \
+ OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 478 */ \
+ OP(BindUniformLocationCHROMIUMBucket) /* 479 */ \
+ OP(GenValuebuffersCHROMIUMImmediate) /* 480 */ \
+ OP(DeleteValuebuffersCHROMIUMImmediate) /* 481 */ \
+ OP(IsValuebufferCHROMIUM) /* 482 */ \
+ OP(BindValuebufferCHROMIUM) /* 483 */ \
+ OP(SubscribeValueCHROMIUM) /* 484 */ \
+ OP(PopulateSubscribedValuesCHROMIUM) /* 485 */ \
+ OP(UniformValuebufferCHROMIUM) /* 486 */ \
+ OP(BindTexImage2DCHROMIUM) /* 487 */ \
+ OP(ReleaseTexImage2DCHROMIUM) /* 488 */ \
+ OP(TraceBeginCHROMIUM) /* 489 */ \
+ OP(TraceEndCHROMIUM) /* 490 */ \
+ OP(AsyncTexSubImage2DCHROMIUM) /* 491 */ \
+ OP(AsyncTexImage2DCHROMIUM) /* 492 */ \
+ OP(WaitAsyncTexImage2DCHROMIUM) /* 493 */ \
+ OP(WaitAllAsyncTexImage2DCHROMIUM) /* 494 */ \
+ OP(DiscardFramebufferEXTImmediate) /* 495 */ \
+ OP(LoseContextCHROMIUM) /* 496 */ \
+ OP(InsertSyncPointCHROMIUM) /* 497 */ \
+ OP(WaitSyncPointCHROMIUM) /* 498 */ \
+ OP(DrawBuffersEXTImmediate) /* 499 */ \
+ OP(DiscardBackbufferCHROMIUM) /* 500 */ \
+ OP(ScheduleOverlayPlaneCHROMIUM) /* 501 */ \
+ OP(SwapInterval) /* 502 */ \
+ OP(MatrixLoadfCHROMIUMImmediate) /* 503 */ \
+ OP(MatrixLoadIdentityCHROMIUM) /* 504 */ \
+ OP(BlendBarrierKHR) /* 505 */
enum CommandId {
kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
index bb809fc..e4ccbe7 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
@@ -48,6 +48,7 @@
static std::string GetStringRenderBufferParameter(uint32_t value);
static std::string GetStringRenderBufferTarget(uint32_t value);
static std::string GetStringResetStatus(uint32_t value);
+static std::string GetStringSamplerParameter(uint32_t value);
static std::string GetStringShaderBinaryFormat(uint32_t value);
static std::string GetStringShaderParameter(uint32_t value);
static std::string GetStringShaderPrecision(uint32_t value);
@@ -68,6 +69,8 @@
static std::string GetStringTextureTarget(uint32_t value);
static std::string GetStringTextureUsage(uint32_t value);
static std::string GetStringTextureWrapMode(uint32_t value);
+static std::string GetStringTransformFeedbackBindTarget(uint32_t value);
+static std::string GetStringTransformFeedbackPrimitiveMode(uint32_t value);
static std::string GetStringValueBufferTarget(uint32_t value);
static std::string GetStringVertexAttribType(uint32_t value);
static std::string GetStringVertexAttribute(uint32_t value);
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
index b205347..03a6d4d 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -4938,6 +4938,22 @@
arraysize(string_table), value);
}
+std::string GLES2Util::GetStringSamplerParameter(uint32_t value) {
+ static const EnumToString string_table[] = {
+ {GL_TEXTURE_MAG_FILTER, "GL_TEXTURE_MAG_FILTER"},
+ {GL_TEXTURE_MIN_FILTER, "GL_TEXTURE_MIN_FILTER"},
+ {GL_TEXTURE_MIN_LOD, "GL_TEXTURE_MIN_LOD"},
+ {GL_TEXTURE_MAX_LOD, "GL_TEXTURE_MAX_LOD"},
+ {GL_TEXTURE_WRAP_S, "GL_TEXTURE_WRAP_S"},
+ {GL_TEXTURE_WRAP_T, "GL_TEXTURE_WRAP_T"},
+ {GL_TEXTURE_WRAP_R, "GL_TEXTURE_WRAP_R"},
+ {GL_TEXTURE_COMPARE_MODE, "GL_TEXTURE_COMPARE_MODE"},
+ {GL_TEXTURE_COMPARE_FUNC, "GL_TEXTURE_COMPARE_FUNC"},
+ };
+ return GLES2Util::GetQualifiedEnumString(string_table,
+ arraysize(string_table), value);
+}
+
std::string GLES2Util::GetStringShaderBinaryFormat(uint32_t value) {
return GLES2Util::GetQualifiedEnumString(NULL, 0, value);
}
@@ -5168,6 +5184,24 @@
arraysize(string_table), value);
}
+std::string GLES2Util::GetStringTransformFeedbackBindTarget(uint32_t value) {
+ static const EnumToString string_table[] = {
+ {GL_TRANSFORM_FEEDBACK, "GL_TRANSFORM_FEEDBACK"},
+ };
+ return GLES2Util::GetQualifiedEnumString(string_table,
+ arraysize(string_table), value);
+}
+
+std::string GLES2Util::GetStringTransformFeedbackPrimitiveMode(uint32_t value) {
+ static const EnumToString string_table[] = {
+ {GL_POINTS, "GL_POINTS"},
+ {GL_LINES, "GL_LINES"},
+ {GL_TRIANGLES, "GL_TRIANGLES"},
+ };
+ return GLES2Util::GetQualifiedEnumString(string_table,
+ arraysize(string_table), value);
+}
+
std::string GLES2Util::GetStringValueBufferTarget(uint32_t value) {
static const EnumToString string_table[] = {
{GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM,
diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h
index b6b6483..f695a3e 100644
--- a/gpu/command_buffer/service/context_group.h
+++ b/gpu/command_buffer/service/context_group.h
@@ -5,6 +5,7 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_CONTEXT_GROUP_H_
#define GPU_COMMAND_BUFFER_SERVICE_CONTEXT_GROUP_H_
+#include <map>
#include <string>
#include <vector>
#include "base/basictypes.h"
@@ -174,6 +175,43 @@
draw_buffer_ = buf;
}
+ void AddSamplerId(GLuint client_id, GLuint service_id) {
+ samplers_id_map_[client_id] = service_id;
+ }
+
+ bool GetSamplerServiceId(GLuint client_id, GLuint* service_id) const {
+ std::map<GLuint, GLuint>::const_iterator iter =
+ samplers_id_map_.find(client_id);
+ if (iter == samplers_id_map_.end())
+ return false;
+ if (service_id)
+ *service_id = iter->second;
+ return true;
+ }
+
+ void RemoveSamplerId(GLuint client_id) {
+ samplers_id_map_.erase(client_id);
+ }
+
+ void AddTransformFeedbackId(GLuint client_id, GLuint service_id) {
+ transformfeedbacks_id_map_[client_id] = service_id;
+ }
+
+ bool GetTransformFeedbackServiceId(
+ GLuint client_id, GLuint* service_id) const {
+ std::map<GLuint, GLuint>::const_iterator iter =
+ transformfeedbacks_id_map_.find(client_id);
+ if (iter == transformfeedbacks_id_map_.end())
+ return false;
+ if (service_id)
+ *service_id = iter->second;
+ return true;
+ }
+
+ void RemoveTransformFeedbackId(GLuint client_id) {
+ transformfeedbacks_id_map_.erase(client_id);
+ }
+
private:
friend class base::RefCounted<ContextGroup>;
~ContextGroup();
@@ -223,6 +261,10 @@
std::vector<base::WeakPtr<gles2::GLES2Decoder> > decoders_;
+ // Mappings from client side IDs to service side IDs.
+ std::map<GLuint, GLuint> samplers_id_map_;
+ std::map<GLuint, GLuint> transformfeedbacks_id_map_;
+
GLenum draw_buffer_;
DISALLOW_COPY_AND_ASSIGN(ContextGroup);
diff --git a/gpu/command_buffer/service/gl_context_virtual.cc b/gpu/command_buffer/service/gl_context_virtual.cc
index a29e540..765dbee 100644
--- a/gpu/command_buffer/service/gl_context_virtual.cc
+++ b/gpu/command_buffer/service/gl_context_virtual.cc
@@ -82,7 +82,7 @@
return shared_context_->GetHandle();
}
-void GLContextVirtual::SetSwapInterval(int interval) {
+void GLContextVirtual::OnSetSwapInterval(int interval) {
shared_context_->SetSwapInterval(interval);
}
diff --git a/gpu/command_buffer/service/gl_context_virtual.h b/gpu/command_buffer/service/gl_context_virtual.h
index ed61016..7a79928 100644
--- a/gpu/command_buffer/service/gl_context_virtual.h
+++ b/gpu/command_buffer/service/gl_context_virtual.h
@@ -41,7 +41,7 @@
void ReleaseCurrent(gfx::GLSurface* surface) override;
bool IsCurrent(gfx::GLSurface* surface) override;
void* GetHandle() override;
- void SetSwapInterval(int interval) override;
+ void OnSetSwapInterval(int interval) override;
std::string GetExtensions() override;
bool GetTotalGpuMemory(size_t* bytes) override;
void SetSafeToForceGpuSwitch() override;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index f97710e..7ea1a06 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1473,6 +1473,11 @@
// Wrapper for glReleaseShaderCompiler.
void DoReleaseShaderCompiler() { }
+ // Wrappers for glSamplerParameter*v functions.
+ void DoSamplerParameterfv(
+ GLuint sampler, GLenum pname, const GLfloat* params);
+ void DoSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* params);
+
// Wrappers for glTexParameter functions.
void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
void DoTexParameteri(GLenum target, GLenum pname, GLint param);
@@ -2955,6 +2960,10 @@
if (workarounds().regenerate_struct_names)
driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEmulateShaderPrecision))
+ resources.WEBGL_debug_shader_precision = true;
+
vertex_translator_ = shader_translator_cache()->GetTranslator(
GL_VERTEX_SHADER,
shader_spec,
@@ -4269,6 +4278,14 @@
void GLES2DecoderImpl::OnFboChanged() const {
if (workarounds().restore_scissor_on_fbo_change)
state_.fbo_binding_for_scissor_workaround_dirty_ = true;
+
+ if (workarounds().gl_begin_gl_end_on_fbo_change_to_backbuffer) {
+ GLint bound_fbo_unsigned = -1;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &bound_fbo_unsigned);
+ GLuint bound_fbo = static_cast<GLuint>(bound_fbo_unsigned);
+ if (surface_ && surface_->GetBackingFrameBufferObject() == bound_fbo)
+ surface_->NotifyWasBound();
+ }
}
// Called after the FBO is checked for completeness.
@@ -5858,6 +5875,18 @@
ExitCommandProcessingEarly();
};
+void GLES2DecoderImpl::DoSamplerParameterfv(
+ GLuint sampler, GLenum pname, const GLfloat* params) {
+ DCHECK(params);
+ glSamplerParameterf(sampler, pname, params[0]);
+}
+
+void GLES2DecoderImpl::DoSamplerParameteriv(
+ GLuint sampler, GLenum pname, const GLint* params) {
+ DCHECK(params);
+ glSamplerParameteri(sampler, pname, params[0]);
+}
+
void GLES2DecoderImpl::DoTexParameterf(
GLenum target, GLenum pname, GLfloat param) {
TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index f81b56a..b7877ff 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -80,6 +80,20 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleBindSampler(uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::BindSampler& c =
+ *static_cast<const gles2::cmds::BindSampler*>(cmd_data);
+ (void)c;
+ GLuint unit = static_cast<GLuint>(c.unit);
+ GLuint sampler = c.sampler;
+ group_->GetSamplerServiceId(sampler, &sampler);
+ glBindSampler(unit, sampler);
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleBindTexture(uint32_t immediate_data_size,
const void* cmd_data) {
const gles2::cmds::BindTexture& c =
@@ -95,6 +109,21 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleBindTransformFeedback(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::BindTransformFeedback& c =
+ *static_cast<const gles2::cmds::BindTransformFeedback*>(cmd_data);
+ (void)c;
+ GLenum target = static_cast<GLenum>(c.target);
+ GLuint transformfeedback = c.transformfeedback;
+ group_->GetTransformFeedbackServiceId(transformfeedback, &transformfeedback);
+ glBindTransformFeedback(target, transformfeedback);
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleBlendColor(uint32_t immediate_data_size,
const void* cmd_data) {
const gles2::cmds::BlendColor& c =
@@ -616,6 +645,34 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleDeleteSamplersImmediate(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::DeleteSamplersImmediate& c =
+ *static_cast<const gles2::cmds::DeleteSamplersImmediate*>(cmd_data);
+ (void)c;
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32_t data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* samplers =
+ GetImmediateDataAs<const GLuint*>(c, data_size, immediate_data_size);
+ if (samplers == NULL) {
+ return error::kOutOfBounds;
+ }
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ GLuint service_id = 0;
+ if (group_->GetSamplerServiceId(samplers[ii], &service_id)) {
+ glDeleteSamplers(1, &service_id);
+ group_->RemoveSamplerId(samplers[ii]);
+ }
+ }
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleDeleteTexturesImmediate(
uint32_t immediate_data_size,
const void* cmd_data) {
@@ -636,6 +693,35 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleDeleteTransformFeedbacksImmediate(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::DeleteTransformFeedbacksImmediate& c =
+ *static_cast<const gles2::cmds::DeleteTransformFeedbacksImmediate*>(
+ cmd_data);
+ (void)c;
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32_t data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLuint* ids =
+ GetImmediateDataAs<const GLuint*>(c, data_size, immediate_data_size);
+ if (ids == NULL) {
+ return error::kOutOfBounds;
+ }
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ GLuint service_id = 0;
+ if (group_->GetTransformFeedbackServiceId(ids[ii], &service_id)) {
+ glDeleteTransformFeedbacks(1, &service_id);
+ group_->RemoveTransformFeedbackId(ids[ii]);
+ }
+ }
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleDepthFunc(uint32_t immediate_data_size,
const void* cmd_data) {
const gles2::cmds::DepthFunc& c =
@@ -934,6 +1020,37 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleGenSamplersImmediate(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::GenSamplersImmediate& c =
+ *static_cast<const gles2::cmds::GenSamplersImmediate*>(cmd_data);
+ (void)c;
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32_t data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* samplers =
+ GetImmediateDataAs<GLuint*>(c, data_size, immediate_data_size);
+ if (samplers == NULL) {
+ return error::kOutOfBounds;
+ }
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ if (group_->GetSamplerServiceId(samplers[ii], NULL)) {
+ return error::kInvalidArguments;
+ }
+ }
+ scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
+ glGenSamplers(n, service_ids.get());
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ group_->AddSamplerId(samplers[ii], service_ids[ii]);
+ }
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleGenTexturesImmediate(
uint32_t immediate_data_size,
const void* cmd_data) {
@@ -956,6 +1073,37 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleGenTransformFeedbacksImmediate(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::GenTransformFeedbacksImmediate& c =
+ *static_cast<const gles2::cmds::GenTransformFeedbacksImmediate*>(
+ cmd_data);
+ (void)c;
+ GLsizei n = static_cast<GLsizei>(c.n);
+ uint32_t data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
+ GLuint* ids = GetImmediateDataAs<GLuint*>(c, data_size, immediate_data_size);
+ if (ids == NULL) {
+ return error::kOutOfBounds;
+ }
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ if (group_->GetTransformFeedbackServiceId(ids[ii], NULL)) {
+ return error::kInvalidArguments;
+ }
+ }
+ scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
+ glGenTransformFeedbacks(n, service_ids.get());
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ group_->AddTransformFeedbackId(ids[ii], service_ids[ii]);
+ }
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleGetBooleanv(uint32_t immediate_data_size,
const void* cmd_data) {
const gles2::cmds::GetBooleanv& c =
@@ -1273,6 +1421,76 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleGetSamplerParameterfv(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::GetSamplerParameterfv& c =
+ *static_cast<const gles2::cmds::GetSamplerParameterfv*>(cmd_data);
+ (void)c;
+ GLuint sampler = c.sampler;
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetSamplerParameterfv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLfloat* params = result ? result->GetData() : NULL;
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetSamplerParameterfv");
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ group_->GetSamplerServiceId(sampler, &sampler);
+ glGetSamplerParameterfv(sampler, pname, params);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ result->SetNumResults(num_values);
+ } else {
+ LOCAL_SET_GL_ERROR(error, "GetSamplerParameterfv", "");
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetSamplerParameteriv(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::GetSamplerParameteriv& c =
+ *static_cast<const gles2::cmds::GetSamplerParameteriv*>(cmd_data);
+ (void)c;
+ GLuint sampler = c.sampler;
+ GLenum pname = static_cast<GLenum>(c.pname);
+ typedef cmds::GetSamplerParameteriv::Result Result;
+ GLsizei num_values = 0;
+ GetNumValuesReturnedForGLGet(pname, &num_values);
+ Result* result = GetSharedMemoryAs<Result*>(
+ c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
+ GLint* params = result ? result->GetData() : NULL;
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetSamplerParameteriv");
+ // Check that the client initialized the result.
+ if (result->size != 0) {
+ return error::kInvalidArguments;
+ }
+ group_->GetSamplerServiceId(sampler, &sampler);
+ glGetSamplerParameteriv(sampler, pname, params);
+ GLenum error = glGetError();
+ if (error == GL_NO_ERROR) {
+ result->SetNumResults(num_values);
+ } else {
+ LOCAL_SET_GL_ERROR(error, "GetSamplerParameteriv", "");
+ }
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleGetShaderiv(uint32_t immediate_data_size,
const void* cmd_data) {
const gles2::cmds::GetShaderiv& c =
@@ -1646,6 +1864,25 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleIsSampler(uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::IsSampler& c =
+ *static_cast<const gles2::cmds::IsSampler*>(cmd_data);
+ (void)c;
+ GLuint sampler = c.sampler;
+ typedef cmds::IsSampler::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ group_->GetSamplerServiceId(sampler, &sampler);
+ *result_dst = glIsSampler(sampler);
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleIsShader(uint32_t immediate_data_size,
const void* cmd_data) {
const gles2::cmds::IsShader& c =
@@ -1678,6 +1915,26 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleIsTransformFeedback(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::IsTransformFeedback& c =
+ *static_cast<const gles2::cmds::IsTransformFeedback*>(cmd_data);
+ (void)c;
+ GLuint transformfeedback = c.transformfeedback;
+ typedef cmds::IsTransformFeedback::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ group_->GetTransformFeedbackServiceId(transformfeedback, &transformfeedback);
+ *result_dst = glIsTransformFeedback(transformfeedback);
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleLineWidth(uint32_t immediate_data_size,
const void* cmd_data) {
const gles2::cmds::LineWidth& c =
@@ -1705,6 +1962,18 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandlePauseTransformFeedback(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::PauseTransformFeedback& c =
+ *static_cast<const gles2::cmds::PauseTransformFeedback*>(cmd_data);
+ (void)c;
+ glPauseTransformFeedback();
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandlePolygonOffset(uint32_t immediate_data_size,
const void* cmd_data) {
const gles2::cmds::PolygonOffset& c =
@@ -1774,6 +2043,18 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleResumeTransformFeedback(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::ResumeTransformFeedback& c =
+ *static_cast<const gles2::cmds::ResumeTransformFeedback*>(cmd_data);
+ (void)c;
+ glResumeTransformFeedback();
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleSampleCoverage(
uint32_t immediate_data_size,
const void* cmd_data) {
@@ -1786,6 +2067,91 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleSamplerParameterf(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::SamplerParameterf& c =
+ *static_cast<const gles2::cmds::SamplerParameterf*>(cmd_data);
+ (void)c;
+ GLuint sampler = c.sampler;
+ GLenum pname = static_cast<GLenum>(c.pname);
+ GLfloat param = static_cast<GLfloat>(c.param);
+ group_->GetSamplerServiceId(sampler, &sampler);
+ glSamplerParameterf(sampler, pname, param);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleSamplerParameterfvImmediate(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::SamplerParameterfvImmediate& c =
+ *static_cast<const gles2::cmds::SamplerParameterfvImmediate*>(cmd_data);
+ (void)c;
+ GLuint sampler = c.sampler;
+ GLenum pname = static_cast<GLenum>(c.pname);
+ uint32_t data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLfloat* params =
+ GetImmediateDataAs<const GLfloat*>(c, data_size, immediate_data_size);
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ group_->GetSamplerServiceId(sampler, &sampler);
+ DoSamplerParameterfv(sampler, pname, params);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleSamplerParameteri(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::SamplerParameteri& c =
+ *static_cast<const gles2::cmds::SamplerParameteri*>(cmd_data);
+ (void)c;
+ GLuint sampler = c.sampler;
+ GLenum pname = static_cast<GLenum>(c.pname);
+ GLint param = static_cast<GLint>(c.param);
+ group_->GetSamplerServiceId(sampler, &sampler);
+ glSamplerParameteri(sampler, pname, param);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleSamplerParameterivImmediate(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::SamplerParameterivImmediate& c =
+ *static_cast<const gles2::cmds::SamplerParameterivImmediate*>(cmd_data);
+ (void)c;
+ GLuint sampler = c.sampler;
+ GLenum pname = static_cast<GLenum>(c.pname);
+ uint32_t data_size;
+ if (!ComputeDataSize(1, sizeof(GLint), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLint* params =
+ GetImmediateDataAs<const GLint*>(c, data_size, immediate_data_size);
+ if (params == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoSamplerParameteriv(sampler, pname, params);
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleScissor(uint32_t immediate_data_size,
const void* cmd_data) {
const gles2::cmds::Scissor& c =
@@ -3416,6 +3782,31 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleBeginTransformFeedback(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::BeginTransformFeedback& c =
+ *static_cast<const gles2::cmds::BeginTransformFeedback*>(cmd_data);
+ (void)c;
+ GLenum primitivemode = static_cast<GLenum>(c.primitivemode);
+ glBeginTransformFeedback(primitivemode);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleEndTransformFeedback(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::EndTransformFeedback& c =
+ *static_cast<const gles2::cmds::EndTransformFeedback*>(cmd_data);
+ (void)c;
+ glEndTransformFeedback();
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleInsertEventMarkerEXT(
uint32_t immediate_data_size,
const void* cmd_data) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
index 014007a..2bc23a0 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
@@ -124,6 +124,18 @@
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
+TEST_P(GLES2DecoderTest1, BindSamplerValidArgs) {
+ EXPECT_CALL(*gl_, BindSampler(1, kServiceSamplerId));
+ SpecializedSetup<cmds::BindSampler, 0>(true);
+ cmds::BindSampler cmd;
+ cmd.Init(1, client_sampler_id_);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+
TEST_P(GLES2DecoderTest1, BindTextureValidArgs) {
EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId));
SpecializedSetup<cmds::BindTexture, 0>(true);
@@ -163,6 +175,19 @@
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
+TEST_P(GLES2DecoderTest1, BindTransformFeedbackValidArgs) {
+ EXPECT_CALL(*gl_, BindTransformFeedback(GL_TRANSFORM_FEEDBACK,
+ kServiceTransformFeedbackId));
+ SpecializedSetup<cmds::BindTransformFeedback, 0>(true);
+ cmds::BindTransformFeedback cmd;
+ cmd.Init(GL_TRANSFORM_FEEDBACK, client_transformfeedback_id_);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+
TEST_P(GLES2DecoderTest1, BlendColorValidArgs) {
EXPECT_CALL(*gl_, BlendColor(1, 2, 3, 4));
SpecializedSetup<cmds::BlendColor, 0>(true);
@@ -515,6 +540,34 @@
EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
}
+TEST_P(GLES2DecoderTest1, DeleteSamplersImmediateValidArgs) {
+ EXPECT_CALL(*gl_, DeleteSamplers(1, Pointee(kServiceSamplerId))).Times(1);
+ cmds::DeleteSamplersImmediate& cmd =
+ *GetImmediateAs<cmds::DeleteSamplersImmediate>();
+ SpecializedSetup<cmds::DeleteSamplersImmediate, 0>(true);
+ cmd.Init(1, &client_sampler_id_);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError,
+ ExecuteImmediateCmd(cmd, sizeof(client_sampler_id_)));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_FALSE(GetSamplerServiceId(client_sampler_id_, NULL));
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand,
+ ExecuteImmediateCmd(cmd, sizeof(client_sampler_id_)));
+}
+
+TEST_P(GLES2DecoderTest1, DeleteSamplersImmediateInvalidArgs) {
+ cmds::DeleteSamplersImmediate& cmd =
+ *GetImmediateAs<cmds::DeleteSamplersImmediate>();
+ SpecializedSetup<cmds::DeleteSamplersImmediate, 0>(false);
+ GLuint temp = kInvalidClientId;
+ cmd.Init(1, &temp);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp)));
+}
+
TEST_P(GLES2DecoderTest1, DeleteShaderValidArgs) {
EXPECT_CALL(*gl_, DeleteShader(kServiceShaderId));
SpecializedSetup<cmds::DeleteShader, 0>(true);
@@ -545,6 +598,36 @@
EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
}
+TEST_P(GLES2DecoderTest1, DeleteTransformFeedbacksImmediateValidArgs) {
+ EXPECT_CALL(*gl_, DeleteTransformFeedbacks(
+ 1, Pointee(kServiceTransformFeedbackId))).Times(1);
+ cmds::DeleteTransformFeedbacksImmediate& cmd =
+ *GetImmediateAs<cmds::DeleteTransformFeedbacksImmediate>();
+ SpecializedSetup<cmds::DeleteTransformFeedbacksImmediate, 0>(true);
+ cmd.Init(1, &client_transformfeedback_id_);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError,
+ ExecuteImmediateCmd(cmd, sizeof(client_transformfeedback_id_)));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_FALSE(
+ GetTransformFeedbackServiceId(client_transformfeedback_id_, NULL));
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand,
+ ExecuteImmediateCmd(cmd, sizeof(client_transformfeedback_id_)));
+}
+
+TEST_P(GLES2DecoderTest1, DeleteTransformFeedbacksImmediateInvalidArgs) {
+ cmds::DeleteTransformFeedbacksImmediate& cmd =
+ *GetImmediateAs<cmds::DeleteTransformFeedbacksImmediate>();
+ SpecializedSetup<cmds::DeleteTransformFeedbacksImmediate, 0>(false);
+ GLuint temp = kInvalidClientId;
+ cmd.Init(1, &temp);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp)));
+}
+
TEST_P(GLES2DecoderTest1, DepthFuncValidArgs) {
EXPECT_CALL(*gl_, DepthFunc(GL_NEVER));
SpecializedSetup<cmds::DepthFunc, 0>(true);
@@ -874,6 +957,36 @@
ExecuteImmediateCmd(*cmd, sizeof(&client_renderbuffer_id_)));
}
+TEST_P(GLES2DecoderTest1, GenSamplersImmediateValidArgs) {
+ EXPECT_CALL(*gl_, GenSamplers(1, _))
+ .WillOnce(SetArgumentPointee<1>(kNewServiceId));
+ cmds::GenSamplersImmediate* cmd =
+ GetImmediateAs<cmds::GenSamplersImmediate>();
+ GLuint temp = kNewClientId;
+ SpecializedSetup<cmds::GenSamplersImmediate, 0>(true);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ cmd->Init(1, &temp);
+ EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ GLuint service_id;
+ EXPECT_TRUE(GetSamplerServiceId(kNewClientId, &service_id));
+ EXPECT_EQ(kNewServiceId, service_id);
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+}
+
+TEST_P(GLES2DecoderTest1, GenSamplersImmediateInvalidArgs) {
+ EXPECT_CALL(*gl_, GenSamplers(_, _)).Times(0);
+ cmds::GenSamplersImmediate* cmd =
+ GetImmediateAs<cmds::GenSamplersImmediate>();
+ SpecializedSetup<cmds::GenSamplersImmediate, 0>(false);
+ cmd->Init(1, &client_sampler_id_);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kInvalidArguments,
+ ExecuteImmediateCmd(*cmd, sizeof(&client_sampler_id_)));
+ decoder_->set_unsafe_es3_apis_enabled(false);
+}
+
TEST_P(GLES2DecoderTest1, GenTexturesImmediateValidArgs) {
EXPECT_CALL(*gl_, GenTextures(1, _))
.WillOnce(SetArgumentPointee<1>(kNewServiceId));
@@ -896,6 +1009,36 @@
EXPECT_EQ(error::kInvalidArguments,
ExecuteImmediateCmd(*cmd, sizeof(&client_texture_id_)));
}
+
+TEST_P(GLES2DecoderTest1, GenTransformFeedbacksImmediateValidArgs) {
+ EXPECT_CALL(*gl_, GenTransformFeedbacks(1, _))
+ .WillOnce(SetArgumentPointee<1>(kNewServiceId));
+ cmds::GenTransformFeedbacksImmediate* cmd =
+ GetImmediateAs<cmds::GenTransformFeedbacksImmediate>();
+ GLuint temp = kNewClientId;
+ SpecializedSetup<cmds::GenTransformFeedbacksImmediate, 0>(true);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ cmd->Init(1, &temp);
+ EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ GLuint service_id;
+ EXPECT_TRUE(GetTransformFeedbackServiceId(kNewClientId, &service_id));
+ EXPECT_EQ(kNewServiceId, service_id);
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+}
+
+TEST_P(GLES2DecoderTest1, GenTransformFeedbacksImmediateInvalidArgs) {
+ EXPECT_CALL(*gl_, GenTransformFeedbacks(_, _)).Times(0);
+ cmds::GenTransformFeedbacksImmediate* cmd =
+ GetImmediateAs<cmds::GenTransformFeedbacksImmediate>();
+ SpecializedSetup<cmds::GenTransformFeedbacksImmediate, 0>(false);
+ cmd->Init(1, &client_transformfeedback_id_);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kInvalidArguments,
+ ExecuteImmediateCmd(*cmd, sizeof(&client_transformfeedback_id_)));
+ decoder_->set_unsafe_es3_apis_enabled(false);
+}
// TODO(gman): GetActiveAttrib
// TODO(gman): GetActiveUniform
@@ -1397,6 +1540,56 @@
EXPECT_EQ(0u, result->size);
}
+TEST_P(GLES2DecoderTest1, GetSamplerParameterfvValidArgs) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ SpecializedSetup<cmds::GetSamplerParameterfv, 0>(true);
+ typedef cmds::GetSamplerParameterfv::Result Result;
+ Result* result = static_cast<Result*>(shared_memory_address_);
+ EXPECT_CALL(*gl_,
+ GetSamplerParameterfv(kServiceSamplerId, GL_TEXTURE_MAG_FILTER,
+ result->GetData()));
+ result->size = 0;
+ cmds::GetSamplerParameterfv cmd;
+ cmd.Init(client_sampler_id_, GL_TEXTURE_MAG_FILTER, shared_memory_id_,
+ shared_memory_offset_);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(
+ decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_TEXTURE_MAG_FILTER),
+ result->GetNumResults());
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest1, GetSamplerParameterivValidArgs) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ SpecializedSetup<cmds::GetSamplerParameteriv, 0>(true);
+ typedef cmds::GetSamplerParameteriv::Result Result;
+ Result* result = static_cast<Result*>(shared_memory_address_);
+ EXPECT_CALL(*gl_,
+ GetSamplerParameteriv(kServiceSamplerId, GL_TEXTURE_MAG_FILTER,
+ result->GetData()));
+ result->size = 0;
+ cmds::GetSamplerParameteriv cmd;
+ cmd.Init(client_sampler_id_, GL_TEXTURE_MAG_FILTER, shared_memory_id_,
+ shared_memory_offset_);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(
+ decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_TEXTURE_MAG_FILTER),
+ result->GetNumResults());
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+
TEST_P(GLES2DecoderTest1, GetShaderivValidArgs) {
EXPECT_CALL(*gl_, GetError())
.WillOnce(Return(GL_NO_ERROR))
@@ -1752,129 +1945,4 @@
cmd.Init(GL_BLEND, shared_memory_id_, kInvalidSharedMemoryOffset);
EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
}
-
-TEST_P(GLES2DecoderTest1, IsFramebufferValidArgs) {
- SpecializedSetup<cmds::IsFramebuffer, 0>(true);
- cmds::IsFramebuffer cmd;
- cmd.Init(client_framebuffer_id_, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_P(GLES2DecoderTest1, IsFramebufferInvalidArgsBadSharedMemoryId) {
- SpecializedSetup<cmds::IsFramebuffer, 0>(false);
- cmds::IsFramebuffer cmd;
- cmd.Init(client_framebuffer_id_, kInvalidSharedMemoryId,
- shared_memory_offset_);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- cmd.Init(client_framebuffer_id_, shared_memory_id_,
- kInvalidSharedMemoryOffset);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
-}
-
-TEST_P(GLES2DecoderTest1, IsProgramValidArgs) {
- SpecializedSetup<cmds::IsProgram, 0>(true);
- cmds::IsProgram cmd;
- cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_P(GLES2DecoderTest1, IsProgramInvalidArgsBadSharedMemoryId) {
- SpecializedSetup<cmds::IsProgram, 0>(false);
- cmds::IsProgram cmd;
- cmd.Init(client_program_id_, kInvalidSharedMemoryId, shared_memory_offset_);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- cmd.Init(client_program_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
-}
-
-TEST_P(GLES2DecoderTest1, IsRenderbufferValidArgs) {
- SpecializedSetup<cmds::IsRenderbuffer, 0>(true);
- cmds::IsRenderbuffer cmd;
- cmd.Init(client_renderbuffer_id_, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_P(GLES2DecoderTest1, IsRenderbufferInvalidArgsBadSharedMemoryId) {
- SpecializedSetup<cmds::IsRenderbuffer, 0>(false);
- cmds::IsRenderbuffer cmd;
- cmd.Init(client_renderbuffer_id_, kInvalidSharedMemoryId,
- shared_memory_offset_);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- cmd.Init(client_renderbuffer_id_, shared_memory_id_,
- kInvalidSharedMemoryOffset);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
-}
-
-TEST_P(GLES2DecoderTest1, IsShaderValidArgs) {
- SpecializedSetup<cmds::IsShader, 0>(true);
- cmds::IsShader cmd;
- cmd.Init(client_shader_id_, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_P(GLES2DecoderTest1, IsShaderInvalidArgsBadSharedMemoryId) {
- SpecializedSetup<cmds::IsShader, 0>(false);
- cmds::IsShader cmd;
- cmd.Init(client_shader_id_, kInvalidSharedMemoryId, shared_memory_offset_);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- cmd.Init(client_shader_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
-}
-
-TEST_P(GLES2DecoderTest1, IsTextureValidArgs) {
- SpecializedSetup<cmds::IsTexture, 0>(true);
- cmds::IsTexture cmd;
- cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_P(GLES2DecoderTest1, IsTextureInvalidArgsBadSharedMemoryId) {
- SpecializedSetup<cmds::IsTexture, 0>(false);
- cmds::IsTexture cmd;
- cmd.Init(client_texture_id_, kInvalidSharedMemoryId, shared_memory_offset_);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- cmd.Init(client_texture_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
-}
-
-TEST_P(GLES2DecoderTest1, LineWidthValidArgs) {
- EXPECT_CALL(*gl_, LineWidth(0.5f));
- SpecializedSetup<cmds::LineWidth, 0>(true);
- cmds::LineWidth cmd;
- cmd.Init(0.5f);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_P(GLES2DecoderTest1, LineWidthInvalidValue0_0) {
- SpecializedSetup<cmds::LineWidth, 0>(false);
- cmds::LineWidth cmd;
- cmd.Init(0.0f);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_P(GLES2DecoderTest1, LineWidthNaNValue0) {
- SpecializedSetup<cmds::LineWidth, 0>(false);
- cmds::LineWidth cmd;
- cmd.Init(nanf(""));
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_P(GLES2DecoderTest1, LinkProgramValidArgs) {
- EXPECT_CALL(*gl_, LinkProgram(kServiceProgramId));
- SpecializedSetup<cmds::LinkProgram, 0>(true);
- cmds::LinkProgram cmd;
- cmd.Init(client_program_id_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-// TODO(gman): PixelStorei
-
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_1_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
index 602be42..6f8b706 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
@@ -12,6 +12,193 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
+TEST_P(GLES2DecoderTest2, IsFramebufferValidArgs) {
+ SpecializedSetup<cmds::IsFramebuffer, 0>(true);
+ cmds::IsFramebuffer cmd;
+ cmd.Init(client_framebuffer_id_, shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest2, IsFramebufferInvalidArgsBadSharedMemoryId) {
+ SpecializedSetup<cmds::IsFramebuffer, 0>(false);
+ cmds::IsFramebuffer cmd;
+ cmd.Init(client_framebuffer_id_, kInvalidSharedMemoryId,
+ shared_memory_offset_);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ cmd.Init(client_framebuffer_id_, shared_memory_id_,
+ kInvalidSharedMemoryOffset);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest2, IsProgramValidArgs) {
+ SpecializedSetup<cmds::IsProgram, 0>(true);
+ cmds::IsProgram cmd;
+ cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest2, IsProgramInvalidArgsBadSharedMemoryId) {
+ SpecializedSetup<cmds::IsProgram, 0>(false);
+ cmds::IsProgram cmd;
+ cmd.Init(client_program_id_, kInvalidSharedMemoryId, shared_memory_offset_);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ cmd.Init(client_program_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest2, IsRenderbufferValidArgs) {
+ SpecializedSetup<cmds::IsRenderbuffer, 0>(true);
+ cmds::IsRenderbuffer cmd;
+ cmd.Init(client_renderbuffer_id_, shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest2, IsRenderbufferInvalidArgsBadSharedMemoryId) {
+ SpecializedSetup<cmds::IsRenderbuffer, 0>(false);
+ cmds::IsRenderbuffer cmd;
+ cmd.Init(client_renderbuffer_id_, kInvalidSharedMemoryId,
+ shared_memory_offset_);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ cmd.Init(client_renderbuffer_id_, shared_memory_id_,
+ kInvalidSharedMemoryOffset);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest2, IsSamplerValidArgs) {
+ EXPECT_CALL(*gl_, IsSampler(kServiceSamplerId));
+ SpecializedSetup<cmds::IsSampler, 0>(true);
+ cmds::IsSampler cmd;
+ cmd.Init(client_sampler_id_, shared_memory_id_, shared_memory_offset_);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest2, IsSamplerInvalidArgsBadSharedMemoryId) {
+ EXPECT_CALL(*gl_, IsSampler(kServiceSamplerId)).Times(0);
+ SpecializedSetup<cmds::IsSampler, 0>(false);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ cmds::IsSampler cmd;
+ cmd.Init(client_sampler_id_, kInvalidSharedMemoryId, shared_memory_offset_);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ cmd.Init(client_sampler_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ decoder_->set_unsafe_es3_apis_enabled(true);
+}
+
+TEST_P(GLES2DecoderTest2, IsShaderValidArgs) {
+ SpecializedSetup<cmds::IsShader, 0>(true);
+ cmds::IsShader cmd;
+ cmd.Init(client_shader_id_, shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest2, IsShaderInvalidArgsBadSharedMemoryId) {
+ SpecializedSetup<cmds::IsShader, 0>(false);
+ cmds::IsShader cmd;
+ cmd.Init(client_shader_id_, kInvalidSharedMemoryId, shared_memory_offset_);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ cmd.Init(client_shader_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest2, IsTextureValidArgs) {
+ SpecializedSetup<cmds::IsTexture, 0>(true);
+ cmds::IsTexture cmd;
+ cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest2, IsTextureInvalidArgsBadSharedMemoryId) {
+ SpecializedSetup<cmds::IsTexture, 0>(false);
+ cmds::IsTexture cmd;
+ cmd.Init(client_texture_id_, kInvalidSharedMemoryId, shared_memory_offset_);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ cmd.Init(client_texture_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest2, IsTransformFeedbackValidArgs) {
+ EXPECT_CALL(*gl_, IsTransformFeedback(kServiceTransformFeedbackId));
+ SpecializedSetup<cmds::IsTransformFeedback, 0>(true);
+ cmds::IsTransformFeedback cmd;
+ cmd.Init(client_transformfeedback_id_, shared_memory_id_,
+ shared_memory_offset_);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest2, IsTransformFeedbackInvalidArgsBadSharedMemoryId) {
+ EXPECT_CALL(*gl_, IsTransformFeedback(kServiceTransformFeedbackId)).Times(0);
+ SpecializedSetup<cmds::IsTransformFeedback, 0>(false);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ cmds::IsTransformFeedback cmd;
+ cmd.Init(client_transformfeedback_id_, kInvalidSharedMemoryId,
+ shared_memory_offset_);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ cmd.Init(client_transformfeedback_id_, shared_memory_id_,
+ kInvalidSharedMemoryOffset);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ decoder_->set_unsafe_es3_apis_enabled(true);
+}
+
+TEST_P(GLES2DecoderTest2, LineWidthValidArgs) {
+ EXPECT_CALL(*gl_, LineWidth(0.5f));
+ SpecializedSetup<cmds::LineWidth, 0>(true);
+ cmds::LineWidth cmd;
+ cmd.Init(0.5f);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest2, LineWidthInvalidValue0_0) {
+ SpecializedSetup<cmds::LineWidth, 0>(false);
+ cmds::LineWidth cmd;
+ cmd.Init(0.0f);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest2, LineWidthNaNValue0) {
+ SpecializedSetup<cmds::LineWidth, 0>(false);
+ cmds::LineWidth cmd;
+ cmd.Init(nanf(""));
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest2, LinkProgramValidArgs) {
+ EXPECT_CALL(*gl_, LinkProgram(kServiceProgramId));
+ SpecializedSetup<cmds::LinkProgram, 0>(true);
+ cmds::LinkProgram cmd;
+ cmd.Init(client_program_id_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest2, PauseTransformFeedbackValidArgs) {
+ EXPECT_CALL(*gl_, PauseTransformFeedback());
+ SpecializedSetup<cmds::PauseTransformFeedback, 0>(true);
+ cmds::PauseTransformFeedback cmd;
+ cmd.Init();
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+// TODO(gman): PixelStorei
+
TEST_P(GLES2DecoderTest2, PolygonOffsetValidArgs) {
EXPECT_CALL(*gl_, PolygonOffset(1, 2));
SpecializedSetup<cmds::PolygonOffset, 0>(true);
@@ -71,6 +258,18 @@
EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
}
+TEST_P(GLES2DecoderTest2, ResumeTransformFeedbackValidArgs) {
+ EXPECT_CALL(*gl_, ResumeTransformFeedback());
+ SpecializedSetup<cmds::ResumeTransformFeedback, 0>(true);
+ cmds::ResumeTransformFeedback cmd;
+ cmd.Init();
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+
TEST_P(GLES2DecoderTest2, SampleCoverageValidArgs) {
EXPECT_CALL(*gl_, SampleCoverage(1, true));
SpecializedSetup<cmds::SampleCoverage, 0>(true);
@@ -80,6 +279,68 @@
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
+TEST_P(GLES2DecoderTest2, SamplerParameterfValidArgs) {
+ EXPECT_CALL(*gl_, SamplerParameterf(kServiceSamplerId, GL_TEXTURE_MAG_FILTER,
+ GL_NEAREST));
+ SpecializedSetup<cmds::SamplerParameterf, 0>(true);
+ cmds::SamplerParameterf cmd;
+ cmd.Init(client_sampler_id_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest2, SamplerParameterfvImmediateValidArgs) {
+ cmds::SamplerParameterfvImmediate& cmd =
+ *GetImmediateAs<cmds::SamplerParameterfvImmediate>();
+ SpecializedSetup<cmds::SamplerParameterfvImmediate, 0>(true);
+ GLfloat temp[1] = {
+ GL_NEAREST,
+ };
+ cmd.Init(kServiceSamplerId, GL_TEXTURE_MAG_FILTER, &temp[0]);
+ EXPECT_CALL(*gl_, SamplerParameterf(kServiceSamplerId, GL_TEXTURE_MAG_FILTER,
+ *reinterpret_cast<GLfloat*>(
+ ImmediateDataAddress(&cmd))));
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp)));
+}
+
+TEST_P(GLES2DecoderTest2, SamplerParameteriValidArgs) {
+ EXPECT_CALL(*gl_, SamplerParameteri(kServiceSamplerId, GL_TEXTURE_MAG_FILTER,
+ GL_NEAREST));
+ SpecializedSetup<cmds::SamplerParameteri, 0>(true);
+ cmds::SamplerParameteri cmd;
+ cmd.Init(client_sampler_id_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest2, SamplerParameterivImmediateValidArgs) {
+ cmds::SamplerParameterivImmediate& cmd =
+ *GetImmediateAs<cmds::SamplerParameterivImmediate>();
+ SpecializedSetup<cmds::SamplerParameterivImmediate, 0>(true);
+ GLint temp[1] = {
+ GL_NEAREST,
+ };
+ cmd.Init(kServiceSamplerId, GL_TEXTURE_MAG_FILTER, &temp[0]);
+ EXPECT_CALL(*gl_, SamplerParameteri(
+ kServiceSamplerId, GL_TEXTURE_MAG_FILTER,
+ *reinterpret_cast<GLint*>(ImmediateDataAddress(&cmd))));
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp)));
+}
+
TEST_P(GLES2DecoderTest2, ScissorValidArgs) {
EXPECT_CALL(*gl_, Scissor(1, 2, 3, 4));
SpecializedSetup<cmds::Scissor, 0>(true);
@@ -220,12 +481,14 @@
cmds::TexParameterfvImmediate& cmd =
*GetImmediateAs<cmds::TexParameterfvImmediate>();
EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
+
SpecializedSetup<cmds::TexParameterfvImmediate, 0>(false);
GLfloat temp[1] = {
GL_NEAREST,
};
cmd.Init(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, &temp[0]);
EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
+
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
@@ -233,12 +496,14 @@
cmds::TexParameterfvImmediate& cmd =
*GetImmediateAs<cmds::TexParameterfvImmediate>();
EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
+
SpecializedSetup<cmds::TexParameterfvImmediate, 0>(false);
GLfloat temp[1] = {
GL_NEAREST,
};
cmd.Init(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, &temp[0]);
EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
+
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
@@ -246,12 +511,14 @@
cmds::TexParameterfvImmediate& cmd =
*GetImmediateAs<cmds::TexParameterfvImmediate>();
EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
+
SpecializedSetup<cmds::TexParameterfvImmediate, 0>(false);
GLfloat temp[1] = {
GL_NEAREST,
};
cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, &temp[0]);
EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
+
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
@@ -311,12 +578,14 @@
cmds::TexParameterivImmediate& cmd =
*GetImmediateAs<cmds::TexParameterivImmediate>();
EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
+
SpecializedSetup<cmds::TexParameterivImmediate, 0>(false);
GLint temp[1] = {
GL_NEAREST,
};
cmd.Init(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, &temp[0]);
EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
+
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
@@ -324,12 +593,14 @@
cmds::TexParameterivImmediate& cmd =
*GetImmediateAs<cmds::TexParameterivImmediate>();
EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
+
SpecializedSetup<cmds::TexParameterivImmediate, 0>(false);
GLint temp[1] = {
GL_NEAREST,
};
cmd.Init(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, &temp[0]);
EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
+
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
@@ -337,12 +608,14 @@
cmds::TexParameterivImmediate& cmd =
*GetImmediateAs<cmds::TexParameterivImmediate>();
EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
+
SpecializedSetup<cmds::TexParameterivImmediate, 0>(false);
GLint temp[1] = {
GL_NEAREST,
};
cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, &temp[0]);
EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
+
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
@@ -1006,35 +1279,17 @@
// TODO(gman): DeleteQueriesEXTImmediate
// TODO(gman): BeginQueryEXT
-// TODO(gman): EndQueryEXT
-
-// TODO(gman): InsertEventMarkerEXT
-
-// TODO(gman): PushGroupMarkerEXT
-
-TEST_P(GLES2DecoderTest2, PopGroupMarkerEXTValidArgs) {
- SpecializedSetup<cmds::PopGroupMarkerEXT, 0>(true);
- cmds::PopGroupMarkerEXT cmd;
- cmd.Init();
+TEST_P(GLES2DecoderTest2, BeginTransformFeedbackValidArgs) {
+ EXPECT_CALL(*gl_, BeginTransformFeedback(GL_POINTS));
+ SpecializedSetup<cmds::BeginTransformFeedback, 0>(true);
+ cmds::BeginTransformFeedback cmd;
+ cmd.Init(GL_POINTS);
+ decoder_->set_unsafe_es3_apis_enabled(true);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
}
-// TODO(gman): GenVertexArraysOESImmediate
-// TODO(gman): DeleteVertexArraysOESImmediate
-// TODO(gman): IsVertexArrayOES
-// TODO(gman): BindVertexArrayOES
-// TODO(gman): SwapBuffers
-// TODO(gman): GetMaxValueInBufferCHROMIUM
-// TODO(gman): EnableFeatureCHROMIUM
+// TODO(gman): EndQueryEXT
-// TODO(gman): ResizeCHROMIUM
-// TODO(gman): GetRequestableExtensionsCHROMIUM
-
-// TODO(gman): RequestExtensionCHROMIUM
-
-// TODO(gman): GetProgramInfoCHROMIUM
-
-// TODO(gman): GetTranslatedShaderSourceANGLE
-// TODO(gman): PostSubBufferCHROMIUM
-// TODO(gman): TexImageIOSurface2DCHROMIUM
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
index 6de18e0..506e045 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
@@ -12,6 +12,46 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_
+TEST_P(GLES2DecoderTest3, EndTransformFeedbackValidArgs) {
+ EXPECT_CALL(*gl_, EndTransformFeedback());
+ SpecializedSetup<cmds::EndTransformFeedback, 0>(true);
+ cmds::EndTransformFeedback cmd;
+ cmd.Init();
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+// TODO(gman): InsertEventMarkerEXT
+
+// TODO(gman): PushGroupMarkerEXT
+
+TEST_P(GLES2DecoderTest3, PopGroupMarkerEXTValidArgs) {
+ SpecializedSetup<cmds::PopGroupMarkerEXT, 0>(true);
+ cmds::PopGroupMarkerEXT cmd;
+ cmd.Init();
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+// TODO(gman): GenVertexArraysOESImmediate
+// TODO(gman): DeleteVertexArraysOESImmediate
+// TODO(gman): IsVertexArrayOES
+// TODO(gman): BindVertexArrayOES
+// TODO(gman): SwapBuffers
+// TODO(gman): GetMaxValueInBufferCHROMIUM
+// TODO(gman): EnableFeatureCHROMIUM
+
+// TODO(gman): ResizeCHROMIUM
+// TODO(gman): GetRequestableExtensionsCHROMIUM
+
+// TODO(gman): RequestExtensionCHROMIUM
+
+// TODO(gman): GetProgramInfoCHROMIUM
+
+// TODO(gman): GetTranslatedShaderSourceANGLE
+// TODO(gman): PostSubBufferCHROMIUM
+// TODO(gman): TexImageIOSurface2DCHROMIUM
// TODO(gman): CopyTextureCHROMIUM
// TODO(gman): DrawArraysInstancedANGLE
// TODO(gman): DrawElementsInstancedANGLE
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index 017f36c..aeb4477 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -90,7 +90,8 @@
client_framebuffer_id_(101),
client_program_id_(102),
client_renderbuffer_id_(103),
- client_shader_id_(104),
+ client_sampler_id_(104),
+ client_shader_id_(105),
client_texture_id_(106),
client_element_buffer_id_(107),
client_vertex_shader_id_(121),
@@ -98,6 +99,7 @@
client_query_id_(123),
client_vertexarray_id_(124),
client_valuebuffer_id_(125),
+ client_transformfeedback_id_(126),
service_renderbuffer_id_(0),
service_renderbuffer_valid_(false),
ignore_cached_state_for_test_(GetParam()),
@@ -413,6 +415,24 @@
DoCreateProgram(client_program_id_, kServiceProgramId);
DoCreateShader(GL_VERTEX_SHADER, client_shader_id_, kServiceShaderId);
+ // Unsafe commands.
+ bool reset_unsafe_es3_apis_enabled = false;
+ if (!decoder_->unsafe_es3_apis_enabled()) {
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ reset_unsafe_es3_apis_enabled = true;
+ }
+ EXPECT_CALL(*gl_, GenSamplers(_, _))
+ .WillOnce(SetArgumentPointee<1>(kServiceSamplerId))
+ .RetiresOnSaturation();
+ GenHelper<cmds::GenSamplersImmediate>(client_sampler_id_);
+ EXPECT_CALL(*gl_, GenTransformFeedbacks(_, _))
+ .WillOnce(SetArgumentPointee<1>(kServiceTransformFeedbackId))
+ .RetiresOnSaturation();
+ GenHelper<cmds::GenTransformFeedbacksImmediate>(client_transformfeedback_id_);
+ if (reset_unsafe_es3_apis_enabled) {
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ }
+
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
@@ -1245,12 +1265,14 @@
const GLuint GLES2DecoderTestBase::kServiceBufferId;
const GLuint GLES2DecoderTestBase::kServiceFramebufferId;
const GLuint GLES2DecoderTestBase::kServiceRenderbufferId;
+const GLuint GLES2DecoderTestBase::kServiceSamplerId;
const GLuint GLES2DecoderTestBase::kServiceTextureId;
const GLuint GLES2DecoderTestBase::kServiceProgramId;
const GLuint GLES2DecoderTestBase::kServiceShaderId;
const GLuint GLES2DecoderTestBase::kServiceElementBufferId;
const GLuint GLES2DecoderTestBase::kServiceQueryId;
const GLuint GLES2DecoderTestBase::kServiceVertexArrayId;
+const GLuint GLES2DecoderTestBase::kServiceTransformFeedbackId;
const int32 GLES2DecoderTestBase::kSharedMemoryId;
const size_t GLES2DecoderTestBase::kSharedBufferSize;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
index 459f1e0..6d6ddd2 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -131,6 +131,15 @@
return decoder_->GetQueryManager()->GetQuery(client_id);
}
+ bool GetSamplerServiceId(GLuint client_id, GLuint* service_id) const {
+ return group_->GetSamplerServiceId(client_id, service_id);
+ }
+
+ bool GetTransformFeedbackServiceId(
+ GLuint client_id, GLuint* service_id) const {
+ return group_->GetTransformFeedbackServiceId(client_id, service_id);
+ }
+
// This name doesn't match the underlying function, but doing it this way
// prevents the need to special-case the unit test generation
VertexAttribManager* GetVertexArrayInfo(GLuint client_id) {
@@ -427,10 +436,12 @@
static const GLuint kServiceRenderbufferId = 303;
static const GLuint kServiceTextureId = 304;
static const GLuint kServiceProgramId = 305;
- static const GLuint kServiceShaderId = 306;
+ static const GLuint kServiceSamplerId = 306;
+ static const GLuint kServiceShaderId = 307;
static const GLuint kServiceElementBufferId = 308;
static const GLuint kServiceQueryId = 309;
static const GLuint kServiceVertexArrayId = 310;
+ static const GLuint kServiceTransformFeedbackId = 311;
static const int32 kSharedMemoryId = 401;
static const size_t kSharedBufferSize = 2048;
@@ -520,6 +531,7 @@
GLuint client_framebuffer_id_;
GLuint client_program_id_;
GLuint client_renderbuffer_id_;
+ GLuint client_sampler_id_;
GLuint client_shader_id_;
GLuint client_texture_id_;
GLuint client_element_buffer_id_;
@@ -528,6 +540,7 @@
GLuint client_query_id_;
GLuint client_vertexarray_id_;
GLuint client_valuebuffer_id_;
+ GLuint client_transformfeedback_id_;
uint32 shared_memory_id_;
uint32 shared_memory_offset_;
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
index 3436e96..fc650d2 100644
--- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
@@ -49,6 +49,7 @@
ValueValidator<GLenum> render_buffer_parameter;
ValueValidator<GLenum> render_buffer_target;
ValueValidator<GLenum> reset_status;
+ValueValidator<GLenum> sampler_parameter;
ValueValidator<GLenum> shader_binary_format;
ValueValidator<GLenum> shader_parameter;
ValueValidator<GLenum> shader_precision;
@@ -69,6 +70,8 @@
ValueValidator<GLenum> texture_target;
ValueValidator<GLenum> texture_usage;
ValueValidator<GLenum> texture_wrap_mode;
+ValueValidator<GLenum> transform_feedback_bind_target;
+ValueValidator<GLenum> transform_feedback_primitive_mode;
ValueValidator<GLenum> value_buffer_target;
ValueValidator<GLint> vertex_attrib_size;
ValueValidator<GLenum> vertex_attrib_type;
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
index d718391..a1e5c74 100644
--- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -353,6 +353,18 @@
GL_UNKNOWN_CONTEXT_RESET_ARB,
};
+static const GLenum valid_sampler_parameter_table[] = {
+ GL_TEXTURE_MAG_FILTER,
+ GL_TEXTURE_MIN_FILTER,
+ GL_TEXTURE_MIN_LOD,
+ GL_TEXTURE_MAX_LOD,
+ GL_TEXTURE_WRAP_S,
+ GL_TEXTURE_WRAP_T,
+ GL_TEXTURE_WRAP_R,
+ GL_TEXTURE_COMPARE_MODE,
+ GL_TEXTURE_COMPARE_FUNC,
+};
+
static const GLenum valid_shader_parameter_table[] = {
GL_SHADER_TYPE,
GL_DELETE_STATUS,
@@ -502,6 +514,16 @@
GL_REPEAT,
};
+static const GLenum valid_transform_feedback_bind_target_table[] = {
+ GL_TRANSFORM_FEEDBACK,
+};
+
+static const GLenum valid_transform_feedback_primitive_mode_table[] = {
+ GL_POINTS,
+ GL_LINES,
+ GL_TRIANGLES,
+};
+
static const GLenum valid_value_buffer_target_table[] = {
GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM,
};
@@ -596,6 +618,8 @@
arraysize(valid_render_buffer_target_table)),
reset_status(valid_reset_status_table,
arraysize(valid_reset_status_table)),
+ sampler_parameter(valid_sampler_parameter_table,
+ arraysize(valid_sampler_parameter_table)),
shader_binary_format(),
shader_parameter(valid_shader_parameter_table,
arraysize(valid_shader_parameter_table)),
@@ -633,6 +657,12 @@
arraysize(valid_texture_usage_table)),
texture_wrap_mode(valid_texture_wrap_mode_table,
arraysize(valid_texture_wrap_mode_table)),
+ transform_feedback_bind_target(
+ valid_transform_feedback_bind_target_table,
+ arraysize(valid_transform_feedback_bind_target_table)),
+ transform_feedback_primitive_mode(
+ valid_transform_feedback_primitive_mode_table,
+ arraysize(valid_transform_feedback_primitive_mode_table)),
value_buffer_target(valid_value_buffer_target_table,
arraysize(valid_value_buffer_target_table)),
vertex_attrib_size(valid_vertex_attrib_size_table,
diff --git a/gpu/command_buffer/service/gpu_switches.cc b/gpu/command_buffer/service/gpu_switches.cc
index 7298140..a2d43e9 100644
--- a/gpu/command_buffer/service/gpu_switches.cc
+++ b/gpu/command_buffer/service/gpu_switches.cc
@@ -68,6 +68,14 @@
// Enable OpenGL ES 3 APIs without proper service side validation.
const char kEnableUnsafeES3APIs[] = "enable-unsafe-es3-apis";
+// Include ANGLE's intermediate representation (AST) output in shader
+// compilation info logs.
+const char kGLShaderIntermOutput[] = "gl-shader-interm-output";
+
+// Emulate ESSL lowp and mediump float precisions by mutating the shaders to
+// round intermediate values in ANGLE.
+const char kEmulateShaderPrecision[] = "emulate-shader-precision";
+
const char* kGpuSwitches[] = {
kCompileShaderAlwaysSucceeds,
kDisableGLErrorLimit,
@@ -86,6 +94,8 @@
kEnableShareGroupAsyncTextureUpload,
kEnableUnsafeES3APIs,
kEnableSubscribeUniformExtension,
+ kGLShaderIntermOutput,
+ kEmulateShaderPrecision,
};
const int kNumGpuSwitches = arraysize(kGpuSwitches);
diff --git a/gpu/command_buffer/service/gpu_switches.h b/gpu/command_buffer/service/gpu_switches.h
index c7a34f6..5ed2861 100644
--- a/gpu/command_buffer/service/gpu_switches.h
+++ b/gpu/command_buffer/service/gpu_switches.h
@@ -29,6 +29,8 @@
GPU_EXPORT extern const char kEnableSubscribeUniformExtension[];
GPU_EXPORT extern const char kEnableThreadedTextureMailboxes[];
GPU_EXPORT extern const char kEnableUnsafeES3APIs[];
+GPU_EXPORT extern const char kGLShaderIntermOutput[];
+GPU_EXPORT extern const char kEmulateShaderPrecision[];
GPU_EXPORT extern const char* kGpuSwitches[];
GPU_EXPORT extern const int kNumGpuSwitches;
diff --git a/gpu/command_buffer/service/shader_translator.cc b/gpu/command_buffer/service/shader_translator.cc
index 576c7c8..d7def00 100644
--- a/gpu/command_buffer/service/shader_translator.cc
+++ b/gpu/command_buffer/service/shader_translator.cc
@@ -14,7 +14,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
-#include "ui/gl/gl_switches.h"
+#include "gpu/command_buffer/service/gpu_switches.h"
namespace gpu {
namespace gles2 {
diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc
index b447c1a..8014746 100644
--- a/gpu/config/gpu_driver_bug_list_json.cc
+++ b/gpu/config/gpu_driver_bug_list_json.cc
@@ -19,7 +19,7 @@
{
"name": "gpu driver bug list",
// Please update the version number whenever you change this file.
- "version": "7.11",
+ "version": "7.12",
"entries": [
{
"id": 1,
@@ -1081,6 +1081,17 @@
"features": [
"gl_clear_broken"
]
+ },
+ {
+ "id": 96,
+ "description": "glBindFramebuffer sometimes requires a glBegin/End to take effect",
+ "cr_bugs": [435786],
+ "os": {
+ "type": "macosx"
+ },
+ "features": [
+ "gl_begin_gl_end_on_fbo_change_to_backbuffer"
+ ]
}
]
}
diff --git a/gpu/config/gpu_driver_bug_workaround_type.h b/gpu/config/gpu_driver_bug_workaround_type.h
index 841a470..77d721b 100644
--- a/gpu/config/gpu_driver_bug_workaround_type.h
+++ b/gpu/config/gpu_driver_bug_workaround_type.h
@@ -54,6 +54,8 @@
force_gl_finish_after_compositing) \
GPU_OP(FORCE_INTEGRATED_GPU, \
force_integrated_gpu) \
+ GPU_OP(GL_BEGIN_GL_END_ON_FBO_CHANGE_TO_BACKBUFFER, \
+ gl_begin_gl_end_on_fbo_change_to_backbuffer) \
GPU_OP(GL_CLEAR_BROKEN, \
gl_clear_broken) \
GPU_OP(INIT_GL_POSITION_IN_VERTEX_SHADER, \
diff --git a/gpu/tools/compositor_model_bench/compositor_model_bench.cc b/gpu/tools/compositor_model_bench/compositor_model_bench.cc
index 5108a87..375bce2 100644
--- a/gpu/tools/compositor_model_bench/compositor_model_bench.cc
+++ b/gpu/tools/compositor_model_bench/compositor_model_bench.cc
@@ -61,12 +61,12 @@
: current_sim_(NULL),
output_path_(output_path),
seconds_per_test_(seconds_per_test),
- weak_factory_(this),
display_(NULL),
window_(0),
gl_context_(NULL),
window_width_(WINDOW_WIDTH),
- window_height_(WINDOW_HEIGHT) {
+ window_height_(WINDOW_HEIGHT),
+ weak_factory_(this) {
}
~Simulator() {
@@ -344,12 +344,12 @@
// Amount of time to run each simulation
int seconds_per_test_;
// GUI data
- base::WeakPtrFactory<Simulator> weak_factory_;
Display* display_;
Window window_;
GLXContext gl_context_;
int window_width_;
int window_height_;
+ base::WeakPtrFactory<Simulator> weak_factory_;
};
int main(int argc, char* argv[]) {
diff --git a/mojo/converters/surfaces/surfaces_type_converters.cc b/mojo/converters/surfaces/surfaces_type_converters.cc
index 1a6ab99..4d563e1 100644
--- a/mojo/converters/surfaces/surfaces_type_converters.cc
+++ b/mojo/converters/surfaces/surfaces_type_converters.cc
@@ -158,7 +158,8 @@
tile_state->resource_id,
tile_state->tex_coord_rect.To<gfx::RectF>(),
tile_state->texture_size.To<gfx::Size>(),
- tile_state->swizzle_contents);
+ tile_state->swizzle_contents,
+ tile_state->nearest_neighbor);
break;
}
case MATERIAL_YUV_VIDEO_CONTENT: {
diff --git a/mojo/public/python/BUILD.gn b/mojo/public/python/BUILD.gn
index 51bd6eb..70c2dca 100644
--- a/mojo/public/python/BUILD.gn
+++ b/mojo/public/python/BUILD.gn
@@ -16,44 +16,40 @@
# GYP version: mojo.gyp:mojo_python_system
python_binary_module("system") {
python_base_module = "mojo"
- sources = [
+ cython_sources = [
"mojo/c_core.pxd",
"mojo/system.pyx",
]
- configs = [ "../build/config:mojo_sdk" ]
deps = [
":base",
"../c/environment",
- "../c/system",
+ "../c/system:for_shared_library",
"../cpp/environment:standalone",
"../cpp/system",
"../cpp/utility",
"../cpp/bindings:callback",
- "../platform/native:system",
]
}
python_binary_module("system_impl") {
python_base_module = "mojo"
- sources = [
+ cython_sources = [
"mojo/c_core.pxd",
"mojo/c_environment.pxd",
"mojo/system_impl.pyx",
]
- additional_sources = [
+ sources = [
"src/python_system_helper.cc",
"src/python_system_helper.h",
]
- configs = [ "../build/config:mojo_sdk" ]
deps = [
":base",
"../c/environment",
- "../c/system",
+ "../c/system:for_shared_library",
"../cpp/environment:standalone",
"../cpp/system",
"../cpp/utility",
"../cpp/bindings:callback",
- "../platform/native:system",
]
}
diff --git a/mojo/python/BUILD.gn b/mojo/python/BUILD.gn
index f96c2cc..8cbb5fa 100644
--- a/mojo/python/BUILD.gn
+++ b/mojo/python/BUILD.gn
@@ -16,7 +16,7 @@
# GYP version: mojo/mojo.gyp:mojo_python_embedder
python_binary_module("embedder") {
python_base_module = "mojo"
- sources = [
+ cython_sources = [
"system/mojo/embedder.pyx",
]
deps = [
@@ -38,7 +38,7 @@
python_binary_module("validation_util") {
python_base_module = "mojo/tests"
- sources = [
+ cython_sources = [
"system/mojo/tests/validation_util.pyx",
]
deps = [
diff --git a/mojo/services/surfaces/public/interfaces/quads.mojom b/mojo/services/surfaces/public/interfaces/quads.mojom
index 88006f7..52a667d 100644
--- a/mojo/services/surfaces/public/interfaces/quads.mojom
+++ b/mojo/services/surfaces/public/interfaces/quads.mojom
@@ -72,6 +72,7 @@
Size texture_size;
bool swizzle_contents;
uint32 resource_id;
+ bool nearest_neighbor;
};
struct StreamVideoQuadState {};
diff --git a/mojo/tools/roll/cc_strip_video.patch b/mojo/tools/roll/cc_strip_video.patch
index df14109..aefb753 100644
--- a/mojo/tools/roll/cc_strip_video.patch
+++ b/mojo/tools/roll/cc_strip_video.patch
@@ -1,8 +1,8 @@
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
-index c744c5b..16a1589 100644
+index 826e12c..13e974d 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
-@@ -212,13 +212,6 @@ component("cc") {
+@@ -213,13 +213,6 @@ component("cc") {
"layers/ui_resource_layer.h",
"layers/ui_resource_layer_impl.cc",
"layers/ui_resource_layer_impl.h",
@@ -16,7 +16,7 @@
"output/begin_frame_args.cc",
"output/begin_frame_args.h",
"output/bsp_tree.cc",
-@@ -453,8 +446,6 @@ component("cc") {
+@@ -456,8 +449,6 @@ component("cc") {
"resources/ui_resource_client.h",
"resources/ui_resource_request.cc",
"resources/ui_resource_request.h",
@@ -25,16 +25,16 @@
"resources/zero_copy_tile_task_worker_pool.cc",
"resources/zero_copy_tile_task_worker_pool.h",
"scheduler/begin_frame_source.cc",
-@@ -588,8 +579,6 @@ source_set("test_support") {
+@@ -590,8 +581,6 @@ source_set("test_support") {
"test/fake_tile_manager_client.h",
"test/fake_ui_resource_layer_tree_host_impl.cc",
"test/fake_ui_resource_layer_tree_host_impl.h",
- "test/fake_video_frame_provider.cc",
- "test/fake_video_frame_provider.h",
+ "test/failure_output_surface.cc",
+ "test/failure_output_surface.h",
"test/geometry_test_utils.cc",
- "test/geometry_test_utils.h",
- "test/test_in_process_context_provider.cc",
-@@ -744,7 +733,6 @@ test("cc_unittests") {
+@@ -747,7 +736,6 @@ test("cc_unittests") {
"layers/tiled_layer_unittest.cc",
"layers/ui_resource_layer_impl_unittest.cc",
"layers/ui_resource_layer_unittest.cc",
@@ -42,7 +42,7 @@
"output/begin_frame_args_unittest.cc",
"output/delegating_renderer_unittest.cc",
"output/filter_operations_unittest.cc",
-@@ -775,7 +763,6 @@ test("cc_unittests") {
+@@ -778,7 +766,6 @@ test("cc_unittests") {
"resources/texture_uploader_unittest.cc",
"resources/tile_manager_unittest.cc",
"resources/tile_priority_unittest.cc",
@@ -50,7 +50,7 @@
"scheduler/begin_frame_source_unittest.cc",
"scheduler/delay_based_time_source_unittest.cc",
"scheduler/scheduler_state_machine_unittest.cc",
-@@ -804,7 +791,6 @@ test("cc_unittests") {
+@@ -807,7 +794,6 @@ test("cc_unittests") {
"trees/layer_tree_host_unittest_picture.cc",
"trees/layer_tree_host_unittest_proxy.cc",
"trees/layer_tree_host_unittest_scroll.cc",
@@ -229,7 +229,7 @@
-
-} // namespace cc
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
-index 27f40eb..49af1c3 100644
+index ee94a4c..7896bb8 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -13,7 +13,6 @@
@@ -241,7 +241,7 @@
#include "cc/output/compositor_frame_metadata.h"
#include "cc/output/context_provider.h"
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
-index 0c2bc3d..d112ed1 100644
+index b51aef6..58205a9 100644
--- a/cc/output/renderer_pixeltest.cc
+++ b/cc/output/renderer_pixeltest.cc
@@ -12,7 +12,6 @@
@@ -252,7 +252,7 @@
#include "third_party/skia/include/core/SkColorPriv.h"
#include "third_party/skia/include/core/SkImageFilter.h"
#include "third_party/skia/include/core/SkMatrix.h"
-@@ -385,346 +384,6 @@ TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
+@@ -386,346 +385,6 @@ TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
FuzzyPixelOffByOneComparator(true)));
}
@@ -624,7 +624,7 @@
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkPicture.h"
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
-index f31cde0..4e070e2 100644
+index fc4780f..61bda89 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -27,7 +27,6 @@
@@ -667,7 +667,7 @@
}
LayerTreeSettings DefaultSettings() {
-@@ -5247,18 +5242,6 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
+@@ -5248,18 +5243,6 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
LayerImpl::Create(host_impl_->active_tree(), 1);
root_layer->SetBounds(gfx::Size(10, 10));
@@ -686,7 +686,7 @@
scoped_ptr<IOSurfaceLayerImpl> io_surface_layer =
IOSurfaceLayerImpl::Create(host_impl_->active_tree(), 5);
io_surface_layer->SetBounds(gfx::Size(10, 10));
-@@ -6321,16 +6304,6 @@ TEST_F(LayerTreeHostImplTest,
+@@ -6322,16 +6305,6 @@ TEST_F(LayerTreeHostImplTest,
scoped_ptr<SolidColorLayerImpl> root_layer =
SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
@@ -704,7 +704,7 @@
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
-index 712909f..51c5d7e 100644
+index a343466..eee6275 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -18,7 +18,6 @@
@@ -723,7 +723,7 @@
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_tree_test.h"
#include "cc/test/test_shared_bitmap_manager.h"
-@@ -4189,28 +4187,6 @@ class LayerInvalidateCausesDraw : public LayerTreeHostTest {
+@@ -4183,28 +4181,6 @@ class LayerInvalidateCausesDraw : public LayerTreeHostTest {
int num_draws_;
};
@@ -753,7 +753,7 @@
// to the compositor thread, even though no resources are updated in
// response to that invalidation.
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
-index 2d23d75..b646e6a 100644
+index 24ffcd4..cc4f28f 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -15,8 +15,6 @@
@@ -764,8 +764,8 @@
-#include "cc/layers/video_layer_impl.h"
#include "cc/output/filter_operations.h"
#include "cc/resources/single_release_callback.h"
- #include "cc/test/fake_content_layer.h"
-@@ -32,7 +30,6 @@
+ #include "cc/test/failure_output_surface.h"
+@@ -33,7 +31,6 @@
#include "cc/test/fake_picture_layer_impl.h"
#include "cc/test/fake_scoped_ui_resource.h"
#include "cc/test/fake_scrollbar.h"
@@ -773,7 +773,7 @@
#include "cc/test/layer_tree_test.h"
#include "cc/test/render_pass_test_common.h"
#include "cc/test/test_context_provider.h"
-@@ -42,9 +39,6 @@
+@@ -43,9 +40,6 @@
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/single_thread_proxy.h"
#include "gpu/GLES2/gl2extchromium.h"
@@ -783,7 +783,7 @@
namespace cc {
namespace {
-@@ -65,7 +59,6 @@ class LayerTreeHostContextTest : public LayerTreeTest {
+@@ -66,7 +60,6 @@ class LayerTreeHostContextTest : public LayerTreeTest {
context_should_support_io_surface_(false),
fallback_context_works_(false),
async_output_surface_creation_(false) {
@@ -791,7 +791,7 @@
}
void LoseContext() {
-@@ -1083,49 +1076,6 @@ class LayerTreeHostContextTestDontUseLostResources
+@@ -1041,49 +1034,6 @@ class LayerTreeHostContextTestDontUseLostResources
layer_with_mask->SetMaskLayer(mask.get());
root->AddChild(layer_with_mask);
@@ -841,7 +841,7 @@
if (!delegating_renderer()) {
// TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
scoped_refptr<IOSurfaceLayer> io_surface = IOSurfaceLayer::Create();
-@@ -1155,14 +1105,6 @@ class LayerTreeHostContextTestDontUseLostResources
+@@ -1113,14 +1063,6 @@ class LayerTreeHostContextTestDontUseLostResources
void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
LayerTreeHostContextTest::CommitCompleteOnThread(host_impl);
@@ -856,7 +856,7 @@
}
DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
-@@ -1212,14 +1154,6 @@ class LayerTreeHostContextTestDontUseLostResources
+@@ -1169,14 +1111,6 @@ class LayerTreeHostContextTestDontUseLostResources
scoped_refptr<DelegatedFrameResourceCollection>
delegated_resource_collection_;
scoped_refptr<DelegatedFrameProvider> delegated_frame_provider_;
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 4cecaef..c4c928e 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -566,6 +566,8 @@
"server/http_server_response_info.h",
"server/web_socket.cc",
"server/web_socket.h",
+ "server/web_socket_encoder.cc",
+ "server/web_socket_encoder.h",
]
configs += [
"//build/config/compiler:wexit_time_destructors",
@@ -677,6 +679,8 @@
"test/spawned_test_server/spawner_communicator.h",
"test/url_request/url_request_failed_job.cc",
"test/url_request/url_request_failed_job.h",
+ "test/url_request/url_request_mock_data_job.cc",
+ "test/url_request/url_request_mock_data_job.h",
"test/url_request/url_request_mock_http_job.cc",
"test/url_request/url_request_mock_http_job.h",
"url_request/test_url_fetcher_factory.cc",
@@ -1247,6 +1251,10 @@
if (!enable_websockets) {
sources -= [
+ "server/http_connection_unittest.cc",
+ "server/http_server_response_info_unittest.cc",
+ "server/http_server_unittest.cc",
+ "server/web_socket_encoder_unittest.cc",
"websockets/websocket_basic_stream_test.cc",
"websockets/websocket_channel_test.cc",
"websockets/websocket_deflate_predictor_impl_test.cc",
@@ -1263,6 +1271,7 @@
"websockets/websocket_test_util.cc",
"websockets/websocket_test_util.h",
]
+ deps -= [ ":http_server" ]
}
if (disable_file_support) {
diff --git a/net/base/filename_util_unittest.cc b/net/base/filename_util_unittest.cc
index 391baeb..0e7d504 100644
--- a/net/base/filename_util_unittest.cc
+++ b/net/base/filename_util_unittest.cc
@@ -48,6 +48,25 @@
#endif
}
+std::string GetLocaleWarningString() {
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ // The generate filename tests can fail on certain OS_POSIX platforms when
+ // LC_CTYPE is not "utf8" or "utf-8" because some of the string conversions
+ // fail.
+ // This warning text is appended to any test failures to save people time if
+ // this happens to be the cause of failure :)
+ // Note: some platforms (MACOSX, Chromecast) don't have this problem:
+ // setlocale returns "c" but it functions as utf8. And Android doesn't
+ // have setlocale at all.
+ std::string locale = setlocale(LC_CTYPE, NULL);
+ return " this test may have failed because the current LC_CTYPE locale is "
+ "not utf8 (currently set to " +
+ locale + ")";
+#else
+ return "";
+#endif
+}
+
void RunGenerateFileNameTestCase(const GenerateFilenameCase* test_case) {
std::string default_filename(base::WideToUTF8(test_case->default_filename));
base::FilePath file_path = GenerateFileName(
@@ -55,7 +74,8 @@
test_case->referrer_charset, test_case->suggested_filename,
test_case->mime_type, default_filename);
EXPECT_EQ(test_case->expected_filename, FilePathAsWString(file_path))
- << "test case at line number: " << test_case->lineno;
+ << "test case at line number: " << test_case->lineno << "; "
+ << GetLocaleWarningString();
}
} // namespace
@@ -418,18 +438,6 @@
}
TEST(FilenameUtilTest, GenerateFileName) {
-#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
- // This test doesn't run when the locale is not UTF-8 because some of the
- // string conversions fail. This is OK (we have the default value) but they
- // don't match our expectations.
- std::string locale = setlocale(LC_CTYPE, NULL);
- base::StringToLowerASCII(&locale);
- EXPECT_TRUE(locale.find("utf-8") != std::string::npos ||
- locale.find("utf8") != std::string::npos)
- << "Your locale (" << locale << ") must be set to UTF-8 "
- << "for this test to pass!";
-#endif
-
// Tests whether the correct filename is selected from the the given
// parameters and that Content-Disposition headers are properly
// handled including failovers when the header is malformed.
diff --git a/net/base/net_log_util.cc b/net/base/net_log_util.cc
index 3b437aa..75be128 100644
--- a/net/base/net_log_util.cc
+++ b/net/base/net_log_util.cc
@@ -33,6 +33,7 @@
#include "net/proxy/proxy_service.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_utils.h"
+#include "net/socket/ssl_client_socket.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
@@ -447,10 +448,17 @@
"force_spdy_always",
http_network_session->params().force_spdy_always);
- std::vector<std::string> next_protos;
+ NextProtoVector next_protos;
http_network_session->GetNextProtos(&next_protos);
- std::string next_protos_string = JoinString(next_protos, ',');
- status_dict->SetString("next_protos", next_protos_string);
+ if (!next_protos.empty()) {
+ std::string next_protos_string;
+ for (const NextProto proto : next_protos) {
+ if (!next_protos_string.empty())
+ next_protos_string.append(",");
+ next_protos_string.append(SSLClientSocket::NextProtoToString(proto));
+ }
+ status_dict->SetString("next_protos", next_protos_string);
+ }
net_info_dict->Set(NetInfoSourceToString(NET_INFO_SPDY_STATUS),
status_dict);
diff --git a/net/data/proxy_resolver_v8_unittest/pac_library_unittest.js b/net/data/proxy_resolver_v8_unittest/pac_library_unittest.js
index 0c0a4a9..58de402 100644
--- a/net/data/proxy_resolver_v8_unittest/pac_library_unittest.js
+++ b/net/data/proxy_resolver_v8_unittest/pac_library_unittest.js
@@ -1,3 +1,7 @@
+// Copyright (c) 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.
+
// This should output "PROXY success:80" if all the tests pass.
// Otherwise it will output "PROXY failure:<num-failures>".
//
@@ -61,6 +65,56 @@
Tests.testIsPlainHostName = function(t) {
t.expectTrue(isPlainHostName("google"));
t.expectFalse(isPlainHostName("google.com"));
+ t.expectFalse(isPlainHostName("192.168.1.1"));
+ t.expectFalse(isPlainHostName("."));
+ t.expectFalse(isPlainHostName(".:"));
+
+ // Valid IPv6 address
+ t.expectFalse(isPlainHostName("::1"));
+
+ // Not a valid IPv6 address
+ t.expectTrue(isPlainHostName("foopy::1"));
+ t.expectTrue(isPlainHostName("foo:112"));
+ t.expectTrue(isPlainHostName(":"));
+ t.expectTrue(isPlainHostName("[:]"));
+
+ // Not considered a valid IPv6 address because of surrounding brackets.
+ t.expectTrue(isPlainHostName("[::1]"));
+
+ // Calling with more than 1 argument is allowed.
+ t.expectTrue(isPlainHostName("foo", "foo", "foo"));
+
+ // Calling with no arguments is an error.
+ try {
+ isPlainHostName();
+ t.expectTrue(false); // Not reached.
+ } catch (e) {
+ t.expectEquals('TypeError: Requires 1 string parameter', e.toString());
+ }
+
+ // Calling with the wrong argument type is an error.
+ try {
+ isPlainHostName(null);
+ t.expectTrue(false); // Not reached.
+ } catch (e) {
+ t.expectEquals('TypeError: Requires 1 string parameter', e.toString());
+ }
+
+ // Calling with the wrong argument type is an error.
+ try {
+ isPlainHostName(1);
+ t.expectTrue(false); // Not reached.
+ } catch (e) {
+ t.expectEquals('TypeError: Requires 1 string parameter', e.toString());
+ }
+
+ // Calling with the wrong argument type is an error.
+ try {
+ isPlainHostName(function() {});
+ t.expectTrue(false); // Not reached.
+ } catch (e) {
+ t.expectEquals('TypeError: Requires 1 string parameter', e.toString());
+ }
};
Tests.testLocalHostOrDomainIs = function(t) {
diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc
index 843a619..3b1f669 100644
--- a/net/disk_cache/backend_unittest.cc
+++ b/net/disk_cache/backend_unittest.cc
@@ -6,6 +6,7 @@
#include "base/files/file_util.h"
#include "base/metrics/field_trial.h"
#include "base/port.h"
+#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
@@ -3282,6 +3283,10 @@
entry->Close();
entry = NULL;
+ // The entry is being closed on the Simple Cache worker pool
+ disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
+ base::RunLoop().RunUntilIdle();
+
// Write an invalid header for stream 0 and stream 1.
base::FilePath entry_file1_path = cache_path_.AppendASCII(
disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0));
diff --git a/net/disk_cache/blockfile/stress_cache.cc b/net/disk_cache/blockfile/stress_cache.cc
index f28e8af..d43cb74 100644
--- a/net/disk_cache/blockfile/stress_cache.cc
+++ b/net/disk_cache/blockfile/stress_cache.cc
@@ -27,7 +27,6 @@
#include "base/path_service.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
-#include "base/process/process_handle.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -59,14 +58,14 @@
base::CommandLine cmdline(exe);
cmdline.AppendArg(base::IntToString(iteration));
- base::ProcessHandle handle;
- if (!base::LaunchProcess(cmdline, base::LaunchOptions(), &handle)) {
+ base::Process process = base::LaunchProcess(cmdline, base::LaunchOptions());
+ if (!process.IsValid()) {
printf("Unable to run test\n");
return kError;
}
int exit_code;
- if (!base::WaitForExitCode(handle, &exit_code)) {
+ if (!process.WaitForExit(&exit_code)) {
printf("Unable to get return code\n");
return kError;
}
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
index 656db54..405c88c 100644
--- a/net/http/http_network_session.cc
+++ b/net/http/http_network_session.cc
@@ -26,6 +26,7 @@
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_pool_manager_impl.h"
#include "net/socket/next_proto.h"
+#include "net/socket/ssl_client_socket.h"
#include "net/spdy/hpack_huffman_aggregator.h"
#include "net/spdy/spdy_session_pool.h"
@@ -166,7 +167,7 @@
// Add the protocol to the TLS next protocol list, except for QUIC
// since it uses UDP.
if (proto != kProtoQUIC1SPDY3) {
- next_protos_.push_back(SSLClientSocket::NextProtoToString(proto));
+ next_protos_.push_back(proto);
}
// Enable the corresponding alternate protocol, except for HTTP
@@ -284,8 +285,7 @@
protocol - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION];
}
-void HttpNetworkSession::GetNextProtos(
- std::vector<std::string>* next_protos) const {
+void HttpNetworkSession::GetNextProtos(NextProtoVector* next_protos) const {
if (HttpStreamFactory::spdy_enabled()) {
*next_protos = next_protos_;
} else {
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index bf93c83..c9704a4 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -205,7 +205,8 @@
bool IsProtocolEnabled(AlternateProtocol protocol) const;
- void GetNextProtos(std::vector<std::string>* next_protos) const;
+ // Populates |*next_protos| with protocols.
+ void GetNextProtos(NextProtoVector* next_protos) const;
// Convenience function for searching through |params_| for
// |forced_spdy_exclusions|.
@@ -242,7 +243,7 @@
// TODO(jgraettinger): Remove when Huffman collection is complete.
scoped_ptr<HpackHuffmanAggregator> huffman_aggregator_;
- std::vector<std::string> next_protos_;
+ NextProtoVector next_protos_;
bool enabled_protocols_[NUM_VALID_ALTERNATE_PROTOCOLS];
Params params_;
diff --git a/net/http/transport_security_state_static.h b/net/http/transport_security_state_static.h
index 4c09bec..3c59a75 100644
--- a/net/http/transport_security_state_static.h
+++ b/net/http/transport_security_state_static.h
@@ -2060,297 +2060,296 @@
0x15, 0xcf, 0xf7, 0x1d, 0xd6, 0x29, 0xba, 0x86,
0x8a, 0xe2, 0x1c, 0x7f, 0x5a, 0x6b, 0x3d, 0x79,
0xdc, 0x1d, 0x3f, 0xaf, 0xc3, 0xff, 0xfd, 0xd0,
- 0xe9, 0x37, 0x40, 0x7a, 0xb4, 0x20, 0x9f, 0xfb,
- 0x7c, 0xff, 0x06, 0x3b, 0xc8, 0xd9, 0xd3, 0xeb,
- 0xf7, 0x23, 0x67, 0x4e, 0xc5, 0x3d, 0x93, 0xe9,
- 0xc2, 0x1c, 0xf8, 0x53, 0x75, 0x0d, 0x14, 0xf4,
- 0xfd, 0x74, 0xe0, 0x1a, 0xf3, 0xa3, 0x8d, 0x4c,
- 0x99, 0x61, 0x2b, 0x66, 0x80, 0x61, 0x3f, 0xfb,
- 0x5e, 0xee, 0x43, 0x7e, 0xa5, 0x17, 0xf3, 0xa1,
- 0xc8, 0x90, 0xe5, 0x16, 0x73, 0xb9, 0xb3, 0xa7,
- 0xca, 0xff, 0xfb, 0x79, 0xd3, 0xc9, 0xba, 0x86,
- 0x8a, 0xce, 0x1a, 0x3d, 0x41, 0x29, 0x9f, 0xaa,
- 0x62, 0x83, 0xe8, 0x74, 0xe5, 0xab, 0xc7, 0x4f,
- 0xb1, 0xff, 0x50, 0x79, 0xd3, 0xbb, 0xda, 0x1d,
- 0x3e, 0xb6, 0xaa, 0xef, 0xf3, 0xa4, 0xeb, 0x46,
- 0xe0, 0x91, 0x64, 0xb7, 0x47, 0x00, 0xab, 0xa8,
- 0xe4, 0xff, 0xce, 0xd7, 0xba, 0xc5, 0x37, 0x50,
- 0xd1, 0x22, 0xcf, 0xe7, 0x58, 0xa6, 0xea, 0x1a,
- 0x2c, 0x99, 0xfc, 0xeb, 0x14, 0xdd, 0x43, 0x45,
- 0xb1, 0x3a, 0xe9, 0x67, 0x4f, 0x85, 0x37, 0x50,
- 0xd1, 0x6d, 0xc9, 0xcf, 0x3c, 0xab, 0x1a, 0x9d,
- 0x56, 0x7c, 0x74, 0xff, 0xb8, 0xde, 0x35, 0xb8,
- 0x63, 0x36, 0x0b, 0xf9, 0xd3, 0xf2, 0x83, 0xf9,
- 0xed, 0x87, 0x4f, 0x85, 0x37, 0x50, 0xd1, 0x78,
- 0x4f, 0x63, 0x8a, 0xf2, 0x74, 0xff, 0xcb, 0xd5,
- 0x95, 0xbf, 0x16, 0x18, 0xa1, 0xd3, 0xeb, 0x0f,
- 0xdb, 0xd4, 0xe9, 0xf2, 0xf5, 0xef, 0x68, 0x74,
- 0xec, 0x2f, 0xe7, 0x49, 0xdc, 0x6a, 0x74, 0x2d,
- 0xc6, 0x8e, 0xd4, 0x9d, 0x65, 0xd5, 0x98, 0x64,
- 0x93, 0xf4, 0x60, 0x29, 0xc1, 0x4c, 0xef, 0x5d,
- 0x67, 0x4f, 0x85, 0x37, 0x50, 0xd1, 0x7a, 0x4f,
- 0xf8, 0x37, 0x0f, 0x5e, 0x98, 0xf5, 0x47, 0x4f,
- 0xad, 0x99, 0xde, 0x4e, 0x93, 0xb9, 0x45, 0x9d,
- 0x8e, 0x75, 0x30, 0x6f, 0x40, 0x85, 0x64, 0x87,
- 0xd5, 0x0b, 0x5b, 0x94, 0x58, 0x84, 0x9e, 0x8d,
- 0x30, 0x56, 0xd8, 0x99, 0xf9, 0xd8, 0x42, 0x17,
- 0xb8, 0xf2, 0x3e, 0x8d, 0x1e, 0x6e, 0xf2, 0x74,
- 0xf5, 0xe7, 0x70, 0x74, 0xfe, 0xbf, 0x0f, 0xff,
- 0xf7, 0x43, 0xa4, 0xdd, 0x01, 0xea, 0xd0, 0x82,
- 0x7d, 0xec, 0x2d, 0x75, 0x1d, 0x3e, 0x14, 0xdd,
- 0x43, 0x44, 0x47, 0x3f, 0xfd, 0x9e, 0xe9, 0x4b,
- 0x60, 0x5b, 0x6e, 0x0a, 0xdd, 0x8e, 0x9f, 0xf3,
- 0xd6, 0xa1, 0xbc, 0x63, 0xd8, 0x3a, 0x7f, 0xff,
- 0x97, 0x3b, 0xec, 0x2e, 0x42, 0xf1, 0x9f, 0x66,
- 0xfd, 0xf1, 0xd3, 0x54, 0xc2, 0xa6, 0xfb, 0xe2,
- 0xa7, 0xfe, 0x7b, 0x93, 0x3e, 0x6b, 0x2b, 0x53,
- 0xbf, 0x35, 0xff, 0x0b, 0xcf, 0xeb, 0xe3, 0x85,
- 0xe7, 0x70, 0x74, 0xff, 0xfc, 0x8e, 0x1d, 0x0f,
- 0x61, 0xc2, 0xb8, 0x0d, 0xfc, 0xe8, 0xe3, 0x15,
- 0x83, 0x71, 0xad, 0x8a, 0x59, 0x65, 0x28, 0x61,
- 0x5a, 0xc8, 0x9f, 0x6c, 0x25, 0x30, 0xbe, 0xd8,
- 0xd2, 0x7c, 0x29, 0xba, 0x86, 0x88, 0xba, 0x7d,
- 0x8f, 0xfa, 0x83, 0xcb, 0x67, 0xb2, 0x4e, 0xb3,
- 0xe8, 0xd3, 0x08, 0x72, 0x65, 0x0f, 0x8c, 0x0a,
- 0x7f, 0xe6, 0x6b, 0xdd, 0x62, 0x9b, 0xa8, 0x68,
- 0x99, 0xa7, 0x56, 0xb4, 0x3a, 0x72, 0x79, 0x87,
- 0x4d, 0xc4, 0xdd, 0xce, 0x9f, 0xb1, 0x75, 0x5f,
- 0xed, 0x1d, 0x0d, 0xdc, 0xf3, 0x9a, 0x1f, 0x9f,
- 0x26, 0xe7, 0xcd, 0x1d, 0x3f, 0xf3, 0x7f, 0xb1,
- 0xe4, 0xf7, 0x38, 0xb4, 0x3a, 0x7f, 0xff, 0xbb,
- 0xd0, 0x40, 0xbe, 0x73, 0xdf, 0x0c, 0xab, 0xc5,
- 0x6a, 0x3a, 0x2d, 0x15, 0xf9, 0x47, 0x9f, 0xff,
- 0x73, 0xe0, 0xaa, 0xe9, 0xed, 0xcb, 0xbe, 0xfb,
- 0xe2, 0xa7, 0x93, 0x75, 0x0d, 0x16, 0x7c, 0xff,
- 0xbd, 0x95, 0x7f, 0xb0, 0xb8, 0xa1, 0xd3, 0xff,
- 0xde, 0x1c, 0xef, 0x0b, 0x6c, 0x17, 0x4b, 0x03,
- 0xa7, 0x7d, 0xf7, 0xc5, 0x4f, 0xfb, 0x5f, 0x40,
- 0xb4, 0xe6, 0xc4, 0xa7, 0x17, 0xf3, 0xfc, 0xb9,
- 0xf7, 0x21, 0xba, 0xd1, 0xd3, 0xfd, 0xe0, 0xe7,
- 0xaf, 0x3d, 0xe2, 0x87, 0x42, 0x27, 0xe2, 0x2b,
- 0x4c, 0x2b, 0xc9, 0xf7, 0xed, 0xd8, 0x4a, 0x6c,
- 0x71, 0x3f, 0xc3, 0xbf, 0x67, 0xca, 0x2a, 0x74,
- 0xff, 0xff, 0xfd, 0x77, 0xfd, 0x2e, 0xc3, 0xa7,
- 0x51, 0x05, 0xbc, 0xba, 0x81, 0x75, 0x32, 0xd8,
- 0x74, 0xea, 0x2d, 0x47, 0x4e, 0xe2, 0xbc, 0x9d,
- 0x0f, 0x46, 0x15, 0x21, 0x11, 0x81, 0xc9, 0xea,
- 0xff, 0xed, 0x0e, 0x9f, 0x64, 0x16, 0xc4, 0xc9,
- 0xff, 0x78, 0x5f, 0x63, 0x57, 0x7b, 0xc9, 0xa2,
- 0x0d, 0x71, 0xa4, 0x9f, 0x6a, 0x79, 0x8a, 0x74,
- 0xfc, 0xfc, 0x86, 0xd7, 0x83, 0xa5, 0x68, 0x7a,
- 0x40, 0x4b, 0x3f, 0xff, 0xed, 0xfb, 0x17, 0x9c,
- 0x2d, 0x85, 0x78, 0xb1, 0xf5, 0x5a, 0xc3, 0xa1,
- 0xe9, 0x9f, 0x5c, 0x2b, 0x80, 0x96, 0x7e, 0x1b,
- 0xe6, 0x99, 0x53, 0xa7, 0xff, 0xf7, 0x61, 0xbd,
- 0x38, 0x75, 0x0d, 0xc5, 0x3d, 0x5e, 0x7d, 0xf1,
- 0xd3, 0xff, 0xfd, 0x4a, 0x28, 0xe1, 0x5c, 0xcb,
- 0xc5, 0x3a, 0xd3, 0x5f, 0x67, 0x4f, 0x66, 0xfc,
- 0xd8, 0xe8, 0xf2, 0x22, 0x72, 0xcd, 0x33, 0x1b,
- 0xa3, 0x45, 0xf9, 0x3f, 0xf3, 0xf1, 0xdb, 0xde,
- 0xcc, 0x61, 0x58, 0x74, 0xff, 0xde, 0xb0, 0xbb,
- 0xa7, 0x07, 0xd1, 0x87, 0x45, 0x68, 0x8a, 0xa2,
- 0x34, 0xde, 0x68, 0xe9, 0xd8, 0xf5, 0x47, 0x4e,
- 0x05, 0x43, 0xa3, 0x81, 0xe6, 0xb0, 0x5c, 0x07,
- 0x61, 0x53, 0x76, 0xe4, 0x8e, 0xe1, 0x65, 0xae,
- 0x33, 0xff, 0xff, 0x37, 0xae, 0x7c, 0xc7, 0x34,
- 0xfd, 0x1e, 0xb9, 0xf5, 0x74, 0x4f, 0x54, 0x74,
- 0xf7, 0xdb, 0x74, 0x3a, 0x7f, 0x9e, 0xcd, 0x7e,
- 0x28, 0xbd, 0x0e, 0x85, 0x3d, 0xbd, 0x21, 0x9e,
- 0xba, 0x78, 0x0e, 0x80, 0x3c, 0x0e, 0xc8, 0x27,
- 0xba, 0xf7, 0xb4, 0x3a, 0x7f, 0xd8, 0xa7, 0xfe,
- 0xae, 0xb7, 0xde, 0x0e, 0x85, 0x3e, 0x6b, 0x24,
- 0x99, 0xae, 0xce, 0x93, 0x0e, 0x8a, 0xcd, 0x43,
- 0x72, 0x31, 0x3f, 0xb7, 0x6b, 0x78, 0x2f, 0x27,
- 0x4f, 0xff, 0xfb, 0x3e, 0xaf, 0x17, 0x5e, 0x04,
- 0x57, 0x1f, 0xf5, 0x07, 0xe6, 0xce, 0x9d, 0xf7,
- 0xdf, 0x15, 0x3d, 0xcf, 0x3a, 0x05, 0x38, 0xbf,
- 0x9f, 0xf6, 0xe5, 0x3d, 0xbc, 0x29, 0xb9, 0x3a,
- 0x15, 0x35, 0x6e, 0x49, 0xd0, 0xcb, 0xd0, 0x8e,
- 0xc9, 0x8c, 0xff, 0xd6, 0x15, 0xe2, 0xc7, 0xd5,
- 0x6b, 0x0e, 0x9f, 0x5e, 0x1e, 0xcc, 0x9d, 0x3e,
- 0xae, 0x80, 0xac, 0x3a, 0x15, 0x12, 0x34, 0x43,
- 0xec, 0x9e, 0x6f, 0xf2, 0x74, 0xfd, 0x53, 0x4f,
- 0xe3, 0x46, 0xa3, 0xa7, 0xf7, 0x4c, 0xde, 0x33,
- 0xec, 0x1d, 0x37, 0x84, 0xe8, 0x6e, 0xe7, 0xff,
- 0xe3, 0x5c, 0x9a, 0xcf, 0xfd, 0xca, 0xf2, 0x2b,
- 0x8f, 0x27, 0xb9, 0x3a, 0x7e, 0xcf, 0x75, 0x35,
- 0x9f, 0x1d, 0x1c, 0x9f, 0xb6, 0x51, 0x64, 0xee,
- 0x31, 0x9e, 0xd0, 0xdc, 0x07, 0x15, 0xa6, 0xa2,
- 0x9e, 0x61, 0xad, 0x72, 0x84, 0xfa, 0x33, 0x57,
- 0x0f, 0x8f, 0x1a, 0xb5, 0x1c, 0x30, 0x9a, 0x30,
- 0xb3, 0x32, 0x9a, 0x35, 0x07, 0xf8, 0xc5, 0x42,
- 0x11, 0x14, 0x8e, 0x7b, 0x10, 0xe0, 0xf8, 0xc3,
- 0x8a, 0x12, 0xdd, 0x61, 0x57, 0x0e, 0x6c, 0x4a,
- 0x73, 0x4f, 0xb4, 0x9f, 0xfc, 0xe6, 0x6b, 0xdd,
- 0x62, 0x9b, 0xa8, 0x68, 0x9b, 0x27, 0xf3, 0xac,
- 0x53, 0x75, 0x0d, 0x15, 0x6c, 0xfe, 0x7b, 0xfb,
- 0xc0, 0x2b, 0xce, 0x9e, 0xbc, 0xee, 0x0e, 0x93,
- 0x75, 0x67, 0xa6, 0x06, 0x73, 0xe1, 0x4d, 0xd4,
- 0x34, 0x56, 0x93, 0xff, 0xc8, 0xa3, 0x7f, 0xeb,
- 0x35, 0xeb, 0xe4, 0x3a, 0x7f, 0xf9, 0xf4, 0xb0,
- 0x56, 0x6d, 0xe3, 0x0a, 0xc3, 0xa6, 0xc6, 0x15,
- 0x12, 0xfa, 0x97, 0x3f, 0x95, 0xb7, 0x5c, 0x02,
- 0xfe, 0x74, 0xfd, 0x55, 0xe7, 0xd6, 0xc3, 0xa7,
- 0xfa, 0xdb, 0xc1, 0x7e, 0xad, 0xf4, 0x3a, 0x7f,
- 0x3e, 0xf1, 0xa1, 0xff, 0x67, 0x49, 0xdc, 0x6a,
- 0x7e, 0x36, 0x57, 0xe8, 0x63, 0xe4, 0xb7, 0x4d,
- 0x80, 0xb7, 0x07, 0x93, 0xf9, 0xd6, 0x29, 0xba,
- 0x86, 0x8b, 0x02, 0x7c, 0x29, 0xba, 0x86, 0x89,
- 0xd6, 0x7f, 0xff, 0x65, 0x6a, 0xe6, 0xd8, 0xea,
- 0x52, 0xf3, 0xea, 0x77, 0x51, 0xd3, 0xe7, 0x33,
- 0x5e, 0xeb, 0x44, 0xab, 0x46, 0x13, 0xe1, 0x4d,
- 0xd4, 0x34, 0x5b, 0x33, 0xfe, 0xfd, 0x68, 0xec,
- 0xf9, 0x34, 0x4e, 0x93, 0xac, 0xfb, 0x74, 0xc2,
- 0x79, 0x37, 0x50, 0xd1, 0x73, 0x49, 0x87, 0x4c,
- 0xeb, 0x13, 0x77, 0xf1, 0x5c, 0xfe, 0x75, 0x8a,
- 0x6e, 0xa1, 0xa2, 0xef, 0x9e, 0x77, 0x4e, 0x7f,
- 0x3a, 0x15, 0xb7, 0x32, 0xba, 0xc5, 0x4d, 0x0c,
- 0x6b, 0x52, 0xf4, 0xa7, 0xf1, 0x72, 0x64, 0x34,
- 0x3f, 0x85, 0x6d, 0x18, 0x70, 0x59, 0xd4, 0xee,
- 0x7f, 0xc1, 0xae, 0x5a, 0x51, 0x9a, 0xf3, 0xa7,
- 0xf0, 0x55, 0x6d, 0xf8, 0x5e, 0x87, 0x4f, 0x85,
- 0x37, 0x50, 0xd1, 0x2b, 0xcf, 0xf8, 0x37, 0xee,
- 0x72, 0xb5, 0x5f, 0xc7, 0x4f, 0x77, 0xa2, 0xf3,
- 0xa7, 0xff, 0xf7, 0xb1, 0xac, 0xd0, 0xff, 0x3f,
- 0x68, 0x54, 0x9e, 0xa8, 0xe8, 0xe5, 0x10, 0x7a,
- 0x43, 0x1c, 0xa3, 0x9b, 0x30, 0xc3, 0x9d, 0xaf,
- 0x72, 0xa6, 0xed, 0x66, 0xf4, 0x8c, 0x5a, 0x76,
- 0x17, 0x92, 0xa7, 0xff, 0x67, 0x7d, 0x85, 0x7f,
- 0x86, 0xae, 0xff, 0x2a, 0x7f, 0x6a, 0x3b, 0x91,
- 0x6e, 0x5c, 0xa7, 0xd1, 0x41, 0xc9, 0x39, 0x15,
- 0x57, 0x32, 0x3b, 0x26, 0xd0, 0xae, 0x9f, 0xfc,
- 0xe6, 0x6b, 0xdd, 0x62, 0x9b, 0xa8, 0x68, 0x98,
- 0x67, 0xff, 0xeb, 0x77, 0x51, 0xdf, 0xdd, 0xd3,
- 0x0f, 0xf9, 0x68, 0xf3, 0xa7, 0xfe, 0x6e, 0xae,
- 0xb7, 0xf7, 0xb8, 0x05, 0x79, 0xd3, 0xf9, 0x76,
- 0xac, 0x74, 0xd1, 0x3a, 0x7d, 0xa2, 0xfd, 0x61,
- 0xd0, 0x07, 0xb1, 0xd9, 0x9c, 0xfc, 0xc5, 0xb0,
- 0xc7, 0x11, 0xd3, 0xe5, 0xb0, 0xc7, 0x11, 0xd3,
- 0xf6, 0x7d, 0x8a, 0x6d, 0x7c, 0x0f, 0x59, 0x85,
- 0xd3, 0xff, 0xfe, 0x0b, 0xf9, 0xbf, 0x17, 0x9e,
- 0x01, 0x75, 0x7a, 0xc2, 0xb7, 0xd0, 0xe9, 0xf9,
- 0xb7, 0x5c, 0x02, 0xfe, 0x74, 0xff, 0xe5, 0xc7,
- 0xea, 0xfb, 0xaf, 0x15, 0x77, 0xf1, 0xd0, 0xa7,
- 0xff, 0xe3, 0x19, 0xfa, 0x9e, 0xe8, 0xcd, 0xc1,
- 0xd3, 0xff, 0xfe, 0x1b, 0x6c, 0xa1, 0x8e, 0x1d,
- 0x41, 0x73, 0xbe, 0xc2, 0xe2, 0x87, 0x4a, 0xeb,
- 0x44, 0xe8, 0x97, 0xcf, 0xff, 0xb2, 0x17, 0x8c,
- 0xfa, 0xeb, 0xc5, 0xb6, 0x5a, 0x1d, 0x39, 0x7f,
- 0xea, 0x74, 0x59, 0xfa, 0x02, 0xb4, 0xf6, 0xf5,
- 0xe6, 0xce, 0x93, 0xb8, 0xd5, 0x7d, 0xdc, 0xc2,
- 0x85, 0x1e, 0x1a, 0x48, 0xcc, 0x3c, 0x02, 0x17,
- 0xd8, 0x84, 0xe7, 0x64, 0x13, 0xe1, 0x4d, 0xd4,
- 0x34, 0x55, 0xd3, 0xfc, 0xf7, 0x58, 0xa6, 0xea,
- 0x1a, 0x23, 0xc9, 0x3a, 0xcf, 0xc7, 0x4c, 0x27,
- 0xf3, 0xac, 0x53, 0x75, 0x0d, 0x16, 0x0c, 0xfe,
- 0x75, 0x8a, 0x6e, 0xa1, 0xa2, 0xca, 0x9f, 0xce,
- 0xb1, 0x4d, 0xd4, 0x34, 0x5a, 0x73, 0xc9, 0xba,
- 0x86, 0x8b, 0x72, 0x7f, 0xe5, 0xb1, 0xb0, 0xe1,
- 0x9b, 0xaf, 0xe3, 0xa0, 0x4f, 0xbe, 0x85, 0x73,
- 0xfc, 0xa1, 0xdb, 0x16, 0x98, 0xf1, 0xd3, 0xfe,
- 0xd7, 0xba, 0xc5, 0x37, 0x50, 0xd1, 0x43, 0xcf,
- 0xfc, 0xcd, 0xe5, 0x79, 0xcf, 0x83, 0xcc, 0x3a,
- 0x7f, 0xdd, 0x8f, 0xe3, 0xa1, 0x8b, 0xfc, 0xe9,
- 0xfa, 0x9b, 0x5d, 0x31, 0xe3, 0xa7, 0xe0, 0xe3,
- 0x6c, 0x56, 0x87, 0x4f, 0xff, 0xd7, 0xce, 0x57,
- 0xab, 0xb0, 0x1b, 0xfd, 0x28, 0xbf, 0x95, 0x27,
- 0x5a, 0x7b, 0xbe, 0x21, 0x61, 0xc6, 0xa3, 0x51,
- 0x17, 0x07, 0xdd, 0x97, 0x71, 0x17, 0xcf, 0xe7,
- 0x58, 0xa6, 0xea, 0x1a, 0x2f, 0x38, 0x56, 0x4e,
- 0x03, 0xd1, 0x39, 0x52, 0xb9, 0xc4, 0xea, 0xe3,
- 0x04, 0x12, 0x66, 0x1d, 0xe4, 0xec, 0x25, 0x43,
- 0xb6, 0x7a, 0x9f, 0xce, 0xb1, 0x4d, 0xd4, 0x34,
- 0x52, 0xd3, 0xf9, 0xd6, 0x29, 0xba, 0x86, 0x8b,
- 0x0a, 0x7f, 0x3a, 0xc5, 0x37, 0x50, 0xd1, 0x65,
- 0xcf, 0x3b, 0xa3, 0x71, 0xdb, 0xb1, 0xd3, 0x9d,
- 0xd5, 0x87, 0x4f, 0x23, 0x96, 0x88, 0x7a, 0x1d,
- 0x99, 0x4f, 0xfe, 0x73, 0x35, 0xee, 0xb1, 0x4d,
- 0xd4, 0x34, 0x51, 0x93, 0xf9, 0xca, 0xd9, 0x45,
- 0x7f, 0x3a, 0x1e, 0x9d, 0xf0, 0x9d, 0xb0, 0xef,
- 0x61, 0x17, 0x43, 0x8c, 0x29, 0x4f, 0xfc, 0xed,
- 0x7b, 0xac, 0x53, 0x75, 0x0d, 0x11, 0xcc, 0xff,
- 0xe7, 0x33, 0x5e, 0xeb, 0x14, 0xdd, 0x43, 0x44,
- 0xe5, 0x3f, 0x9d, 0x62, 0x9b, 0xa8, 0x68, 0xb3,
- 0x27, 0xfe, 0x72, 0xfe, 0x2b, 0x8c, 0xed, 0x6f,
- 0x3a, 0x7f, 0x3a, 0xc5, 0x37, 0x50, 0xd1, 0x6e,
- 0xcf, 0xfe, 0x73, 0x35, 0xee, 0xb1, 0x4d, 0xd4,
- 0x34, 0x52, 0x13, 0xff, 0x3b, 0x5e, 0xeb, 0x14,
- 0xdd, 0x43, 0x44, 0xa5, 0x15, 0x27, 0xec, 0xd2,
- 0x63, 0x14, 0xbf, 0x3b, 0x04, 0x4c, 0x1d, 0xb7,
- 0xa9, 0x4f, 0xfb, 0x5e, 0xeb, 0x14, 0xdd, 0x43,
- 0x44, 0xed, 0x3f, 0xfe, 0xf7, 0x3d, 0xb1, 0x5b,
- 0xf7, 0x90, 0x50, 0xb4, 0x3a, 0x4e, 0x62, 0x27,
- 0x75, 0x1a, 0x7f, 0xed, 0x66, 0x6d, 0x37, 0x2b,
- 0xd5, 0xe7, 0x4f, 0xfc, 0x17, 0x9d, 0xaa, 0xe8,
- 0x1b, 0x59, 0xd3, 0x71, 0x3b, 0x94, 0x42, 0xd1,
- 0x0e, 0x18, 0x8e, 0x0e, 0x28, 0x56, 0xcf, 0x85,
- 0x37, 0x50, 0xd1, 0x16, 0x4f, 0xfb, 0x5e, 0xeb,
- 0x14, 0xdd, 0x43, 0x44, 0xbb, 0x3f, 0xff, 0x5f,
- 0x39, 0x5e, 0xae, 0xc0, 0x6f, 0xf4, 0xa2, 0xfe,
- 0x54, 0x9d, 0x68, 0xd4, 0x61, 0x87, 0x12, 0x34,
- 0xff, 0xe7, 0x33, 0x5e, 0xeb, 0x14, 0xdd, 0x43,
- 0x44, 0xc5, 0x3f, 0x58, 0xa6, 0xea, 0x1a, 0x2a,
- 0x99, 0xff, 0xff, 0xc3, 0xb9, 0xad, 0xf7, 0x87,
- 0x67, 0x68, 0x3e, 0xfb, 0x19, 0xf0, 0xbc, 0xe8,
- 0x72, 0x2b, 0x74, 0xd6, 0x7f, 0xf3, 0x99, 0xaf,
- 0x75, 0x8a, 0x6e, 0xa1, 0xa2, 0x74, 0x9f, 0xde,
- 0xd1, 0x57, 0xeb, 0x63, 0xa7, 0xcd, 0x2b, 0x4b,
- 0x43, 0xa7, 0xef, 0xaf, 0xcd, 0xac, 0x0e, 0x9e,
- 0xf6, 0x55, 0xde, 0x3d, 0x6a, 0x14, 0x4f, 0xfd,
- 0xdd, 0x30, 0xb5, 0xbb, 0xb6, 0xbc, 0xc3, 0xa1,
- 0x88, 0x82, 0xc9, 0xcc, 0xff, 0xb5, 0xee, 0xb1,
- 0x4d, 0xd4, 0x34, 0x4e, 0xf3, 0xec, 0x77, 0xac,
- 0xf1, 0x52, 0x77, 0x29, 0xcd, 0xdc, 0x61, 0x4c,
- 0x23, 0xd4, 0x69, 0xff, 0xce, 0x66, 0xbd, 0xd6,
- 0x29, 0xba, 0x86, 0x8a, 0x16, 0x7f, 0xf3, 0x99,
- 0xaf, 0x75, 0x8a, 0x6e, 0xa1, 0xa2, 0x92, 0x9f,
- 0xff, 0xd7, 0x47, 0x75, 0xb6, 0xb3, 0xac, 0xc6,
- 0x57, 0x1d, 0xb0, 0xe8, 0xa9, 0x72, 0x5d, 0xe7,
- 0x09, 0x0f, 0xf1, 0x22, 0x64, 0x7d, 0xbf, 0xa4,
- 0xf6, 0xa5, 0xc4, 0xa5, 0x3f, 0x9d, 0x62, 0x9b,
- 0xa8, 0x68, 0x89, 0x27, 0xff, 0x39, 0x9a, 0xf7,
- 0x58, 0xa6, 0xea, 0x1a, 0x25, 0xe9, 0xf0, 0xfe,
- 0xcf, 0x50, 0xe9, 0xdf, 0xae, 0x0e, 0x9f, 0xfb,
- 0x5a, 0xa2, 0xb6, 0xdc, 0xad, 0x6d, 0x1d, 0x1e,
- 0x44, 0x5b, 0x45, 0x02, 0x39, 0x3f, 0xde, 0xd0,
- 0xef, 0x0d, 0x2f, 0x43, 0xa7, 0xc2, 0x9b, 0xa8,
- 0x68, 0xa5, 0xe7, 0xff, 0x5b, 0xd7, 0xfa, 0x0a,
- 0xd6, 0xff, 0x30, 0xe9, 0xf3, 0x7f, 0x98, 0xb4,
- 0x3a, 0x7d, 0xad, 0xac, 0x68, 0x74, 0x97, 0x93,
- 0xd1, 0x61, 0x54, 0x9c, 0xa9, 0xaf, 0x72, 0x61,
- 0x67, 0x6d, 0x18, 0x62, 0x13, 0x73, 0xf9, 0xd6,
- 0x29, 0xba, 0x86, 0x8a, 0x72, 0x7f, 0xde, 0x1d,
- 0xa6, 0x6e, 0xc1, 0x0e, 0x9f, 0xf5, 0xe5, 0x46,
- 0xdd, 0xf7, 0xdf, 0x15, 0x37, 0xbe, 0x3a, 0x6a,
- 0x9d, 0xca, 0x24, 0x38, 0x8e, 0x9b, 0xcf, 0xe7,
- 0xc2, 0x9b, 0xa8, 0x68, 0xaf, 0x27, 0xff, 0xeb,
- 0xe7, 0x2b, 0xd5, 0xd8, 0x0d, 0xfe, 0x94, 0x5f,
- 0xca, 0x93, 0xad, 0x11, 0xdc, 0x46, 0x13, 0xff,
- 0x3b, 0x5e, 0xeb, 0x14, 0xdd, 0x43, 0x44, 0x8f,
- 0x3b, 0xdf, 0xa9, 0xd3, 0x92, 0xd8, 0x53, 0x8b,
- 0xc9, 0xf0, 0xa6, 0xea, 0x1a, 0x24, 0x89, 0xe7,
- 0x6b, 0xdc, 0xa7, 0xb3, 0x65, 0x33, 0xff, 0x3b,
- 0x5e, 0xeb, 0x14, 0xdd, 0x43, 0x44, 0x95, 0x3e,
- 0x14, 0xdd, 0x43, 0x45, 0xe3, 0x3f, 0x76, 0x15,
- 0xed, 0x74, 0x3a, 0x7d, 0x4a, 0x62, 0xd0, 0xe9,
- 0xfe, 0x7b, 0xac, 0x53, 0x75, 0x0d, 0x12, 0x6c,
- 0x9d, 0x68, 0xc6, 0xac, 0xc0, 0x4b, 0xf4, 0x9a,
- 0x15, 0x7b, 0x7e, 0xa3, 0xb7, 0xca, 0x3b, 0xe5,
- 0x5b, 0xd0, 0xcb, 0x6a, 0x1a, 0x4c, 0x2b, 0xcc,
- 0x30, 0x70, 0x6f, 0xdc, 0x62, 0x50, 0xb1, 0xc7,
- 0x36, 0xd5, 0x1d, 0x83, 0xe5, 0x05, 0x73, 0x28,
- 0x6a, 0xed, 0xe8, 0x9f, 0x49, 0x4b, 0x49, 0x68,
- 0x6f, 0x2b, 0x9e, 0xd3, 0xf4, 0xe9, 0x7f, 0x1e,
- 0x3b, 0x66, 0xab, 0x05, 0x41, 0xa5, 0x2a, 0xb3,
- 0x12, 0x76, 0x39, 0x9d, 0xfe, 0xda, 0xc7, 0x9b,
- 0xf9, 0x62, 0xed, 0xcc, 0x2c, 0x42, 0x90, 0xcd,
- 0x4a, 0x4e, 0x4e, 0x2b, 0xc1, 0xee, 0xe9, 0xa4,
- 0xcd, 0xa5, 0x31, 0x7d, 0x29, 0x47, 0x8a, 0x3e,
- 0x7e, 0xb3, 0xb2, 0xcd, 0xf3, 0xec, 0x50,
+ 0xe9, 0x37, 0x40, 0x7a, 0xb4, 0x20, 0x9f, 0xff,
+ 0xb1, 0x4f, 0x67, 0x7c, 0xff, 0x06, 0x3b, 0xc8,
+ 0xd9, 0xd3, 0xe1, 0x4d, 0xd4, 0x34, 0x53, 0xd3,
+ 0xf5, 0xd3, 0x80, 0x6b, 0xce, 0x8e, 0x35, 0x1c,
+ 0x8a, 0x59, 0x6b, 0x60, 0x61, 0x3f, 0xfb, 0x5e,
+ 0xee, 0x43, 0x7e, 0xa5, 0x17, 0xf3, 0xa1, 0xc8,
+ 0x8a, 0xe4, 0xfe, 0x73, 0xb9, 0xb3, 0xa7, 0xca,
+ 0xff, 0xfb, 0x79, 0xd3, 0xc9, 0xba, 0x86, 0x8a,
+ 0xce, 0x1a, 0x3d, 0x41, 0x29, 0x9f, 0xaa, 0x62,
+ 0x83, 0xe8, 0x74, 0xe5, 0xab, 0xc7, 0x4f, 0xb1,
+ 0xff, 0x50, 0x79, 0xd3, 0xbb, 0xda, 0x1d, 0x3e,
+ 0xb6, 0xaa, 0xef, 0xf3, 0xa4, 0xeb, 0x46, 0xe0,
+ 0x91, 0x64, 0xb7, 0x47, 0x00, 0xab, 0xa8, 0xe4,
+ 0xff, 0xce, 0xd7, 0xba, 0xc5, 0x37, 0x50, 0xd1,
+ 0x22, 0xcf, 0xe7, 0x58, 0xa6, 0xea, 0x1a, 0x2c,
+ 0x99, 0xfc, 0xeb, 0x14, 0xdd, 0x43, 0x45, 0xb1,
+ 0x3a, 0xe9, 0x67, 0x4f, 0x85, 0x37, 0x50, 0xd1,
+ 0x6d, 0xc9, 0xcf, 0x3c, 0xab, 0x1a, 0x9d, 0x56,
+ 0x7c, 0x74, 0xff, 0xb8, 0xde, 0x35, 0xb8, 0x63,
+ 0x36, 0x0b, 0xf9, 0xd3, 0xf2, 0x83, 0xf9, 0xed,
+ 0x87, 0x4f, 0x85, 0x37, 0x50, 0xd1, 0x78, 0x4f,
+ 0x63, 0x8a, 0xf2, 0x74, 0xff, 0xcb, 0xd5, 0x95,
+ 0xbf, 0x16, 0x18, 0xa1, 0xd3, 0xeb, 0x0f, 0xdb,
+ 0xd4, 0xe9, 0xf2, 0xf5, 0xef, 0x68, 0x74, 0xec,
+ 0x2f, 0xe7, 0x49, 0xdc, 0x6a, 0x74, 0x2d, 0xc6,
+ 0x8e, 0xd4, 0x9d, 0x65, 0xd5, 0x98, 0x64, 0x93,
+ 0xf4, 0x60, 0x29, 0xc1, 0x4c, 0xef, 0x5d, 0x67,
+ 0x4f, 0x85, 0x37, 0x50, 0xd1, 0x7a, 0x4f, 0xf8,
+ 0x37, 0x0f, 0x5e, 0x98, 0xf5, 0x47, 0x4f, 0xad,
+ 0x99, 0xde, 0x4e, 0x93, 0xb9, 0x45, 0x9d, 0x8e,
+ 0x75, 0x30, 0x6f, 0x40, 0x85, 0x64, 0x63, 0xd5,
+ 0x0b, 0x5b, 0x8f, 0x91, 0x09, 0x3d, 0x1a, 0x60,
+ 0xad, 0xb1, 0x33, 0xf3, 0xb0, 0x84, 0x2f, 0x71,
+ 0xe4, 0x7d, 0x1a, 0x3c, 0xdd, 0xe4, 0xe9, 0xeb,
+ 0xce, 0xe0, 0xe9, 0xfd, 0x7e, 0x1f, 0xff, 0xee,
+ 0x87, 0x49, 0xba, 0x03, 0xd5, 0xa1, 0x04, 0xfb,
+ 0xd8, 0x5a, 0xea, 0x3a, 0x7c, 0x29, 0xba, 0x86,
+ 0x88, 0x8e, 0x7f, 0xfb, 0x3d, 0xd2, 0x96, 0xc0,
+ 0xb6, 0xdc, 0x15, 0xbb, 0x1d, 0x3f, 0xe7, 0xad,
+ 0x43, 0x78, 0xc7, 0xb0, 0x74, 0xff, 0xff, 0x2e,
+ 0x77, 0xd8, 0x5c, 0x85, 0xe3, 0x3e, 0xcd, 0xfb,
+ 0xe3, 0xa6, 0xa9, 0x85, 0x4d, 0xf7, 0xc5, 0x4f,
+ 0xfc, 0xf7, 0x26, 0x7c, 0xd6, 0x56, 0xa7, 0x7e,
+ 0x6b, 0xfe, 0x17, 0x9f, 0xd7, 0xc7, 0x0b, 0xce,
+ 0xe0, 0xe9, 0xff, 0xf9, 0x1c, 0x3a, 0x1e, 0xc3,
+ 0x85, 0x70, 0x1b, 0xf9, 0xd1, 0xc6, 0x2b, 0x06,
+ 0xe3, 0x5b, 0x14, 0xb2, 0xca, 0x50, 0xc2, 0xb5,
+ 0x91, 0x3e, 0xd8, 0x4a, 0x61, 0x7d, 0xb1, 0xa4,
+ 0xf8, 0x53, 0x75, 0x0d, 0x11, 0x74, 0xfb, 0x1f,
+ 0xf5, 0x07, 0x96, 0xcf, 0x64, 0x9d, 0x67, 0xd1,
+ 0xa6, 0x10, 0xe4, 0xca, 0x1f, 0x18, 0x14, 0xff,
+ 0xcc, 0xd7, 0xba, 0xc5, 0x37, 0x50, 0xd1, 0x33,
+ 0x4e, 0xad, 0x68, 0x74, 0xe4, 0xf3, 0x0e, 0x9b,
+ 0x89, 0xbb, 0x9d, 0x3f, 0x62, 0xea, 0xbf, 0xda,
+ 0x3a, 0x1b, 0xb9, 0xe7, 0x34, 0x3f, 0x3e, 0x4d,
+ 0xcf, 0x9a, 0x3a, 0x7f, 0xe6, 0xff, 0x63, 0xc9,
+ 0xee, 0x71, 0x68, 0x74, 0xff, 0xff, 0x77, 0xa0,
+ 0x81, 0x7c, 0xe7, 0xbe, 0x19, 0x57, 0x8a, 0xd4,
+ 0x74, 0x5a, 0x2b, 0xf2, 0x8f, 0x3f, 0xfe, 0xe7,
+ 0xc1, 0x55, 0xd3, 0xdb, 0x97, 0x7d, 0xf7, 0xc5,
+ 0x4f, 0x26, 0xea, 0x1a, 0x2c, 0xf9, 0xff, 0x7b,
+ 0x2a, 0xff, 0x61, 0x71, 0x43, 0xa7, 0xff, 0xbc,
+ 0x39, 0xde, 0x16, 0xd8, 0x2e, 0x96, 0x07, 0x4e,
+ 0xfb, 0xef, 0x8a, 0x9f, 0xf6, 0xbe, 0x81, 0x69,
+ 0xcd, 0x89, 0x4e, 0x2f, 0xe7, 0xf9, 0x73, 0xee,
+ 0x43, 0x75, 0xa3, 0xa7, 0xfb, 0xc1, 0xcf, 0x5e,
+ 0x7b, 0xc5, 0x0e, 0x84, 0x4f, 0xc4, 0x56, 0x98,
+ 0x57, 0x93, 0xef, 0xdb, 0xb0, 0x94, 0xd8, 0xe2,
+ 0x7f, 0x87, 0x7e, 0xcf, 0x94, 0x54, 0xe9, 0xff,
+ 0xff, 0xfa, 0xef, 0xfa, 0x5d, 0x87, 0x4e, 0xa2,
+ 0x0b, 0x79, 0x75, 0x02, 0xea, 0x65, 0xb0, 0xe9,
+ 0xd4, 0x5a, 0x8e, 0x9d, 0xc5, 0x79, 0x3a, 0x1e,
+ 0x8c, 0x2a, 0x42, 0x23, 0x03, 0x93, 0xd5, 0xff,
+ 0xda, 0x1d, 0x3e, 0xc8, 0x2d, 0x89, 0x93, 0xfe,
+ 0xf0, 0xbe, 0xc6, 0xae, 0xf7, 0x93, 0x44, 0x1a,
+ 0xe3, 0x49, 0x3e, 0xd4, 0xf3, 0x14, 0xe9, 0xf9,
+ 0xf9, 0x0d, 0xaf, 0x07, 0x4a, 0xd0, 0xf4, 0x80,
+ 0x96, 0x7f, 0xff, 0xdb, 0xf6, 0x2f, 0x38, 0x5b,
+ 0x0a, 0xf1, 0x63, 0xea, 0xb5, 0x87, 0x43, 0xd3,
+ 0x3e, 0xb8, 0x57, 0x01, 0x2c, 0xfc, 0x37, 0xcd,
+ 0x32, 0xa7, 0x4f, 0xff, 0xee, 0xc3, 0x7a, 0x70,
+ 0xea, 0x1b, 0x8a, 0x7a, 0xbc, 0xfb, 0xe3, 0xa7,
+ 0xff, 0xfa, 0x94, 0x51, 0xc2, 0xb9, 0x97, 0x8a,
+ 0x75, 0xa6, 0xbe, 0xce, 0x9e, 0xcd, 0xf9, 0xb1,
+ 0xd1, 0xe4, 0x44, 0xe5, 0x9a, 0x66, 0x37, 0x46,
+ 0x8b, 0xf2, 0x7f, 0xe7, 0xe3, 0xb7, 0xbd, 0x98,
+ 0xc2, 0xb0, 0xe9, 0xff, 0xbd, 0x61, 0x77, 0x4e,
+ 0x0f, 0xa3, 0x0e, 0x8a, 0xd1, 0x15, 0x44, 0x69,
+ 0xbc, 0xd1, 0xd3, 0xb1, 0xea, 0x8e, 0x9c, 0x0a,
+ 0x87, 0x47, 0x03, 0xcd, 0x60, 0xb8, 0x0e, 0xc2,
+ 0xa6, 0xed, 0xc9, 0x1d, 0xc2, 0xcb, 0x5c, 0x67,
+ 0xff, 0xfe, 0x6f, 0x5c, 0xf9, 0x8e, 0x69, 0xfa,
+ 0x3d, 0x73, 0xea, 0xe8, 0x9e, 0xa8, 0xe9, 0xef,
+ 0xb6, 0xe8, 0x74, 0xff, 0x3d, 0x9a, 0xfc, 0x51,
+ 0x7a, 0x1d, 0x0a, 0x7b, 0x7a, 0x43, 0x3d, 0x74,
+ 0xf0, 0x1d, 0x00, 0x78, 0x1d, 0x90, 0x4f, 0x75,
+ 0xef, 0x68, 0x74, 0xff, 0xb1, 0x4f, 0xfd, 0x5d,
+ 0x6f, 0xbc, 0x1d, 0x0a, 0x7c, 0xd6, 0x49, 0x33,
+ 0x5d, 0x9d, 0x26, 0x1d, 0x15, 0x9a, 0x86, 0xe4,
+ 0x62, 0x7f, 0x6e, 0xd6, 0xf0, 0x5e, 0x4e, 0x9f,
+ 0xff, 0xf6, 0x7d, 0x5e, 0x2e, 0xbc, 0x08, 0xae,
+ 0x3f, 0xea, 0x0f, 0xcd, 0x9d, 0x3b, 0xef, 0xbe,
+ 0x2a, 0x7b, 0x9e, 0x74, 0x0a, 0x71, 0x7f, 0x3f,
+ 0xed, 0xca, 0x7b, 0x78, 0x53, 0x72, 0x74, 0x2a,
+ 0x6a, 0xdc, 0x93, 0xa1, 0x97, 0xa1, 0x1d, 0x93,
+ 0x19, 0xff, 0xac, 0x2b, 0xc5, 0x8f, 0xaa, 0xd6,
+ 0x1d, 0x3e, 0xbc, 0x3d, 0x99, 0x3a, 0x7d, 0x5d,
+ 0x01, 0x58, 0x74, 0x2a, 0x24, 0x68, 0x87, 0xd9,
+ 0x3c, 0xdf, 0xe4, 0xe9, 0xfa, 0xa6, 0x9f, 0xc6,
+ 0x8d, 0x47, 0x4f, 0xee, 0x99, 0xbc, 0x67, 0xd8,
+ 0x3a, 0x6f, 0x09, 0xd0, 0xdd, 0xcf, 0xff, 0xc6,
+ 0xb9, 0x35, 0x9f, 0xfb, 0x95, 0xe4, 0x57, 0x1e,
+ 0x4f, 0x72, 0x74, 0xfd, 0x9e, 0xea, 0x6b, 0x3e,
+ 0x3a, 0x39, 0x3f, 0x6c, 0xa2, 0xc9, 0xdc, 0x63,
+ 0x3d, 0xa1, 0xb8, 0x0e, 0x2b, 0x4d, 0x45, 0x3c,
+ 0xc3, 0x5a, 0xe5, 0x09, 0xf4, 0x66, 0xae, 0x1f,
+ 0x1e, 0x35, 0x6a, 0x38, 0x61, 0x34, 0x61, 0x66,
+ 0x65, 0x34, 0x6a, 0x0f, 0xf1, 0x8a, 0x84, 0x22,
+ 0x29, 0x1c, 0xf6, 0x21, 0xc1, 0xf1, 0x87, 0x14,
+ 0x25, 0xba, 0xc2, 0xae, 0x1c, 0xd8, 0x94, 0xe6,
+ 0x9f, 0x69, 0x3f, 0xf9, 0xcc, 0xd7, 0xba, 0xc5,
+ 0x37, 0x50, 0xd1, 0x36, 0x4f, 0xe7, 0x58, 0xa6,
+ 0xea, 0x1a, 0x2a, 0xd9, 0xfc, 0xf7, 0xf7, 0x80,
+ 0x57, 0x9d, 0x3d, 0x79, 0xdc, 0x1d, 0x26, 0xea,
+ 0xcf, 0x4c, 0x0c, 0xe7, 0xc2, 0x9b, 0xa8, 0x68,
+ 0xad, 0x27, 0xff, 0x91, 0x46, 0xff, 0xd6, 0x6b,
+ 0xd7, 0xc8, 0x74, 0xff, 0xf3, 0xe9, 0x60, 0xac,
+ 0xdb, 0xc6, 0x15, 0x87, 0x4d, 0x8c, 0x2a, 0x25,
+ 0xf5, 0x2e, 0x7f, 0x2b, 0x6e, 0xb8, 0x05, 0xfc,
+ 0xe9, 0xfa, 0xab, 0xcf, 0xad, 0x87, 0x4f, 0xf5,
+ 0xb7, 0x82, 0xfd, 0x5b, 0xe8, 0x74, 0xfe, 0x7d,
+ 0xe3, 0x43, 0xfe, 0xce, 0x93, 0xb8, 0xd4, 0xfc,
+ 0x6c, 0xaf, 0xd0, 0xc7, 0xc9, 0x6e, 0x9b, 0x01,
+ 0x6e, 0x0f, 0x27, 0xf3, 0xac, 0x53, 0x75, 0x0d,
+ 0x16, 0x04, 0xf8, 0x53, 0x75, 0x0d, 0x13, 0xac,
+ 0xff, 0xfe, 0xca, 0xd5, 0xcd, 0xb1, 0xd4, 0xa5,
+ 0xe7, 0xd4, 0xee, 0xa3, 0xa7, 0xce, 0x66, 0xbd,
+ 0xd6, 0x89, 0x56, 0x8c, 0x27, 0xc2, 0x9b, 0xa8,
+ 0x68, 0xb6, 0x67, 0xfd, 0xfa, 0xd1, 0xd9, 0xf2,
+ 0x68, 0x9d, 0x27, 0x59, 0xf6, 0xe9, 0x84, 0xf2,
+ 0x6e, 0xa1, 0xa2, 0xe6, 0x93, 0x0e, 0x99, 0xd6,
+ 0x26, 0xef, 0xe2, 0xb9, 0xfc, 0xeb, 0x14, 0xdd,
+ 0x43, 0x45, 0xdf, 0x3c, 0xee, 0x9c, 0xfe, 0x74,
+ 0x2b, 0x6e, 0x65, 0x75, 0x8a, 0x9a, 0x18, 0xd6,
+ 0xa5, 0xe9, 0x4f, 0xe2, 0xe4, 0xc8, 0x68, 0x7f,
+ 0x0a, 0xda, 0x30, 0xe0, 0xb3, 0xa9, 0xdc, 0xff,
+ 0x83, 0x5c, 0xb4, 0xa3, 0x35, 0xe7, 0x4f, 0xe0,
+ 0xaa, 0xdb, 0xf0, 0xbd, 0x0e, 0x9f, 0x0a, 0x6e,
+ 0xa1, 0xa2, 0x57, 0x9f, 0xf0, 0x6f, 0xdc, 0xe5,
+ 0x6a, 0xbf, 0x8e, 0x9e, 0xef, 0x45, 0xe7, 0x4f,
+ 0xff, 0xef, 0x63, 0x59, 0xa1, 0xfe, 0x7e, 0xd0,
+ 0xa9, 0x3d, 0x51, 0xd1, 0xca, 0x20, 0xf4, 0x86,
+ 0x39, 0x47, 0x36, 0x61, 0x87, 0x3b, 0x5e, 0xe5,
+ 0x4d, 0xda, 0xcd, 0xe9, 0x18, 0xb4, 0xec, 0x2f,
+ 0x25, 0x4f, 0xfe, 0xce, 0xfb, 0x0a, 0xff, 0x0d,
+ 0x5d, 0xfe, 0x54, 0xfe, 0xd4, 0x77, 0x22, 0xdc,
+ 0xb9, 0x4f, 0xa2, 0x83, 0x92, 0x72, 0x2a, 0xae,
+ 0x64, 0x76, 0x4d, 0xa1, 0x5d, 0x3f, 0xf9, 0xcc,
+ 0xd7, 0xba, 0xc5, 0x37, 0x50, 0xd1, 0x30, 0xcf,
+ 0xff, 0xd6, 0xee, 0xa3, 0xbf, 0xbb, 0xa6, 0x1f,
+ 0xf2, 0xd1, 0xe7, 0x4f, 0xfc, 0xdd, 0x5d, 0x6f,
+ 0xef, 0x70, 0x0a, 0xf3, 0xa7, 0xf2, 0xed, 0x58,
+ 0xe9, 0xa2, 0x74, 0xfb, 0x45, 0xfa, 0xc3, 0xa0,
+ 0x0f, 0x63, 0xb3, 0x39, 0xf9, 0x8b, 0x61, 0x8e,
+ 0x23, 0xa7, 0xcb, 0x61, 0x8e, 0x23, 0xa7, 0xec,
+ 0xfb, 0x14, 0xda, 0xf8, 0x1e, 0xb3, 0x0b, 0xa7,
+ 0xff, 0xfc, 0x17, 0xf3, 0x7e, 0x2f, 0x3c, 0x02,
+ 0xea, 0xf5, 0x85, 0x6f, 0xa1, 0xd3, 0xf3, 0x6e,
+ 0xb8, 0x05, 0xfc, 0xe9, 0xff, 0xcb, 0x8f, 0xd5,
+ 0xf7, 0x5e, 0x2a, 0xef, 0xe3, 0xa1, 0x4f, 0xff,
+ 0xc6, 0x33, 0xf5, 0x3d, 0xd1, 0x9b, 0x83, 0xa7,
+ 0xff, 0xfc, 0x36, 0xd9, 0x43, 0x1c, 0x3a, 0x82,
+ 0xe7, 0x7d, 0x85, 0xc5, 0x0e, 0x95, 0xd6, 0x89,
+ 0xd1, 0x2f, 0x9f, 0xff, 0x64, 0x2f, 0x19, 0xf5,
+ 0xd7, 0x8b, 0x6c, 0xb4, 0x3a, 0x72, 0xff, 0xd4,
+ 0xe8, 0xb3, 0xf4, 0x05, 0x69, 0xed, 0xeb, 0xcd,
+ 0x9d, 0x27, 0x71, 0xaa, 0xfb, 0xb9, 0x85, 0x0a,
+ 0x3c, 0x34, 0x91, 0x98, 0x78, 0x04, 0x2f, 0xb1,
+ 0x09, 0xce, 0xc8, 0x27, 0xc2, 0x9b, 0xa8, 0x68,
+ 0xab, 0xa7, 0xf9, 0xee, 0xb1, 0x4d, 0xd4, 0x34,
+ 0x47, 0x92, 0x75, 0x9f, 0x8e, 0x98, 0x4f, 0xe7,
+ 0x58, 0xa6, 0xea, 0x1a, 0x2c, 0x19, 0xfc, 0xeb,
+ 0x14, 0xdd, 0x43, 0x45, 0x95, 0x3f, 0x9d, 0x62,
+ 0x9b, 0xa8, 0x68, 0xb4, 0xe7, 0x93, 0x75, 0x0d,
+ 0x16, 0xe4, 0xff, 0xcb, 0x63, 0x61, 0xc3, 0x37,
+ 0x5f, 0xc7, 0x40, 0x9f, 0x7d, 0x0a, 0xe7, 0xf9,
+ 0x43, 0xb6, 0x2d, 0x31, 0xe3, 0xa7, 0xfd, 0xaf,
+ 0x75, 0x8a, 0x6e, 0xa1, 0xa2, 0x87, 0x9f, 0xf9,
+ 0x9b, 0xca, 0xf3, 0x9f, 0x07, 0x98, 0x74, 0xff,
+ 0xbb, 0x1f, 0xc7, 0x43, 0x17, 0xf9, 0xd3, 0xf5,
+ 0x36, 0xba, 0x63, 0xc7, 0x4f, 0xc1, 0xc6, 0xd8,
+ 0xad, 0x0e, 0x9f, 0xff, 0xaf, 0x9c, 0xaf, 0x57,
+ 0x60, 0x37, 0xfa, 0x51, 0x7f, 0x2a, 0x4e, 0xb4,
+ 0xf7, 0x7c, 0x42, 0xc3, 0x8d, 0x46, 0xa2, 0x2e,
+ 0x0f, 0xbb, 0x2e, 0xe2, 0x2f, 0x9f, 0xce, 0xb1,
+ 0x4d, 0xd4, 0x34, 0x5e, 0x70, 0xac, 0x9c, 0x07,
+ 0xa2, 0x72, 0xa5, 0x73, 0x89, 0xd5, 0xc6, 0x08,
+ 0x24, 0xcc, 0x3b, 0xc9, 0xd8, 0x4a, 0x87, 0x6c,
+ 0xf5, 0x3f, 0x9d, 0x62, 0x9b, 0xa8, 0x68, 0xa5,
+ 0xa7, 0xf3, 0xac, 0x53, 0x75, 0x0d, 0x16, 0x14,
+ 0xfe, 0x75, 0x8a, 0x6e, 0xa1, 0xa2, 0xcb, 0x9e,
+ 0x77, 0x46, 0xe3, 0xb7, 0x63, 0xa7, 0x3b, 0xab,
+ 0x0e, 0x9e, 0x47, 0x2d, 0x10, 0xf4, 0x3b, 0x32,
+ 0x9f, 0xfc, 0xe6, 0x6b, 0xdd, 0x62, 0x9b, 0xa8,
+ 0x68, 0xa3, 0x27, 0xf3, 0x95, 0xb2, 0x8a, 0xfe,
+ 0x74, 0x3d, 0x3b, 0xe1, 0x3b, 0x61, 0xde, 0xc2,
+ 0x2e, 0x87, 0x18, 0x52, 0x9f, 0xf9, 0xda, 0xf7,
+ 0x58, 0xa6, 0xea, 0x1a, 0x23, 0x99, 0xff, 0xce,
+ 0x66, 0xbd, 0xd6, 0x29, 0xba, 0x86, 0x89, 0xca,
+ 0x7f, 0x3a, 0xc5, 0x37, 0x50, 0xd1, 0x66, 0x4f,
+ 0xfc, 0xe5, 0xfc, 0x57, 0x19, 0xda, 0xde, 0x74,
+ 0xfe, 0x75, 0x8a, 0x6e, 0xa1, 0xa2, 0xdd, 0x9f,
+ 0xfc, 0xe6, 0x6b, 0xdd, 0x62, 0x9b, 0xa8, 0x68,
+ 0xa4, 0x27, 0xfe, 0x76, 0xbd, 0xd6, 0x29, 0xba,
+ 0x86, 0x89, 0x4a, 0x2a, 0x4f, 0xd9, 0xa4, 0xc6,
+ 0x29, 0x7e, 0x76, 0x08, 0x98, 0x3b, 0x6f, 0x52,
+ 0x9f, 0xf6, 0xbd, 0xd6, 0x29, 0xba, 0x86, 0x89,
+ 0xda, 0x7f, 0xfd, 0xee, 0x7b, 0x62, 0xb7, 0xef,
+ 0x20, 0xa1, 0x68, 0x74, 0x9c, 0xc4, 0x4e, 0xea,
+ 0x34, 0xff, 0xda, 0xcc, 0xda, 0x6e, 0x57, 0xab,
+ 0xce, 0x9f, 0xf8, 0x2f, 0x3b, 0x55, 0xd0, 0x36,
+ 0xb3, 0xa6, 0xe2, 0x77, 0x28, 0x85, 0xa2, 0x1c,
+ 0x31, 0x1c, 0x1c, 0x50, 0xad, 0x9f, 0x0a, 0x6e,
+ 0xa1, 0xa2, 0x2c, 0x9f, 0xf6, 0xbd, 0xd6, 0x29,
+ 0xba, 0x86, 0x89, 0x76, 0x7f, 0xfe, 0xbe, 0x72,
+ 0xbd, 0x5d, 0x80, 0xdf, 0xe9, 0x45, 0xfc, 0xa9,
+ 0x3a, 0xd1, 0xa8, 0xc3, 0x0e, 0x24, 0x69, 0xff,
+ 0xce, 0x66, 0xbd, 0xd6, 0x29, 0xba, 0x86, 0x89,
+ 0x8a, 0x7e, 0xb1, 0x4d, 0xd4, 0x34, 0x55, 0x33,
+ 0xff, 0xff, 0x87, 0x73, 0x5b, 0xef, 0x0e, 0xce,
+ 0xd0, 0x7d, 0xf6, 0x33, 0xe1, 0x79, 0xd0, 0xe4,
+ 0x56, 0xe9, 0xac, 0xff, 0xe7, 0x33, 0x5e, 0xeb,
+ 0x14, 0xdd, 0x43, 0x44, 0xe9, 0x3f, 0xbd, 0xa2,
+ 0xaf, 0xd6, 0xc7, 0x4f, 0x9a, 0x56, 0x96, 0x87,
+ 0x4f, 0xdf, 0x5f, 0x9b, 0x58, 0x1d, 0x3d, 0xec,
+ 0xab, 0xbc, 0x7a, 0xd4, 0x28, 0x9f, 0xfb, 0xba,
+ 0x61, 0x6b, 0x77, 0x6d, 0x79, 0x87, 0x43, 0x11,
+ 0x05, 0x93, 0x99, 0xff, 0x6b, 0xdd, 0x62, 0x9b,
+ 0xa8, 0x68, 0x9d, 0xe7, 0xd8, 0xef, 0x59, 0xe2,
+ 0xa4, 0xee, 0x53, 0x9b, 0xb8, 0xc2, 0x98, 0x47,
+ 0xa8, 0xd3, 0xff, 0x9c, 0xcd, 0x7b, 0xac, 0x53,
+ 0x75, 0x0d, 0x14, 0x2c, 0xff, 0xe7, 0x33, 0x5e,
+ 0xeb, 0x14, 0xdd, 0x43, 0x45, 0x25, 0x3f, 0xff,
+ 0xae, 0x8e, 0xeb, 0x6d, 0x67, 0x59, 0x8c, 0xae,
+ 0x3b, 0x61, 0xd1, 0x52, 0xe4, 0xbb, 0xce, 0x12,
+ 0x1f, 0xe2, 0x44, 0xc8, 0xfb, 0x7f, 0x49, 0xed,
+ 0x4b, 0x89, 0x4a, 0x7f, 0x3a, 0xc5, 0x37, 0x50,
+ 0xd1, 0x12, 0x4f, 0xfe, 0x73, 0x35, 0xee, 0xb1,
+ 0x4d, 0xd4, 0x34, 0x4b, 0xd3, 0xe1, 0xfd, 0x9e,
+ 0xa1, 0xd3, 0xbf, 0x5c, 0x1d, 0x3f, 0xf6, 0xb5,
+ 0x45, 0x6d, 0xb9, 0x5a, 0xda, 0x3a, 0x3c, 0x88,
+ 0xb6, 0x8a, 0x04, 0x72, 0x7f, 0xbd, 0xa1, 0xde,
+ 0x1a, 0x5e, 0x87, 0x4f, 0x85, 0x37, 0x50, 0xd1,
+ 0x4b, 0xcf, 0xfe, 0xb7, 0xaf, 0xf4, 0x15, 0xad,
+ 0xfe, 0x61, 0xd3, 0xe6, 0xff, 0x31, 0x68, 0x74,
+ 0xfb, 0x5b, 0x58, 0xd0, 0xe9, 0x2f, 0x27, 0xa2,
+ 0xc2, 0xa9, 0x39, 0x53, 0x5e, 0xe4, 0xc2, 0xce,
+ 0xda, 0x30, 0xc4, 0x26, 0xe7, 0xf3, 0xac, 0x53,
+ 0x75, 0x0d, 0x14, 0xe4, 0xff, 0xbc, 0x3b, 0x4c,
+ 0xdd, 0x82, 0x1d, 0x3f, 0xeb, 0xca, 0x8d, 0xbb,
+ 0xef, 0xbe, 0x2a, 0x6f, 0x7c, 0x74, 0xd5, 0x3b,
+ 0x94, 0x48, 0x71, 0x1d, 0x37, 0x9f, 0xcf, 0x85,
+ 0x37, 0x50, 0xd1, 0x5e, 0x4f, 0xff, 0xd7, 0xce,
+ 0x57, 0xab, 0xb0, 0x1b, 0xfd, 0x28, 0xbf, 0x95,
+ 0x27, 0x5a, 0x23, 0xb8, 0x8c, 0x27, 0xfe, 0x76,
+ 0xbd, 0xd6, 0x29, 0xba, 0x86, 0x89, 0x1e, 0x77,
+ 0xbf, 0x53, 0xa7, 0x25, 0xb0, 0xa7, 0x17, 0x93,
+ 0xe1, 0x4d, 0xd4, 0x34, 0x49, 0x13, 0xce, 0xd7,
+ 0xb9, 0x4f, 0x66, 0xca, 0x67, 0xfe, 0x76, 0xbd,
+ 0xd6, 0x29, 0xba, 0x86, 0x89, 0x2a, 0x7c, 0x29,
+ 0xba, 0x86, 0x8b, 0xc6, 0x7e, 0xec, 0x2b, 0xda,
+ 0xe8, 0x74, 0xfa, 0x94, 0xc5, 0xa1, 0xd3, 0xfc,
+ 0xf7, 0x58, 0xa6, 0xea, 0x1a, 0x24, 0xd9, 0x3a,
+ 0xd1, 0x8d, 0x59, 0x80, 0x97, 0xe9, 0x34, 0x2a,
+ 0xf6, 0xfd, 0x47, 0x6f, 0x94, 0x77, 0xca, 0xb7,
+ 0xa1, 0x96, 0xd4, 0x34, 0x98, 0x57, 0x98, 0x60,
+ 0xe0, 0xdf, 0xb8, 0xc4, 0xa1, 0x63, 0x8e, 0x24,
+ 0xaa, 0x3b, 0x07, 0xca, 0x0a, 0xe6, 0x50, 0xd5,
+ 0xdb, 0xd1, 0x3e, 0x92, 0x96, 0x92, 0xd0, 0xde,
+ 0x57, 0x3d, 0xa7, 0xe9, 0xd2, 0xfe, 0x3c, 0x76,
+ 0xcd, 0x56, 0x0a, 0x83, 0x4a, 0x55, 0x66, 0x24,
+ 0xec, 0x73, 0x3b, 0xfd, 0xb5, 0x8f, 0x37, 0xf2,
+ 0xc5, 0xdb, 0x98, 0x58, 0x85, 0x21, 0x9a, 0x94,
+ 0x98, 0x1c, 0x57, 0x83, 0xbd, 0xd3, 0x49, 0x9b,
+ 0x4a, 0x62, 0xfa, 0x52, 0x8f, 0x14, 0x7c, 0xfd,
+ 0x67, 0x65, 0x9b, 0xe7, 0xd8, 0xa0,
};
-static const unsigned kPreloadedHSTSBits = 103990;
+static const unsigned kPreloadedHSTSBits = 103917;
-static const unsigned kHSTSRootPosition = 103406;
+static const unsigned kHSTSRootPosition = 103333;
#endif // NET_HTTP_TRANSPORT_SECURITY_STATE_STATIC_H_
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json
index a8a5bf1..ff5d79a 100644
--- a/net/http/transport_security_state_static.json
+++ b/net/http/transport_security_state_static.json
@@ -1217,7 +1217,6 @@
{ "name": "cloudstoragemaus.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "comdurav.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "digitaldaddy.net", "include_subdomains": true, "mode": "force-https" },
- { "name": "eldietista.es", "include_subdomains": true, "mode": "force-https" },
{ "name": "elnutricionista.es", "include_subdomains": true, "mode": "force-https" },
{ "name": "fronteers.nl", "include_subdomains": true, "mode": "force-https" },
{ "name": "getssl.uz", "include_subdomains": true, "mode": "force-https" },
diff --git a/net/net.gyp b/net/net.gyp
index 8bfcc7b..c1338bf 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -665,6 +665,10 @@
[ 'enable_websockets != 1', {
'sources/': [
['exclude', '^websockets/'],
+ ['exclude', '^server/'],
+ ],
+ 'dependencies!': [
+ 'http_server',
],
}],
['disable_file_support==1', {
@@ -959,6 +963,8 @@
'test/spawned_test_server/spawner_communicator.h',
'test/url_request/url_request_failed_job.cc',
'test/url_request/url_request_failed_job.h',
+ 'test/url_request/url_request_mock_data_job.cc',
+ 'test/url_request/url_request_mock_data_job.h',
'test/url_request/url_request_mock_http_job.cc',
'test/url_request/url_request_mock_http_job.h',
'url_request/test_url_fetcher_factory.cc',
@@ -1075,6 +1081,8 @@
'server/http_server_response_info.h',
'server/web_socket.cc',
'server/web_socket.h',
+ 'server/web_socket_encoder.cc',
+ 'server/web_socket_encoder.h',
],
# TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
'msvs_disabled_warnings': [4267, ],
diff --git a/net/net.gypi b/net/net.gypi
index 7d7d2f0..5ca70f7 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -153,6 +153,8 @@
'ssl/signed_certificate_timestamp_and_status.h',
'ssl/ssl_cert_request_info.cc',
'ssl/ssl_cert_request_info.h',
+ 'ssl/ssl_cipher_suite_names.cc',
+ 'ssl/ssl_cipher_suite_names.h',
'ssl/ssl_client_auth_cache.cc',
'ssl/ssl_client_auth_cache.h',
'ssl/ssl_client_cert_type.h',
@@ -1107,8 +1109,6 @@
'ssl/client_cert_store_nss.h',
'ssl/client_cert_store_win.cc',
'ssl/client_cert_store_win.h',
- 'ssl/ssl_cipher_suite_names.cc',
- 'ssl/ssl_cipher_suite_names.h',
'ssl/ssl_config_service_defaults.cc',
'ssl/ssl_config_service_defaults.h',
'third_party/mozilla_security_manager/nsKeygenHandler.cpp',
@@ -1587,6 +1587,7 @@
'server/http_connection_unittest.cc',
'server/http_server_response_info_unittest.cc',
'server/http_server_unittest.cc',
+ 'server/web_socket_encoder_unittest.cc',
'socket/client_socket_pool_base_unittest.cc',
'socket/deterministic_socket_data_unittest.cc',
'socket/mock_client_socket_pool_manager.cc',
diff --git a/net/proxy/proxy_config_service_android.cc b/net/proxy/proxy_config_service_android.cc
index 50407fe..80e3b92 100644
--- a/net/proxy/proxy_config_service_android.cc
+++ b/net/proxy/proxy_config_service_android.cc
@@ -98,6 +98,12 @@
// by | and that use * as a wildcard. For example, setting the
// http.nonProxyHosts property to *.android.com|*.kernel.org will cause
// requests to http://developer.android.com to be made without a proxy.
+
+ // Force localhost to be on the proxy exclusion list;
+ // otherwise all localhost traffic is routed through
+ // the proxy which is not desired.
+ bypass_rules->AddRuleToBypassLocal();
+
std::string non_proxy_hosts =
get_property.Run(scheme + ".nonProxyHosts");
if (non_proxy_hosts.empty())
diff --git a/net/proxy/proxy_resolver_script.h b/net/proxy/proxy_resolver_script.h
index 283eff9..e838bed 100644
--- a/net/proxy/proxy_resolver_script.h
+++ b/net/proxy/proxy_resolver_script.h
@@ -1,3 +1,10 @@
+// Copyright (c) 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 NET_PROXY_PROXY_RESOLVER_SCRIPT_H_
+#define NET_PROXY_PROXY_RESOLVER_SCRIPT_H_
+
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -37,9 +44,6 @@
*
* ***** END LICENSE BLOCK ***** */
-#ifndef NET_PROXY_PROXY_RESOLVER_SCRIPT_H_
-#define NET_PROXY_PROXY_RESOLVER_SCRIPT_H_
-
// The following code was formatted from:
// 'mozilla/netwerk/base/src/nsProxyAutoConfig.js' (1.55)
//
@@ -51,6 +55,8 @@
// sed -e 's/"$/" \\/g' |
// sed -e 's/\/(ipaddr);/\/.exec(ipaddr);/g' |
// grep -v '^var pacUtils ='
+//
+// isPlainHost() was removed.
#define PROXY_RESOLVER_SCRIPT \
"function dnsDomainIs(host, domain) {\n" \
" return (host.length >= domain.length &&\n" \
@@ -87,10 +93,6 @@
" \n" \
"}\n" \
"" \
- "function isPlainHostName(host) {\n" \
- " return (host.search('\\\\.') == -1);\n" \
- "}\n" \
- "" \
"function isResolvable(host) {\n" \
" var ip = dnsResolve(host);\n" \
" return (ip != null);\n" \
diff --git a/net/proxy/proxy_resolver_v8.cc b/net/proxy/proxy_resolver_v8.cc
index 963153d..57ee714 100644
--- a/net/proxy/proxy_resolver_v8.cc
+++ b/net/proxy/proxy_resolver_v8.cc
@@ -334,6 +334,17 @@
return IPNumberMatchesPrefix(address, prefix, prefix_length_in_bits);
}
+// Consider only single component domains like 'foo' as plain host names.
+bool IsPlainHostName(const std::string& hostname_utf8) {
+ if (hostname_utf8.find('.') != std::string::npos)
+ return false;
+
+ // IPv6 addresses may not contain periods, however are not be considered a
+ // plain host name.
+ IPAddressNumber unused;
+ return !ParseIPLiteralToNumber(hostname_utf8, &unused);
+}
+
} // namespace
// ProxyResolverV8::Context ---------------------------------------------------
@@ -439,6 +450,11 @@
global_template->Set(ASCIILiteralToV8String(isolate_, "dnsResolve"),
dns_resolve_template);
+ v8::Local<v8::FunctionTemplate> is_plain_host_name_template =
+ v8::FunctionTemplate::New(isolate_, &IsPlainHostNameCallback, v8_this);
+ global_template->Set(ASCIILiteralToV8String(isolate_, "isPlainHostName"),
+ is_plain_host_name_template);
+
// Microsoft's PAC extensions:
v8::Local<v8::FunctionTemplate> dns_resolve_ex_template =
@@ -698,6 +714,22 @@
args.GetReturnValue().Set(IsInNetEx(ip_address, ip_prefix));
}
+ // V8 callback for when "isPlainHostName()" is invoked by the PAC script.
+ static void IsPlainHostNameCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ // Need at least 1 string arguments.
+ if (args.Length() < 1 || args[0].IsEmpty() || !args[0]->IsString()) {
+ args.GetIsolate()->ThrowException(
+ v8::Exception::TypeError(ASCIIStringToV8String(
+ args.GetIsolate(), "Requires 1 string parameter")));
+ return;
+ }
+
+ std::string hostname_utf8 =
+ V8StringToUTF8(v8::Local<v8::String>::Cast(args[0]));
+ args.GetReturnValue().Set(IsPlainHostName(hostname_utf8));
+ }
+
mutable base::Lock lock_;
ProxyResolverV8* parent_;
v8::Isolate* isolate_;
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index 738326a..ecd338a 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -292,13 +292,17 @@
}
void QuicStreamFactory::Job::OnIOComplete(int rv) {
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+ tracked_objects::ScopedTracker tracking_profile1(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "436634 QuicStreamFactory::Job::OnIOComplete"));
+ "422516 QuicStreamFactory::Job::OnIOComplete1"));
rv = DoLoop(rv);
+ tracked_objects::ScopedTracker tracking_profile2(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 QuicStreamFactory::Job::OnIOComplete2"));
+
if (rv != ERR_IO_PENDING && !callback_.is_null()) {
callback_.Run(rv);
}
@@ -647,6 +651,11 @@
void QuicStreamFactory::OnJobComplete(Job* job, int rv) {
if (rv == OK) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+ tracked_objects::ScopedTracker tracking_profile1(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 QuicStreamFactory::OnJobComplete1"));
+
if (!always_require_handshake_confirmation_)
set_require_confirmation(false);
@@ -658,6 +667,12 @@
(*it)->net_log()));
}
}
+
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+ tracked_objects::ScopedTracker tracking_profile2(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 QuicStreamFactory::OnJobComplete2"));
+
while (!job_requests_map_[job].empty()) {
RequestSet::iterator it = job_requests_map_[job].begin();
QuicStreamRequest* request = *it;
@@ -668,6 +683,12 @@
// profile which can not be deleted via callbacks.
request->OnRequestComplete(rv);
}
+
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
+ tracked_objects::ScopedTracker tracking_profile3(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 QuicStreamFactory::OnJobComplete3"));
+
active_jobs_.erase(job->server_id());
job_requests_map_.erase(job);
delete job;
diff --git a/net/server/web_socket.cc b/net/server/web_socket.cc
index d67ecb6..e5d1cb7 100644
--- a/net/server/web_socket.cc
+++ b/net/server/web_socket.cc
@@ -4,10 +4,7 @@
#include "net/server/web_socket.h"
-#include <limits>
-
#include "base/base64.h"
-#include "base/rand_util.h"
#include "base/logging.h"
#include "base/md5.h"
#include "base/sha1.h"
@@ -18,6 +15,7 @@
#include "net/server/http_server.h"
#include "net/server/http_server_request_info.h"
#include "net/server/http_server_response_info.h"
+#include "net/server/web_socket_encoder.h"
namespace net {
@@ -152,31 +150,6 @@
const int WebSocketHixie76::kWebSocketHandshakeBodyLen = 8;
-
-// Constants for hybi-10 frame format.
-
-typedef int OpCode;
-
-const OpCode kOpCodeContinuation = 0x0;
-const OpCode kOpCodeText = 0x1;
-const OpCode kOpCodeBinary = 0x2;
-const OpCode kOpCodeClose = 0x8;
-const OpCode kOpCodePing = 0x9;
-const OpCode kOpCodePong = 0xA;
-
-const unsigned char kFinalBit = 0x80;
-const unsigned char kReserved1Bit = 0x40;
-const unsigned char kReserved2Bit = 0x20;
-const unsigned char kReserved3Bit = 0x10;
-const unsigned char kOpCodeMask = 0xF;
-const unsigned char kMaskBit = 0x80;
-const unsigned char kPayloadLengthMask = 0x7F;
-
-const size_t kMaxSingleBytePayloadLength = 125;
-const size_t kTwoBytePayloadLengthField = 126;
-const size_t kEightBytePayloadLengthField = 127;
-const size_t kMaskingKeyWidthInBytes = 4;
-
class WebSocketHybi17 : public WebSocket {
public:
static WebSocket* Create(HttpServer* server,
@@ -207,22 +180,22 @@
std::string encoded_hash;
base::Base64Encode(base::SHA1HashString(data), &encoded_hash);
- server_->SendRaw(
- connection_->id(),
- base::StringPrintf("HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
- "Upgrade: WebSocket\r\n"
- "Connection: Upgrade\r\n"
- "Sec-WebSocket-Accept: %s\r\n"
- "\r\n",
- encoded_hash.c_str()));
+ server_->SendRaw(connection_->id(),
+ base::StringPrintf(
+ "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
+ "Upgrade: WebSocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Accept: %s\r\n"
+ "%s"
+ "\r\n",
+ encoded_hash.c_str(), response_extensions_.c_str()));
}
ParseResult Read(std::string* message) override {
HttpConnection::ReadIOBuffer* read_buf = connection_->read_buf();
base::StringPiece frame(read_buf->StartOfBuffer(), read_buf->GetSize());
int bytes_consumed = 0;
- ParseResult result =
- WebSocket::DecodeFrameHybi17(frame, true, &bytes_consumed, message);
+ ParseResult result = encoder_->DecodeFrame(frame, &bytes_consumed, message);
if (result == FRAME_OK)
read_buf->DidConsume(bytes_consumed);
if (result == FRAME_CLOSE)
@@ -233,8 +206,9 @@
void Send(const std::string& message) override {
if (closed_)
return;
- server_->SendRaw(connection_->id(),
- WebSocket::EncodeFrameHybi17(message, 0));
+ std::string encoded;
+ encoder_->EncodeFrame(message, 0, &encoded);
+ server_->SendRaw(connection_->id(), encoded);
}
private:
@@ -243,27 +217,19 @@
const HttpServerRequestInfo& request,
size_t* pos)
: WebSocket(server, connection),
- op_code_(0),
- final_(false),
- reserved1_(false),
- reserved2_(false),
- reserved3_(false),
- masked_(false),
- payload_(0),
- payload_length_(0),
- frame_end_(0),
closed_(false) {
+ std::string request_extensions =
+ request.GetHeaderValue("sec-websocket-extensions");
+ encoder_.reset(WebSocketEncoder::CreateServer(request_extensions,
+ &response_extensions_));
+ if (!response_extensions_.empty()) {
+ response_extensions_ =
+ "Sec-WebSocket-Extensions: " + response_extensions_ + "\r\n";
+ }
}
- OpCode op_code_;
- bool final_;
- bool reserved1_;
- bool reserved2_;
- bool reserved3_;
- bool masked_;
- const char* payload_;
- size_t payload_length_;
- const char* frame_end_;
+ scoped_ptr<WebSocketEncoder> encoder_;
+ std::string response_extensions_;
bool closed_;
DISALLOW_COPY_AND_ASSIGN(WebSocketHybi17);
@@ -282,142 +248,12 @@
return WebSocketHixie76::Create(server, connection, request, pos);
}
-// static
-WebSocket::ParseResult WebSocket::DecodeFrameHybi17(
- const base::StringPiece& frame,
- bool client_frame,
- int* bytes_consumed,
- std::string* output) {
- size_t data_length = frame.length();
- if (data_length < 2)
- return FRAME_INCOMPLETE;
-
- const char* buffer_begin = const_cast<char*>(frame.data());
- const char* p = buffer_begin;
- const char* buffer_end = p + data_length;
-
- unsigned char first_byte = *p++;
- unsigned char second_byte = *p++;
-
- bool final = (first_byte & kFinalBit) != 0;
- bool reserved1 = (first_byte & kReserved1Bit) != 0;
- bool reserved2 = (first_byte & kReserved2Bit) != 0;
- bool reserved3 = (first_byte & kReserved3Bit) != 0;
- int op_code = first_byte & kOpCodeMask;
- bool masked = (second_byte & kMaskBit) != 0;
- if (!final || reserved1 || reserved2 || reserved3)
- return FRAME_ERROR; // Extensions and not supported.
-
- bool closed = false;
- switch (op_code) {
- case kOpCodeClose:
- closed = true;
- break;
- case kOpCodeText:
- break;
- case kOpCodeBinary: // We don't support binary frames yet.
- case kOpCodeContinuation: // We don't support binary frames yet.
- case kOpCodePing: // We don't support binary frames yet.
- case kOpCodePong: // We don't support binary frames yet.
- default:
- return FRAME_ERROR;
- }
-
- if (client_frame && !masked) // In Hybi-17 spec client MUST mask his frame.
- return FRAME_ERROR;
-
- uint64 payload_length64 = second_byte & kPayloadLengthMask;
- if (payload_length64 > kMaxSingleBytePayloadLength) {
- int extended_payload_length_size;
- if (payload_length64 == kTwoBytePayloadLengthField)
- extended_payload_length_size = 2;
- else {
- DCHECK(payload_length64 == kEightBytePayloadLengthField);
- extended_payload_length_size = 8;
- }
- if (buffer_end - p < extended_payload_length_size)
- return FRAME_INCOMPLETE;
- payload_length64 = 0;
- for (int i = 0; i < extended_payload_length_size; ++i) {
- payload_length64 <<= 8;
- payload_length64 |= static_cast<unsigned char>(*p++);
- }
- }
-
- size_t actual_masking_key_length = masked ? kMaskingKeyWidthInBytes : 0;
- static const uint64 max_payload_length = 0x7FFFFFFFFFFFFFFFull;
- static size_t max_length = std::numeric_limits<size_t>::max();
- if (payload_length64 > max_payload_length ||
- payload_length64 + actual_masking_key_length > max_length) {
- // WebSocket frame length too large.
- return FRAME_ERROR;
- }
- size_t payload_length = static_cast<size_t>(payload_length64);
-
- size_t total_length = actual_masking_key_length + payload_length;
- if (static_cast<size_t>(buffer_end - p) < total_length)
- return FRAME_INCOMPLETE;
-
- if (masked) {
- output->resize(payload_length);
- const char* masking_key = p;
- char* payload = const_cast<char*>(p + kMaskingKeyWidthInBytes);
- for (size_t i = 0; i < payload_length; ++i) // Unmask the payload.
- (*output)[i] = payload[i] ^ masking_key[i % kMaskingKeyWidthInBytes];
- } else {
- output->assign(p, p + payload_length);
- }
-
- size_t pos = p + actual_masking_key_length + payload_length - buffer_begin;
- *bytes_consumed = pos;
- return closed ? FRAME_CLOSE : FRAME_OK;
-}
-
-// static
-std::string WebSocket::EncodeFrameHybi17(const std::string& message,
- int masking_key) {
- std::vector<char> frame;
- OpCode op_code = kOpCodeText;
- size_t data_length = message.length();
-
- frame.push_back(kFinalBit | op_code);
- char mask_key_bit = masking_key != 0 ? kMaskBit : 0;
- if (data_length <= kMaxSingleBytePayloadLength)
- frame.push_back(data_length | mask_key_bit);
- else if (data_length <= 0xFFFF) {
- frame.push_back(kTwoBytePayloadLengthField | mask_key_bit);
- frame.push_back((data_length & 0xFF00) >> 8);
- frame.push_back(data_length & 0xFF);
- } else {
- frame.push_back(kEightBytePayloadLengthField | mask_key_bit);
- char extended_payload_length[8];
- size_t remaining = data_length;
- // Fill the length into extended_payload_length in the network byte order.
- for (int i = 0; i < 8; ++i) {
- extended_payload_length[7 - i] = remaining & 0xFF;
- remaining >>= 8;
- }
- frame.insert(frame.end(),
- extended_payload_length,
- extended_payload_length + 8);
- DCHECK(!remaining);
- }
-
- const char* data = const_cast<char*>(message.data());
- if (masking_key != 0) {
- const char* mask_bytes = reinterpret_cast<char*>(&masking_key);
- frame.insert(frame.end(), mask_bytes, mask_bytes + 4);
- for (size_t i = 0; i < data_length; ++i) // Mask the payload.
- frame.push_back(data[i] ^ mask_bytes[i % kMaskingKeyWidthInBytes]);
- } else {
- frame.insert(frame.end(), data, data + data_length);
- }
- return std::string(&frame[0], frame.size());
-}
-
WebSocket::WebSocket(HttpServer* server, HttpConnection* connection)
: server_(server),
connection_(connection) {
}
+WebSocket::~WebSocket() {
+}
+
} // namespace net
diff --git a/net/server/web_socket.h b/net/server/web_socket.h
index 9b3a794..3f2c1d8 100644
--- a/net/server/web_socket.h
+++ b/net/server/web_socket.h
@@ -30,18 +30,10 @@
const HttpServerRequestInfo& request,
size_t* pos);
- static ParseResult DecodeFrameHybi17(const base::StringPiece& frame,
- bool client_frame,
- int* bytes_consumed,
- std::string* output);
-
- static std::string EncodeFrameHybi17(const std::string& data,
- int masking_key);
-
virtual void Accept(const HttpServerRequestInfo& request) = 0;
virtual ParseResult Read(std::string* message) = 0;
virtual void Send(const std::string& message) = 0;
- virtual ~WebSocket() {}
+ virtual ~WebSocket();
protected:
WebSocket(HttpServer* server, HttpConnection* connection);
diff --git a/net/server/web_socket_encoder.cc b/net/server/web_socket_encoder.cc
new file mode 100644
index 0000000..cb23326
--- /dev/null
+++ b/net/server/web_socket_encoder.cc
@@ -0,0 +1,364 @@
+// 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 "net/server/web_socket_encoder.h"
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "net/base/io_buffer.h"
+#include "net/websockets/websocket_extension_parser.h"
+
+namespace net {
+
+const char WebSocketEncoder::kClientExtensions[] =
+ "Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits";
+
+namespace {
+
+const int kInflaterChunkSize = 16 * 1024;
+
+// Constants for hybi-10 frame format.
+
+typedef int OpCode;
+
+const OpCode kOpCodeContinuation = 0x0;
+const OpCode kOpCodeText = 0x1;
+const OpCode kOpCodeBinary = 0x2;
+const OpCode kOpCodeClose = 0x8;
+const OpCode kOpCodePing = 0x9;
+const OpCode kOpCodePong = 0xA;
+
+const unsigned char kFinalBit = 0x80;
+const unsigned char kReserved1Bit = 0x40;
+const unsigned char kReserved2Bit = 0x20;
+const unsigned char kReserved3Bit = 0x10;
+const unsigned char kOpCodeMask = 0xF;
+const unsigned char kMaskBit = 0x80;
+const unsigned char kPayloadLengthMask = 0x7F;
+
+const size_t kMaxSingleBytePayloadLength = 125;
+const size_t kTwoBytePayloadLengthField = 126;
+const size_t kEightBytePayloadLengthField = 127;
+const size_t kMaskingKeyWidthInBytes = 4;
+
+WebSocket::ParseResult DecodeFrameHybi17(const base::StringPiece& frame,
+ bool client_frame,
+ int* bytes_consumed,
+ std::string* output,
+ bool* compressed) {
+ size_t data_length = frame.length();
+ if (data_length < 2)
+ return WebSocket::FRAME_INCOMPLETE;
+
+ const char* buffer_begin = const_cast<char*>(frame.data());
+ const char* p = buffer_begin;
+ const char* buffer_end = p + data_length;
+
+ unsigned char first_byte = *p++;
+ unsigned char second_byte = *p++;
+
+ bool final = (first_byte & kFinalBit) != 0;
+ bool reserved1 = (first_byte & kReserved1Bit) != 0;
+ bool reserved2 = (first_byte & kReserved2Bit) != 0;
+ bool reserved3 = (first_byte & kReserved3Bit) != 0;
+ int op_code = first_byte & kOpCodeMask;
+ bool masked = (second_byte & kMaskBit) != 0;
+ *compressed = reserved1;
+ if (!final || reserved2 || reserved3)
+ return WebSocket::FRAME_ERROR; // Only compression extension is supported.
+
+ bool closed = false;
+ switch (op_code) {
+ case kOpCodeClose:
+ closed = true;
+ break;
+ case kOpCodeText:
+ break;
+ case kOpCodeBinary: // We don't support binary frames yet.
+ case kOpCodeContinuation: // We don't support binary frames yet.
+ case kOpCodePing: // We don't support binary frames yet.
+ case kOpCodePong: // We don't support binary frames yet.
+ default:
+ return WebSocket::FRAME_ERROR;
+ }
+
+ if (client_frame && !masked) // In Hybi-17 spec client MUST mask his frame.
+ return WebSocket::FRAME_ERROR;
+
+ uint64 payload_length64 = second_byte & kPayloadLengthMask;
+ if (payload_length64 > kMaxSingleBytePayloadLength) {
+ int extended_payload_length_size;
+ if (payload_length64 == kTwoBytePayloadLengthField)
+ extended_payload_length_size = 2;
+ else {
+ DCHECK(payload_length64 == kEightBytePayloadLengthField);
+ extended_payload_length_size = 8;
+ }
+ if (buffer_end - p < extended_payload_length_size)
+ return WebSocket::FRAME_INCOMPLETE;
+ payload_length64 = 0;
+ for (int i = 0; i < extended_payload_length_size; ++i) {
+ payload_length64 <<= 8;
+ payload_length64 |= static_cast<unsigned char>(*p++);
+ }
+ }
+
+ size_t actual_masking_key_length = masked ? kMaskingKeyWidthInBytes : 0;
+ static const uint64 max_payload_length = 0x7FFFFFFFFFFFFFFFull;
+ static size_t max_length = std::numeric_limits<size_t>::max();
+ if (payload_length64 > max_payload_length ||
+ payload_length64 + actual_masking_key_length > max_length) {
+ // WebSocket frame length too large.
+ return WebSocket::FRAME_ERROR;
+ }
+ size_t payload_length = static_cast<size_t>(payload_length64);
+
+ size_t total_length = actual_masking_key_length + payload_length;
+ if (static_cast<size_t>(buffer_end - p) < total_length)
+ return WebSocket::FRAME_INCOMPLETE;
+
+ if (masked) {
+ output->resize(payload_length);
+ const char* masking_key = p;
+ char* payload = const_cast<char*>(p + kMaskingKeyWidthInBytes);
+ for (size_t i = 0; i < payload_length; ++i) // Unmask the payload.
+ (*output)[i] = payload[i] ^ masking_key[i % kMaskingKeyWidthInBytes];
+ } else {
+ output->assign(p, p + payload_length);
+ }
+
+ size_t pos = p + actual_masking_key_length + payload_length - buffer_begin;
+ *bytes_consumed = pos;
+ return closed ? WebSocket::FRAME_CLOSE : WebSocket::FRAME_OK;
+}
+
+void EncodeFrameHybi17(const std::string& message,
+ int masking_key,
+ bool compressed,
+ std::string* output) {
+ std::vector<char> frame;
+ OpCode op_code = kOpCodeText;
+ size_t data_length = message.length();
+
+ int reserved1 = compressed ? kReserved1Bit : 0;
+ frame.push_back(kFinalBit | op_code | reserved1);
+ char mask_key_bit = masking_key != 0 ? kMaskBit : 0;
+ if (data_length <= kMaxSingleBytePayloadLength)
+ frame.push_back(data_length | mask_key_bit);
+ else if (data_length <= 0xFFFF) {
+ frame.push_back(kTwoBytePayloadLengthField | mask_key_bit);
+ frame.push_back((data_length & 0xFF00) >> 8);
+ frame.push_back(data_length & 0xFF);
+ } else {
+ frame.push_back(kEightBytePayloadLengthField | mask_key_bit);
+ char extended_payload_length[8];
+ size_t remaining = data_length;
+ // Fill the length into extended_payload_length in the network byte order.
+ for (int i = 0; i < 8; ++i) {
+ extended_payload_length[7 - i] = remaining & 0xFF;
+ remaining >>= 8;
+ }
+ frame.insert(frame.end(), extended_payload_length,
+ extended_payload_length + 8);
+ DCHECK(!remaining);
+ }
+
+ const char* data = const_cast<char*>(message.data());
+ if (masking_key != 0) {
+ const char* mask_bytes = reinterpret_cast<char*>(&masking_key);
+ frame.insert(frame.end(), mask_bytes, mask_bytes + 4);
+ for (size_t i = 0; i < data_length; ++i) // Mask the payload.
+ frame.push_back(data[i] ^ mask_bytes[i % kMaskingKeyWidthInBytes]);
+ } else {
+ frame.insert(frame.end(), data, data + data_length);
+ }
+ *output = std::string(&frame[0], frame.size());
+}
+
+} // anonymous namespace
+
+// static
+WebSocketEncoder* WebSocketEncoder::CreateServer(
+ const std::string& request_extensions,
+ std::string* response_extensions) {
+ bool deflate;
+ int client_window_bits;
+ int server_window_bits;
+ bool client_no_context_takeover;
+ bool server_no_context_takeover;
+ ParseExtensions(request_extensions, &deflate, &client_window_bits,
+ &server_window_bits, &client_no_context_takeover,
+ &server_no_context_takeover);
+
+ if (deflate) {
+ *response_extensions = base::StringPrintf(
+ "permessage-deflate; server_max_window_bits=%d; "
+ "client_max_window_bits=%d%s",
+ server_window_bits, client_window_bits,
+ server_no_context_takeover ? "; server_no_context_takeover" : "");
+ return new WebSocketEncoder(true /* is_server */, server_window_bits,
+ client_window_bits, server_no_context_takeover);
+ } else {
+ *response_extensions = std::string();
+ return new WebSocketEncoder(true /* is_server */);
+ }
+}
+
+// static
+WebSocketEncoder* WebSocketEncoder::CreateClient(
+ const std::string& response_extensions) {
+ bool deflate;
+ int client_window_bits;
+ int server_window_bits;
+ bool client_no_context_takeover;
+ bool server_no_context_takeover;
+ ParseExtensions(response_extensions, &deflate, &client_window_bits,
+ &server_window_bits, &client_no_context_takeover,
+ &server_no_context_takeover);
+
+ if (deflate) {
+ return new WebSocketEncoder(false /* is_server */, client_window_bits,
+ server_window_bits, client_no_context_takeover);
+ } else {
+ return new WebSocketEncoder(false /* is_server */);
+ }
+}
+
+// static
+void WebSocketEncoder::ParseExtensions(const std::string& extensions,
+ bool* deflate,
+ int* client_window_bits,
+ int* server_window_bits,
+ bool* client_no_context_takeover,
+ bool* server_no_context_takeover) {
+ *deflate = false;
+ *client_window_bits = 15;
+ *server_window_bits = 15;
+ *client_no_context_takeover = false;
+ *server_no_context_takeover = false;
+
+ if (extensions.empty())
+ return;
+
+ // TODO(dgozman): split extensions header if another extension is introduced.
+ WebSocketExtensionParser parser;
+ parser.Parse(extensions);
+ if (parser.has_error())
+ return;
+ if (parser.extension().name() != "permessage-deflate")
+ return;
+
+ const std::vector<WebSocketExtension::Parameter>& parameters =
+ parser.extension().parameters();
+ for (const auto& param : parameters) {
+ const std::string& name = param.name();
+ if (name == "client_max_window_bits" && param.HasValue()) {
+ int bits = 0;
+ if (base::StringToInt(param.value(), &bits) && bits >= 8 && bits <= 15)
+ *client_window_bits = bits;
+ }
+ if (name == "server_max_window_bits" && param.HasValue()) {
+ int bits = 0;
+ if (base::StringToInt(param.value(), &bits) && bits >= 8 && bits <= 15)
+ *server_window_bits = bits;
+ }
+ if (name == "client_no_context_takeover")
+ *client_no_context_takeover = true;
+ if (name == "server_no_context_takeover")
+ *server_no_context_takeover = true;
+ }
+ *deflate = true;
+}
+
+WebSocketEncoder::WebSocketEncoder(bool is_server) : is_server_(is_server) {
+}
+
+WebSocketEncoder::WebSocketEncoder(bool is_server,
+ int deflate_bits,
+ int inflate_bits,
+ bool no_context_takeover)
+ : is_server_(is_server) {
+ deflater_.reset(new WebSocketDeflater(
+ no_context_takeover ? WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT
+ : WebSocketDeflater::TAKE_OVER_CONTEXT));
+ inflater_.reset(
+ new WebSocketInflater(kInflaterChunkSize, kInflaterChunkSize));
+
+ if (!deflater_->Initialize(deflate_bits) ||
+ !inflater_->Initialize(inflate_bits)) {
+ // Disable deflate support.
+ deflater_.reset();
+ inflater_.reset();
+ }
+}
+
+WebSocketEncoder::~WebSocketEncoder() {
+}
+
+WebSocket::ParseResult WebSocketEncoder::DecodeFrame(
+ const base::StringPiece& frame,
+ int* bytes_consumed,
+ std::string* output) {
+ bool compressed;
+ WebSocket::ParseResult result =
+ DecodeFrameHybi17(frame, is_server_, bytes_consumed, output, &compressed);
+ if (result == WebSocket::FRAME_OK && compressed) {
+ if (!Inflate(output))
+ result = WebSocket::FRAME_ERROR;
+ }
+ return result;
+}
+
+void WebSocketEncoder::EncodeFrame(const std::string& frame,
+ int masking_key,
+ std::string* output) {
+ std::string compressed;
+ if (Deflate(frame, &compressed))
+ EncodeFrameHybi17(compressed, masking_key, true, output);
+ else
+ EncodeFrameHybi17(frame, masking_key, false, output);
+}
+
+bool WebSocketEncoder::Inflate(std::string* message) {
+ if (!inflater_)
+ return false;
+ if (!inflater_->AddBytes(message->data(), message->length()))
+ return false;
+ if (!inflater_->Finish())
+ return false;
+
+ std::vector<char> output;
+ while (inflater_->CurrentOutputSize() > 0) {
+ scoped_refptr<IOBufferWithSize> chunk =
+ inflater_->GetOutput(inflater_->CurrentOutputSize());
+ if (!chunk.get())
+ return false;
+ output.insert(output.end(), chunk->data(), chunk->data() + chunk->size());
+ }
+
+ *message =
+ output.size() ? std::string(&output[0], output.size()) : std::string();
+ return true;
+}
+
+bool WebSocketEncoder::Deflate(const std::string& message,
+ std::string* output) {
+ if (!deflater_)
+ return false;
+ if (!deflater_->AddBytes(message.data(), message.length())) {
+ deflater_->Finish();
+ return false;
+ }
+ if (!deflater_->Finish())
+ return false;
+ scoped_refptr<IOBufferWithSize> buffer =
+ deflater_->GetOutput(deflater_->CurrentOutputSize());
+ if (!buffer.get())
+ return false;
+ *output = std::string(buffer->data(), buffer->size());
+ return true;
+}
+
+} // namespace net
diff --git a/net/server/web_socket_encoder.h b/net/server/web_socket_encoder.h
new file mode 100644
index 0000000..c534c2f
--- /dev/null
+++ b/net/server/web_socket_encoder.h
@@ -0,0 +1,63 @@
+// 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 NET_SERVER_WEB_SOCKET_ENCODER_H_
+#define NET_SERVER_WEB_SOCKET_ENCODER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_piece.h"
+#include "net/server/web_socket.h"
+#include "net/websockets/websocket_deflater.h"
+#include "net/websockets/websocket_inflater.h"
+
+namespace net {
+
+class WebSocketEncoder {
+ public:
+ ~WebSocketEncoder();
+
+ static WebSocketEncoder* CreateServer(const std::string& request_extensions,
+ std::string* response_extensions);
+
+ static const char kClientExtensions[];
+ static WebSocketEncoder* CreateClient(const std::string& response_extensions);
+
+ WebSocket::ParseResult DecodeFrame(const base::StringPiece& frame,
+ int* bytes_consumed,
+ std::string* output);
+
+ void EncodeFrame(const std::string& frame,
+ int masking_key,
+ std::string* output);
+
+ private:
+ explicit WebSocketEncoder(bool is_server);
+ WebSocketEncoder(bool is_server,
+ int deflate_bits,
+ int inflate_bits,
+ bool no_context_takeover);
+
+ static void ParseExtensions(const std::string& extensions,
+ bool* deflate,
+ int* client_window_bits,
+ int* server_window_bits,
+ bool* client_no_context_takeover,
+ bool* server_no_context_takeover);
+
+ bool Inflate(std::string* message);
+ bool Deflate(const std::string& message, std::string* output);
+
+ scoped_ptr<WebSocketDeflater> deflater_;
+ scoped_ptr<WebSocketInflater> inflater_;
+ bool is_server_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebSocketEncoder);
+};
+
+} // namespace net
+
+#endif // NET_SERVER_WEB_SOCKET_ENCODER_H_
diff --git a/net/server/web_socket_encoder_unittest.cc b/net/server/web_socket_encoder_unittest.cc
new file mode 100644
index 0000000..b52939a
--- /dev/null
+++ b/net/server/web_socket_encoder_unittest.cc
@@ -0,0 +1,155 @@
+// 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 "net/server/web_socket_encoder.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+class WebSocketEncoderTest : public testing::Test {
+ public:
+ WebSocketEncoderTest() {}
+
+ void SetUp() override {
+ std::string response_extensions;
+ server_.reset(WebSocketEncoder::CreateServer("", &response_extensions));
+ EXPECT_EQ(std::string(), response_extensions);
+ client_.reset(WebSocketEncoder::CreateClient(""));
+ }
+
+ protected:
+ scoped_ptr<WebSocketEncoder> server_;
+ scoped_ptr<WebSocketEncoder> client_;
+};
+
+class WebSocketEncoderCompressionTest : public WebSocketEncoderTest {
+ public:
+ WebSocketEncoderCompressionTest() : WebSocketEncoderTest() {}
+
+ void SetUp() override {
+ std::string response_extensions;
+ server_.reset(WebSocketEncoder::CreateServer(
+ "permessage-deflate; client_max_window_bits", &response_extensions));
+ EXPECT_EQ(
+ "permessage-deflate; server_max_window_bits=15; "
+ "client_max_window_bits=15",
+ response_extensions);
+ client_.reset(WebSocketEncoder::CreateClient(response_extensions));
+ }
+};
+
+TEST_F(WebSocketEncoderTest, ClientToServer) {
+ std::string frame("ClientToServer");
+ int mask = 123456;
+ std::string encoded;
+ int bytes_consumed;
+ std::string decoded;
+
+ client_->EncodeFrame(frame, mask, &encoded);
+ EXPECT_EQ(WebSocket::FRAME_OK,
+ server_->DecodeFrame(encoded, &bytes_consumed, &decoded));
+ EXPECT_EQ(frame, decoded);
+ EXPECT_EQ((int)encoded.length(), bytes_consumed);
+
+ std::string partial = encoded.substr(0, encoded.length() - 2);
+ EXPECT_EQ(WebSocket::FRAME_INCOMPLETE,
+ server_->DecodeFrame(partial, &bytes_consumed, &decoded));
+
+ std::string extra = encoded + "more stuff";
+ EXPECT_EQ(WebSocket::FRAME_OK,
+ server_->DecodeFrame(extra, &bytes_consumed, &decoded));
+ EXPECT_EQ(frame, decoded);
+ EXPECT_EQ((int)encoded.length(), bytes_consumed);
+
+ EXPECT_EQ(
+ WebSocket::FRAME_ERROR,
+ server_->DecodeFrame(std::string("abcde"), &bytes_consumed, &decoded));
+}
+
+TEST_F(WebSocketEncoderTest, ServerToClient) {
+ std::string frame("ServerToClient");
+ int mask = 0;
+ std::string encoded;
+ int bytes_consumed;
+ std::string decoded;
+
+ server_->EncodeFrame(frame, mask, &encoded);
+ EXPECT_EQ(WebSocket::FRAME_OK,
+ client_->DecodeFrame(encoded, &bytes_consumed, &decoded));
+ EXPECT_EQ(frame, decoded);
+ EXPECT_EQ((int)encoded.length(), bytes_consumed);
+
+ std::string partial = encoded.substr(0, encoded.length() - 2);
+ EXPECT_EQ(WebSocket::FRAME_INCOMPLETE,
+ client_->DecodeFrame(partial, &bytes_consumed, &decoded));
+
+ std::string extra = encoded + "more stuff";
+ EXPECT_EQ(WebSocket::FRAME_OK,
+ client_->DecodeFrame(extra, &bytes_consumed, &decoded));
+ EXPECT_EQ(frame, decoded);
+ EXPECT_EQ((int)encoded.length(), bytes_consumed);
+
+ EXPECT_EQ(
+ WebSocket::FRAME_ERROR,
+ client_->DecodeFrame(std::string("abcde"), &bytes_consumed, &decoded));
+}
+
+TEST_F(WebSocketEncoderCompressionTest, ClientToServer) {
+ std::string frame("CompressionCompressionCompressionCompression");
+ int mask = 654321;
+ std::string encoded;
+ int bytes_consumed;
+ std::string decoded;
+
+ client_->EncodeFrame(frame, mask, &encoded);
+ EXPECT_LT(encoded.length(), frame.length());
+ EXPECT_EQ(WebSocket::FRAME_OK,
+ server_->DecodeFrame(encoded, &bytes_consumed, &decoded));
+ EXPECT_EQ(frame, decoded);
+ EXPECT_EQ((int)encoded.length(), bytes_consumed);
+}
+
+TEST_F(WebSocketEncoderCompressionTest, ServerToClient) {
+ std::string frame("CompressionCompressionCompressionCompression");
+ int mask = 0;
+ std::string encoded;
+ int bytes_consumed;
+ std::string decoded;
+
+ server_->EncodeFrame(frame, mask, &encoded);
+ EXPECT_LT(encoded.length(), frame.length());
+ EXPECT_EQ(WebSocket::FRAME_OK,
+ client_->DecodeFrame(encoded, &bytes_consumed, &decoded));
+ EXPECT_EQ(frame, decoded);
+ EXPECT_EQ((int)encoded.length(), bytes_consumed);
+}
+
+TEST_F(WebSocketEncoderCompressionTest, LongFrame) {
+ int length = 1000000;
+ std::string temp;
+ temp.reserve(length);
+ for (int i = 0; i < length; ++i)
+ temp += (char)('a' + (i % 26));
+
+ std::string frame;
+ frame.reserve(length);
+ for (int i = 0; i < length; ++i) {
+ int64 j = i;
+ frame += temp.data()[(j * j) % length];
+ }
+
+ int mask = 0;
+ std::string encoded;
+ int bytes_consumed;
+ std::string decoded;
+
+ server_->EncodeFrame(frame, mask, &encoded);
+ EXPECT_LT(encoded.length(), frame.length());
+ EXPECT_EQ(WebSocket::FRAME_OK,
+ client_->DecodeFrame(encoded, &bytes_consumed, &decoded));
+ EXPECT_EQ(frame, decoded);
+ EXPECT_EQ((int)encoded.length(), bytes_consumed);
+}
+
+} // namespace net
diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc
index 9e1abf4..4092365 100644
--- a/net/socket/client_socket_pool_base.cc
+++ b/net/socket/client_socket_pool_base.cc
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/stats_counters.h"
+#include "base/profiler/scoped_tracker.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
@@ -865,6 +866,11 @@
void ClientSocketPoolBaseHelper::OnConnectJobComplete(
int result, ConnectJob* job) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "436634 ClientSocketPoolBaseHelper::OnConnectJobComplete"));
+
DCHECK_NE(ERR_IO_PENDING, result);
const std::string group_name = job->group_name();
GroupMap::iterator group_it = group_map_.find(group_name);
diff --git a/net/socket/next_proto.cc b/net/socket/next_proto.cc
index 0e59ce7..0d1b400 100644
--- a/net/socket/next_proto.cc
+++ b/net/socket/next_proto.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "next_proto.h"
+#include "net/socket/next_proto.h"
namespace net {
@@ -16,6 +16,8 @@
NextProtoVector next_protos;
next_protos.push_back(kProtoHTTP11);
next_protos.push_back(kProtoSPDY31);
+ next_protos.push_back(kProtoSPDY4_14);
+ next_protos.push_back(kProtoSPDY4_15);
return next_protos;
}
@@ -27,6 +29,8 @@
next_protos.push_back(kProtoQUIC1SPDY3);
if (spdy_enabled) {
next_protos.push_back(kProtoSPDY31);
+ next_protos.push_back(kProtoSPDY4_14);
+ next_protos.push_back(kProtoSPDY4_15);
}
return next_protos;
}
diff --git a/net/socket/ssl_client_socket.cc b/net/socket/ssl_client_socket.cc
index a52e6a3..2ea403f 100644
--- a/net/socket/ssl_client_socket.cc
+++ b/net/socket/ssl_client_socket.cc
@@ -11,6 +11,7 @@
#include "net/base/connection_type_histograms.h"
#include "net/base/host_port_pair.h"
#include "net/ssl/channel_id_service.h"
+#include "net/ssl/ssl_cipher_suite_names.h"
#include "net/ssl/ssl_config_service.h"
#include "net/ssl/ssl_connection_status_flags.h"
@@ -234,38 +235,46 @@
}
// static
+bool SSLClientSocket::HasCipherAdequateForHTTP2(
+ const std::vector<uint16>& cipher_suites) {
+ for (uint16 cipher : cipher_suites) {
+ if (IsSecureTLSCipherSuite(cipher))
+ return true;
+ }
+ return false;
+}
+
+// static
+bool SSLClientSocket::IsTLSVersionAdequateForHTTP2(
+ const SSLConfig& ssl_config) {
+ return ssl_config.version_max >= SSL_PROTOCOL_VERSION_TLS1_2;
+}
+
+// static
std::vector<uint8_t> SSLClientSocket::SerializeNextProtos(
- const std::vector<std::string>& next_protos) {
- // Do a first pass to determine the total length.
- size_t wire_length = 0;
- for (std::vector<std::string>::const_iterator i = next_protos.begin();
- i != next_protos.end(); ++i) {
- if (i->size() > 255) {
- LOG(WARNING) << "Ignoring overlong NPN/ALPN protocol: " << *i;
+ const NextProtoVector& next_protos,
+ bool can_advertise_http2) {
+ std::vector<uint8_t> wire_protos;
+ for (const NextProto next_proto : next_protos) {
+ if (!can_advertise_http2 && kProtoSPDY4MinimumVersion <= next_proto &&
+ next_proto <= kProtoSPDY4MaximumVersion) {
continue;
}
- if (i->size() == 0) {
+ const std::string proto = NextProtoToString(next_proto);
+ if (proto.size() > 255) {
+ LOG(WARNING) << "Ignoring overlong NPN/ALPN protocol: " << proto;
+ continue;
+ }
+ if (proto.size() == 0) {
LOG(WARNING) << "Ignoring empty NPN/ALPN protocol";
continue;
}
- wire_length += i->size();
- wire_length++;
+ wire_protos.push_back(proto.size());
+ for (const char ch : proto) {
+ wire_protos.push_back(static_cast<uint8_t>(ch));
+ }
}
- // Allocate memory for the result and fill it in.
- std::vector<uint8_t> wire_protos;
- wire_protos.reserve(wire_length);
- for (std::vector<std::string>::const_iterator i = next_protos.begin();
- i != next_protos.end(); i++) {
- if (i->size() == 0 || i->size() > 255)
- continue;
- wire_protos.push_back(i->size());
- wire_protos.resize(wire_protos.size() + i->size());
- memcpy(&wire_protos[wire_protos.size() - i->size()],
- i->data(), i->size());
- }
- DCHECK_EQ(wire_protos.size(), wire_length);
-
return wire_protos;
}
diff --git a/net/socket/ssl_client_socket.h b/net/socket/ssl_client_socket.h
index 11b19a1..46461df 100644
--- a/net/socket/ssl_client_socket.h
+++ b/net/socket/ssl_client_socket.h
@@ -209,10 +209,23 @@
const SSLConfig& ssl_config,
ChannelIDService* channel_id_service);
+ // Determine if there is at least one enabled cipher suite that satisfies
+ // Section 9.2 of the HTTP/2 specification. Note that the server might still
+ // pick an inadequate cipher suite.
+ static bool HasCipherAdequateForHTTP2(
+ const std::vector<uint16>& cipher_suites);
+
+ // Determine if the TLS version required by Section 9.2 of the HTTP/2
+ // specification is enabled. Note that the server might still pick an
+ // inadequate TLS version.
+ static bool IsTLSVersionAdequateForHTTP2(const SSLConfig& ssl_config);
+
// Serializes |next_protos| in the wire format for ALPN: protocols are listed
- // in order, each prefixed by a one-byte length.
+ // in order, each prefixed by a one-byte length. Any HTTP/2 protocols in
+ // |next_protos| are ignored if |can_advertise_http2| is false.
static std::vector<uint8_t> SerializeNextProtos(
- const std::vector<std::string>& next_protos);
+ const NextProtoVector& next_protos,
+ bool can_advertise_http2);
// For unit testing only.
// Returns the unverified certificate chain as presented by server.
@@ -222,6 +235,7 @@
const = 0;
private:
+ FRIEND_TEST_ALL_PREFIXES(SSLClientSocket, SerializeNextProtos);
// For signed_cert_timestamps_received_ and stapled_ocsp_response_received_.
FRIEND_TEST_ALL_PREFIXES(SSLClientSocketTest,
ConnectSignedCertTimestampsEnabledTLSExtension);
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index 3651e8d..5e33e12 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -149,6 +149,14 @@
} while (0)
#endif
+#if !defined(CKM_AES_GCM)
+#define CKM_AES_GCM 0x00001087
+#endif
+
+#if !defined(CKM_NSS_CHACHA20_POLY1305)
+#define CKM_NSS_CHACHA20_POLY1305 (CKM_NSS + 26)
+#endif
+
namespace {
// SSL plaintext fragments are shorter than 16KB. Although the record layer
@@ -973,8 +981,16 @@
SECStatus rv = SECSuccess;
if (!ssl_config_.next_protos.empty()) {
+ // TODO(bnc): Check ssl_config_.disabled_cipher_suites.
+ const bool adequate_encryption =
+ PK11_TokenExists(CKM_AES_GCM) ||
+ PK11_TokenExists(CKM_NSS_CHACHA20_POLY1305);
+ const bool adequate_key_agreement = PK11_TokenExists(CKM_DH_PKCS_DERIVE) ||
+ PK11_TokenExists(CKM_ECDH1_DERIVE);
std::vector<uint8_t> wire_protos =
- SerializeNextProtos(ssl_config_.next_protos);
+ SerializeNextProtos(ssl_config_.next_protos,
+ adequate_encryption && adequate_key_agreement &&
+ IsTLSVersionAdequateForHTTP2(ssl_config_));
rv = SSL_SetNextProtoNego(
nss_fd_, wire_protos.empty() ? NULL : &wire_protos[0],
wire_protos.size());
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index 4e86c05..c78a974 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -788,8 +788,8 @@
// disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256
// and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384
// as the handshake hash.
- std::string command("DEFAULT:!NULL:!aNULL:!IDEA:!FZA:!SRP:!SHA256:!SHA384:"
- "!aECDH:!AESGCM+AES256");
+ std::string command(
+ "DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK");
// Walk through all the installed ciphers, seeing if any need to be
// appended to the cipher removal |command|.
for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
@@ -838,8 +838,20 @@
}
if (!ssl_config_.next_protos.empty()) {
+ // Get list of ciphers that are enabled.
+ STACK_OF(SSL_CIPHER)* enabled_ciphers = SSL_get_ciphers(ssl_);
+ DCHECK(enabled_ciphers);
+ std::vector<uint16> enabled_ciphers_vector;
+ for (size_t i = 0; i < sk_SSL_CIPHER_num(enabled_ciphers); ++i) {
+ const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(enabled_ciphers, i);
+ const uint16 id = static_cast<uint16>(SSL_CIPHER_get_id(cipher));
+ enabled_ciphers_vector.push_back(id);
+ }
+
std::vector<uint8_t> wire_protos =
- SerializeNextProtos(ssl_config_.next_protos);
+ SerializeNextProtos(ssl_config_.next_protos,
+ HasCipherAdequateForHTTP2(enabled_ciphers_vector) &&
+ IsTLSVersionAdequateForHTTP2(ssl_config_));
SSL_set_alpn_protos(ssl_, wire_protos.empty() ? NULL : &wire_protos[0],
wire_protos.size());
}
@@ -1131,9 +1143,18 @@
}
}
- if (result == OK)
+ if (result == OK) {
RecordConnectionTypeMetrics(GetNetSSLVersion(ssl_));
+ if (SSL_session_reused(ssl_)) {
+ // Record whether or not the server tried to resume a session for a
+ // different version. See https://crbug.com/441456.
+ UMA_HISTOGRAM_BOOLEAN(
+ "Net.SSLSessionVersionMatch",
+ SSL_version(ssl_) == SSL_get_session(ssl_)->ssl_version);
+ }
+ }
+
const CertStatus cert_status = server_cert_verify_result_.cert_status;
if (transport_security_state_ &&
(result == OK ||
@@ -1782,11 +1803,10 @@
// For each protocol in server preference order, see if we support it.
for (unsigned int i = 0; i < inlen; i += in[i] + 1) {
- for (std::vector<std::string>::const_iterator
- j = ssl_config_.next_protos.begin();
- j != ssl_config_.next_protos.end(); ++j) {
- if (in[i] == j->size() &&
- memcmp(&in[i + 1], j->data(), in[i]) == 0) {
+ for (NextProto next_proto : ssl_config_.next_protos) {
+ const std::string proto = NextProtoToString(next_proto);
+ if (in[i] == proto.size() &&
+ memcmp(&in[i + 1], proto.data(), in[i]) == 0) {
// We found a match.
*out = const_cast<unsigned char*>(in) + i + 1;
*outlen = in[i];
@@ -1800,9 +1820,9 @@
// If we didn't find a protocol, we select the first one from our list.
if (npn_status_ == kNextProtoNoOverlap) {
- *out = reinterpret_cast<uint8*>(const_cast<char*>(
- ssl_config_.next_protos[0].data()));
- *outlen = ssl_config_.next_protos[0].size();
+ const std::string proto = NextProtoToString(ssl_config_.next_protos[0]);
+ *out = reinterpret_cast<uint8*>(const_cast<char*>(proto.data()));
+ *outlen = proto.size();
}
npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen);
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc
index 16e03f7..d14f1fd 100644
--- a/net/socket/ssl_client_socket_unittest.cc
+++ b/net/socket/ssl_client_socket_unittest.cc
@@ -2351,6 +2351,33 @@
SSLClientSocket::ClearSessionCache();
}
+TEST(SSLClientSocket, SerializeNextProtos) {
+ NextProtoVector next_protos;
+ next_protos.push_back(kProtoHTTP11);
+ next_protos.push_back(kProtoSPDY31);
+ static std::vector<uint8_t> serialized =
+ SSLClientSocket::SerializeNextProtos(next_protos, true);
+ ASSERT_EQ(18u, serialized.size());
+ EXPECT_EQ(8, serialized[0]); // length("http/1.1")
+ EXPECT_EQ('h', serialized[1]);
+ EXPECT_EQ('t', serialized[2]);
+ EXPECT_EQ('t', serialized[3]);
+ EXPECT_EQ('p', serialized[4]);
+ EXPECT_EQ('/', serialized[5]);
+ EXPECT_EQ('1', serialized[6]);
+ EXPECT_EQ('.', serialized[7]);
+ EXPECT_EQ('1', serialized[8]);
+ EXPECT_EQ(8, serialized[9]); // length("spdy/3.1")
+ EXPECT_EQ('s', serialized[10]);
+ EXPECT_EQ('p', serialized[11]);
+ EXPECT_EQ('d', serialized[12]);
+ EXPECT_EQ('y', serialized[13]);
+ EXPECT_EQ('/', serialized[14]);
+ EXPECT_EQ('3', serialized[15]);
+ EXPECT_EQ('.', serialized[16]);
+ EXPECT_EQ('1', serialized[17]);
+}
+
// Test that the server certificates are properly retrieved from the underlying
// SSL stack.
TEST_F(SSLClientSocketTest, VerifyServerChainProperlyOrdered) {
@@ -2889,7 +2916,7 @@
SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
server_options.enable_npn = true;
SSLConfig client_config;
- client_config.next_protos.push_back("http/1.1");
+ client_config.next_protos.push_back(kProtoHTTP11);
monitor_handshake_callback_ = true;
fail_handshake_after_false_start_ = true;
ASSERT_NO_FATAL_FAILURE(TestFalseStart(server_options, client_config, true));
@@ -2904,7 +2931,7 @@
SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
server_options.enable_npn = true;
SSLConfig client_config;
- client_config.next_protos.push_back("http/1.1");
+ client_config.next_protos.push_back(kProtoHTTP11);
monitor_handshake_callback_ = true;
ASSERT_NO_FATAL_FAILURE(TestFalseStart(server_options, client_config, true));
ASSERT_TRUE(ran_handshake_completion_callback_);
@@ -2918,7 +2945,7 @@
SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
server_options.enable_npn = true;
SSLConfig client_config;
- client_config.next_protos.push_back("http/1.1");
+ client_config.next_protos.push_back(kProtoHTTP11);
ASSERT_NO_FATAL_FAILURE(
TestFalseStart(server_options, client_config, true));
}
@@ -2941,7 +2968,7 @@
SpawnedTestServer::SSLOptions::KEY_EXCHANGE_RSA;
server_options.enable_npn = true;
SSLConfig client_config;
- client_config.next_protos.push_back("http/1.1");
+ client_config.next_protos.push_back(kProtoHTTP11);
ASSERT_NO_FATAL_FAILURE(
TestFalseStart(server_options, client_config, false));
}
@@ -2954,7 +2981,7 @@
SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA;
server_options.enable_npn = true;
SSLConfig client_config;
- client_config.next_protos.push_back("http/1.1");
+ client_config.next_protos.push_back(kProtoHTTP11);
// Let a full handshake complete with False Start.
ASSERT_NO_FATAL_FAILURE(
@@ -2987,7 +3014,7 @@
ASSERT_TRUE(StartTestServer(server_options));
SSLConfig client_config;
- client_config.next_protos.push_back("http/1.1");
+ client_config.next_protos.push_back(kProtoHTTP11);
// Start a handshake up to the server Finished message.
TestCompletionCallback callback;
diff --git a/net/socket/transport_client_socket_pool.h b/net/socket/transport_client_socket_pool.h
index bcc369f..2deb947 100644
--- a/net/socket/transport_client_socket_pool.h
+++ b/net/socket/transport_client_socket_pool.h
@@ -326,6 +326,12 @@
"436634 TransportConnectJobHelper::OnIOComplete"));
result = this->DoLoop(job, result);
+
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed.
+ tracked_objects::ScopedTracker tracking_profile1(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "436634 TransportConnectJobHelper::OnIOComplete1"));
+
if (result != ERR_IO_PENDING)
job->NotifyDelegateOfCompletion(result); // Deletes |job| and |this|
}
diff --git a/net/socket/websocket_transport_client_socket_pool.cc b/net/socket/websocket_transport_client_socket_pool.cc
index 15ec028..ec83529 100644
--- a/net/socket/websocket_transport_client_socket_pool.cc
+++ b/net/socket/websocket_transport_client_socket_pool.cc
@@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
+#include "base/profiler/scoped_tracker.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "base/values.h"
@@ -630,6 +631,11 @@
WebSocketTransportClientSocketPool::ConnectJobDelegate::OnConnectJobComplete(
int result,
ConnectJob* job) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "436634 WebSocket...::ConnectJobDelegate::OnConnectJobComplete"));
+
owner_->OnConnectJobComplete(result,
static_cast<WebSocketTransportConnectJob*>(job));
}
diff --git a/net/ssl/client_cert_store.h b/net/ssl/client_cert_store.h
index fe050e5..b1172de 100644
--- a/net/ssl/client_cert_store.h
+++ b/net/ssl/client_cert_store.h
@@ -14,8 +14,10 @@
class SSLCertRequestInfo;
-// The caller is expected to keep the ClientCertStore alive until the callback
-// supplied to GetClientCerts has been run.
+// A handle to a client certificate store to query matching certificates when a
+// server requests client auth. Note that there may be multiple ClientCertStore
+// objects corresponding to the same platform certificate store; each request
+// gets its own uniquely owned handle.
class NET_EXPORT ClientCertStore {
public:
virtual ~ClientCertStore() {}
@@ -23,8 +25,8 @@
// Get client certs matching the |cert_request_info|. On completion, the
// results will be stored in |selected_certs| and the |callback| will be run.
// The |callback| may be called sychronously. The caller must ensure the
- // ClientCertStore and the |selected_certs| object remain alive until the
- // callback has been run.
+ // ClientCertStore, |cert_request_info|, and |selected_certs| remain alive
+ // until the callback has been run.
virtual void GetClientCerts(const SSLCertRequestInfo& cert_request_info,
CertificateList* selected_certs,
const base::Closure& callback) = 0;
diff --git a/net/ssl/ssl_config.h b/net/ssl/ssl_config.h
index 5a0c0fa..2cbc995 100644
--- a/net/ssl/ssl_config.h
+++ b/net/ssl/ssl_config.h
@@ -9,6 +9,7 @@
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
#include "net/cert/x509_certificate.h"
+#include "net/socket/next_proto.h"
namespace net {
@@ -155,7 +156,7 @@
// Protocol Negotiation, but there is no overlap between the server's and
// client's protocol sets, then the first protocol in this list will be
// requested by the client.
- std::vector<std::string> next_protos;
+ NextProtoVector next_protos;
scoped_refptr<X509Certificate> client_cert;
};
diff --git a/net/test/embedded_test_server/embedded_test_server.cc b/net/test/embedded_test_server/embedded_test_server.cc
index 97b5d84..ac7d3bc 100644
--- a/net/test/embedded_test_server/embedded_test_server.cc
+++ b/net/test/embedded_test_server/embedded_test_server.cc
@@ -49,8 +49,15 @@
// This is a test-only server. Ignore I/O thread restrictions.
base::ThreadRestrictions::ScopedAllowIO allow_io;
+ std::string relative_url(request.relative_url);
+ // A proxy request will have an absolute path. Simulate the proxy by stripping
+ // the scheme, host, and port.
+ GURL relative_gurl(relative_url);
+ if (relative_gurl.is_valid())
+ relative_url = relative_gurl.PathForRequest();
+
// Trim the first byte ('/').
- std::string request_path(request.relative_url.substr(1));
+ std::string request_path = relative_url.substr(1);
// Remove the query string if present.
size_t query_pos = request_path.find('?');
diff --git a/net/test/spawned_test_server/local_test_server.cc b/net/test/spawned_test_server/local_test_server.cc
index c85e05a..309c69c 100644
--- a/net/test/spawned_test_server/local_test_server.cc
+++ b/net/test/spawned_test_server/local_test_server.cc
@@ -121,18 +121,17 @@
bool LocalTestServer::Stop() {
CleanUpWhenStoppingServer();
- if (!process_handle_)
+ if (!process_.IsValid())
return true;
// First check if the process has already terminated.
- bool ret = base::WaitForSingleProcess(process_handle_, base::TimeDelta());
+ bool ret = base::WaitForSingleProcess(process_.Handle(), base::TimeDelta());
if (!ret) {
- ret = base::KillProcess(process_handle_, 1, true);
+ ret = base::KillProcess(process_.Handle(), 1, true);
}
if (ret) {
- base::CloseProcessHandle(process_handle_);
- process_handle_ = base::kNullProcessHandle;
+ process_.Close();
} else {
VLOG(1) << "Kill failed?";
}
@@ -149,7 +148,6 @@
// number out over a pipe that this TestServer object will read from. Once
// that is complete, the host port pair will contain the actual port.
DCHECK(!GetPort());
- process_handle_ = base::kNullProcessHandle;
base::FilePath src_dir;
if (!PathService::Get(base::DIR_SOURCE_ROOT, &src_dir))
diff --git a/net/test/spawned_test_server/local_test_server.h b/net/test/spawned_test_server/local_test_server.h
index 37b1185..785d726 100644
--- a/net/test/spawned_test_server/local_test_server.h
+++ b/net/test/spawned_test_server/local_test_server.h
@@ -9,7 +9,7 @@
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
-#include "base/process/process_handle.h"
+#include "base/process/process.h"
#include "net/test/spawned_test_server/base_test_server.h"
#if defined(OS_WIN)
@@ -92,8 +92,8 @@
// Waits for the server to start. Returns true on success.
bool WaitToStart() WARN_UNUSED_RESULT;
- // Handle of the Python process running the test server.
- base::ProcessHandle process_handle_;
+ // The Python process running the test server.
+ base::Process process_;
#if defined(OS_WIN)
// The pipe file handle we read from.
diff --git a/net/test/spawned_test_server/local_test_server_posix.cc b/net/test/spawned_test_server/local_test_server_posix.cc
index 0edbedf..c770152 100644
--- a/net/test/spawned_test_server/local_test_server_posix.cc
+++ b/net/test/spawned_test_server/local_test_server_posix.cc
@@ -139,7 +139,8 @@
base::LaunchOptions options;
options.fds_to_remap = &map_write_fd;
- if (!base::LaunchProcess(python_command, options, &process_handle_)) {
+ process_ = base::LaunchProcess(python_command, options);
+ if (!process_.IsValid()) {
LOG(ERROR) << "Failed to launch " << python_command.GetCommandLineString();
return false;
}
diff --git a/net/test/spawned_test_server/local_test_server_win.cc b/net/test/spawned_test_server/local_test_server_win.cc
index 412e4e1..5eb5aaf 100644
--- a/net/test/spawned_test_server/local_test_server_win.cc
+++ b/net/test/spawned_test_server/local_test_server_win.cc
@@ -176,7 +176,8 @@
base::LaunchOptions launch_options;
launch_options.inherit_handles = true;
- if (!base::LaunchProcess(python_command, launch_options, &process_handle_)) {
+ process_ = base::LaunchProcess(python_command, launch_options);
+ if (!process_.IsValid()) {
LOG(ERROR) << "Failed to launch " << python_command.GetCommandLineString();
return false;
}
diff --git a/net/test/url_request/url_request_mock_data_job.cc b/net/test/url_request/url_request_mock_data_job.cc
new file mode 100644
index 0000000..54c174c
--- /dev/null
+++ b/net/test/url_request/url_request_mock_data_job.cc
@@ -0,0 +1,165 @@
+// 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 "net/test/url_request/url_request_mock_data_job.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "net/base/io_buffer.h"
+#include "net/base/url_util.h"
+#include "net/http/http_request_headers.h"
+#include "net/url_request/url_request_filter.h"
+
+namespace net {
+namespace {
+
+const char kMockHostname[] = "mock.data";
+
+// Gets the data from URL of the form:
+// scheme://kMockHostname/?data=abc&repeat_count=nnn.
+std::string GetDataFromRequest(const net::URLRequest& request) {
+ std::string value;
+ if (!GetValueForKeyInQuery(request.url(), "data", &value))
+ return "default_data";
+ return value;
+}
+
+// Gets the numeric repeat count from URL of the form:
+// scheme://kMockHostname/?data=abc&repeat_count=nnn.
+int GetRepeatCountFromRequest(const net::URLRequest& request) {
+ std::string value;
+ if (!GetValueForKeyInQuery(request.url(), "repeat", &value))
+ return 1;
+
+ int repeat_count;
+ if (!base::StringToInt(value, &repeat_count))
+ return 1;
+
+ DCHECK_GT(repeat_count, 0);
+
+ return repeat_count;
+}
+
+GURL GetMockUrl(const std::string& scheme,
+ const std::string& hostname,
+ const std::string& data,
+ int data_repeat_count) {
+ DCHECK_GT(data_repeat_count, 0);
+ std::string url(scheme + "://" + hostname + "/");
+ url.append("?data=");
+ url.append(data);
+ url.append("&repeat=");
+ url.append(base::IntToString(data_repeat_count));
+ return GURL(url);
+}
+
+class MockJobInterceptor : public net::URLRequestInterceptor {
+ public:
+ MockJobInterceptor() {}
+ ~MockJobInterceptor() override {}
+
+ // net::URLRequestInterceptor implementation
+ net::URLRequestJob* MaybeInterceptRequest(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ return new URLRequestMockDataJob(request, network_delegate,
+ GetDataFromRequest(*request),
+ GetRepeatCountFromRequest(*request));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockJobInterceptor);
+};
+
+} // namespace
+
+URLRequestMockDataJob::URLRequestMockDataJob(URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const std::string& data,
+ int data_repeat_count)
+ : URLRequestJob(request, network_delegate),
+ data_offset_(0),
+ weak_factory_(this) {
+ DCHECK_GT(data_repeat_count, 0);
+ for (int i = 0; i < data_repeat_count; ++i) {
+ data_.append(data);
+ }
+}
+
+void URLRequestMockDataJob::Start() {
+ // Start reading asynchronously so that all error reporting and data
+ // callbacks happen as they would for network requests.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(&URLRequestMockDataJob::StartAsync,
+ weak_factory_.GetWeakPtr()));
+}
+
+URLRequestMockDataJob::~URLRequestMockDataJob() {
+}
+
+bool URLRequestMockDataJob::ReadRawData(IOBuffer* buf,
+ int buf_size,
+ int* bytes_read) {
+ DCHECK(bytes_read);
+ *bytes_read = static_cast<int>(
+ std::min(static_cast<size_t>(buf_size), data_.length() - data_offset_));
+ memcpy(buf->data(), data_.c_str() + data_offset_, *bytes_read);
+ data_offset_ += *bytes_read;
+ return true;
+}
+
+void URLRequestMockDataJob::StartAsync() {
+ if (!request_)
+ return;
+
+ set_expected_content_size(data_.length());
+ NotifyHeadersComplete();
+}
+
+// static
+void URLRequestMockDataJob::AddUrlHandler() {
+ return AddUrlHandlerForHostname(kMockHostname);
+}
+
+// static
+void URLRequestMockDataJob::AddUrlHandlerForHostname(
+ const std::string& hostname) {
+ // Add |hostname| to net::URLRequestFilter for HTTP and HTTPS.
+ net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
+ filter->AddHostnameInterceptor("http", hostname,
+ make_scoped_ptr(new MockJobInterceptor()));
+ filter->AddHostnameInterceptor("https", hostname,
+ make_scoped_ptr(new MockJobInterceptor()));
+}
+
+// static
+GURL URLRequestMockDataJob::GetMockHttpUrl(const std::string& data,
+ int repeat_count) {
+ return GetMockHttpUrlForHostname(kMockHostname, data, repeat_count);
+}
+
+// static
+GURL URLRequestMockDataJob::GetMockHttpsUrl(const std::string& data,
+ int repeat_count) {
+ return GetMockHttpsUrlForHostname(kMockHostname, data, repeat_count);
+}
+
+// static
+GURL URLRequestMockDataJob::GetMockHttpUrlForHostname(
+ const std::string& hostname,
+ const std::string& data,
+ int repeat_count) {
+ return GetMockUrl("http", hostname, data, repeat_count);
+}
+
+// static
+GURL URLRequestMockDataJob::GetMockHttpsUrlForHostname(
+ const std::string& hostname,
+ const std::string& data,
+ int repeat_count) {
+ return GetMockUrl("https", hostname, data, repeat_count);
+}
+
+} // namespace net
diff --git a/net/test/url_request/url_request_mock_data_job.h b/net/test/url_request/url_request_mock_data_job.h
new file mode 100644
index 0000000..5bdfa23
--- /dev/null
+++ b/net/test/url_request/url_request_mock_data_job.h
@@ -0,0 +1,60 @@
+// 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 NET_URL_REQUEST_URL_REQUEST_MOCK_DATA_JOB_H_
+#define NET_URL_REQUEST_URL_REQUEST_MOCK_DATA_JOB_H_
+
+#include <string>
+
+#include "base/memory/weak_ptr.h"
+#include "net/base/net_export.h"
+#include "net/url_request/url_request_job.h"
+
+namespace net {
+
+class URLRequest;
+
+// Mock data job, which synchronously returns data repeated multiple times.
+class URLRequestMockDataJob : public URLRequestJob {
+ public:
+ URLRequestMockDataJob(URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const std::string& data,
+ int data_repeat_count);
+
+ void Start() override;
+ bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
+
+ // Adds the testing URLs to the URLRequestFilter.
+ static void AddUrlHandler();
+ static void AddUrlHandlerForHostname(const std::string& hostname);
+
+ // Given data and repeat cound, constructs a mock URL that will return that
+ // data repeated |repeat_count| times when started. |data| must be safe for
+ // URL.
+ static GURL GetMockHttpUrl(const std::string& data, int repeat_count);
+ static GURL GetMockHttpsUrl(const std::string& data, int repeat_count);
+
+ // URLRequestFailedJob must be added as a handler for |hostname| for
+ // the returned URL to return |net_error|.
+ static GURL GetMockHttpUrlForHostname(const std::string& hostname,
+ const std::string& data,
+ int repeat_count);
+ static GURL GetMockHttpsUrlForHostname(const std::string& hostname,
+ const std::string& data,
+ int repeat_count);
+
+ private:
+ ~URLRequestMockDataJob() override;
+
+ void StartAsync();
+
+ std::string data_;
+ size_t data_offset_;
+ base::WeakPtrFactory<URLRequestMockDataJob> weak_factory_;
+};
+
+} // namespace net
+
+#endif // NET_URL_REQUEST_URL_REQUEST_SIMPLE_JOB_H_
diff --git a/net/tools/crash_cache/crash_cache.cc b/net/tools/crash_cache/crash_cache.cc
index d548c79..9ec15bb 100644
--- a/net/tools/crash_cache/crash_cache.cc
+++ b/net/tools/crash_cache/crash_cache.cc
@@ -17,7 +17,6 @@
#include "base/path_service.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
-#include "base/process/process_handle.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -50,15 +49,15 @@
base::CommandLine cmdline(exe);
cmdline.AppendArg(base::IntToString(action));
- base::ProcessHandle handle;
- if (!base::LaunchProcess(cmdline, base::LaunchOptions(), &handle)) {
+ base::Process process = base::LaunchProcess(cmdline, base::LaunchOptions());
+ if (!process.IsValid()) {
printf("Unable to run test %d\n", action);
return GENERIC;
}
int exit_code;
- if (!base::WaitForExitCode(handle, &exit_code)) {
+ if (!process.WaitForExit(&exit_code)) {
printf("Unable to get return code, test %d\n", action);
return GENERIC;
}
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index 3cd8cf4..2deb0f5 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -97,18 +97,32 @@
filtered_read_buffer_ = buf;
filtered_read_buffer_len_ = buf_size;
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile2(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION("423948 URLRequestJob::Read2"));
+
if (ReadFilteredData(bytes_read)) {
rv = true; // We have data to return.
// It is fine to call DoneReading even if ReadFilteredData receives 0
// bytes from the net, but we avoid making that call if we know for
// sure that's the case (ReadRawDataHelper path).
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is
+ // fixed.
+ tracked_objects::ScopedTracker tracking_profile3(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION("423948 URLRequestJob::Read3"));
+
if (*bytes_read == 0)
DoneReading();
} else {
rv = false; // Error, or a new IO is pending.
}
}
+
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile4(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION("423948 URLRequestJob::Read4"));
+
if (rv && *bytes_read == 0)
NotifyDone(URLRequestStatus());
return rv;
@@ -487,6 +501,10 @@
}
void URLRequestJob::NotifyReadComplete(int bytes_read) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION("URLRequestJob::NotifyReadComplete"));
+
if (!request_ || !request_->has_delegate())
return; // The request was destroyed, so there is no more work to do.
@@ -801,6 +819,11 @@
bool URLRequestJob::ReadRawDataHelper(IOBuffer* buf, int buf_size,
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 URLRequestJob::ReadRawDataHelper"));
+
DCHECK(!request_->status().is_io_pending());
DCHECK(raw_read_buffer_.get() == NULL);
diff --git a/services/surfaces/surfaces_impl.cc b/services/surfaces/surfaces_impl.cc
index df91bf8..eccdd75 100644
--- a/services/surfaces/surfaces_impl.cc
+++ b/services/surfaces/surfaces_impl.cc
@@ -19,7 +19,7 @@
namespace surfaces {
namespace {
-void CallCallback(const mojo::Closure& callback) {
+void CallCallback(const mojo::Closure& callback, bool frame_drawn) {
callback.Run();
}
}
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index bd039e3..07b47d2 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -257,10 +257,6 @@
# define SK_SUPPORT_LEGACY_PUBLIC_IMAGEINFO_FIELDS
#endif
-#ifndef SK_SUPPORT_LEGACY_PICTURE_CLONE
-# define SK_SUPPORT_LEGACY_PICTURE_CLONE
-#endif
-
#ifndef SK_IGNORE_ETC1_SUPPORT
# define SK_IGNORE_ETC1_SUPPORT
#endif
@@ -269,24 +265,14 @@
# define SK_IGNORE_GPU_DITHER
#endif
-#ifndef SK_LEGACY_PICTURE_SIZE_API
-# define SK_LEGACY_PICTURE_SIZE_API
-#endif
-
#ifndef SK_LEGACY_PICTURE_DRAW_API
# define SK_LEGACY_PICTURE_DRAW_API
#endif
-
-// Turns SkPicture::clone() into a simple "return SkRef(this);" as a way to
-// test the threadsafety of SkPicture playback.
-#define SK_PICTURE_CLONE_NOOP 1
-
-// Turns on new (nicer, hopefully faster) SkPicture backend.
-#define SK_PICTURE_USE_SK_RECORD 1
-
-// Run a few optimization passes over the SkRecord after recording.
-#define SK_PICTURE_OPTIMIZE_SK_RECORD 1
+// If this goes well, we can have Skia respect DYNAMIC_ANNOTATIONS_ENABLED directly.
+#if DYNAMIC_ANNOTATIONS_ENABLED
+# define SK_DYNAMIC_ANNOTATIONS_ENABLED 1
+#endif
// ===== End Chrome-specific definitions =====
diff --git a/skia/ext/pixel_ref_utils.cc b/skia/ext/pixel_ref_utils.cc
index 324adbd..777c253 100644
--- a/skia/ext/pixel_ref_utils.cc
+++ b/skia/ext/pixel_ref_utils.cc
@@ -351,15 +351,17 @@
pixel_refs->clear();
DiscardablePixelRefSet pixel_ref_set(pixel_refs);
+ SkRect picture_bounds = picture->cullRect();
+ SkIRect picture_ibounds = picture_bounds.roundOut();
SkBitmap empty_bitmap;
- empty_bitmap.setInfo(SkImageInfo::MakeUnknown(picture->width(), picture->height()));
+ empty_bitmap.setInfo(SkImageInfo::MakeUnknown(picture_ibounds.width(),
+ picture_ibounds.height()));
GatherPixelRefDevice device(empty_bitmap, &pixel_ref_set);
SkNoSaveLayerCanvas canvas(&device);
- canvas.clipRect(SkRect::MakeWH(picture->width(), picture->height()),
- SkRegion::kIntersect_Op,
- false);
+ // Draw the picture pinned against our top/left corner.
+ canvas.translate(-picture_bounds.left(), -picture_bounds.top());
canvas.drawPicture(picture);
}
diff --git a/skia/ext/skia_utils_mac.mm b/skia/ext/skia_utils_mac.mm
index dd8f560..9e552eb 100644
--- a/skia/ext/skia_utils_mac.mm
+++ b/skia/ext/skia_utils_mac.mm
@@ -376,16 +376,9 @@
if (!bitmap_.extractSubset(&subset, bounds)) {
return;
}
- // Neutralize the global matrix by concatenating the inverse. In the
- // future, Skia may provide some mechanism to set the device portion of
- // the matrix to identity without clobbering any hosting matrix (e.g., the
- // picture's matrix).
- const SkMatrix& skMatrix = canvas_->getTotalMatrix();
- SkMatrix inverse;
- if (!skMatrix.invert(&inverse))
- return;
+ subset.setImmutable(); // Prevents a defensive copy inside Skia.
canvas_->save();
- canvas_->concat(inverse);
+ canvas_->setMatrix(SkMatrix::I()); // Reset back to device space.
canvas_->translate(bounds.x() + bitmapOffset_.x(),
bounds.y() + bitmapOffset_.y());
canvas_->scale(1.f / bitmapScaleFactor_, 1.f / bitmapScaleFactor_);
diff --git a/sky/engine/core/rendering/RenderBlock.cpp b/sky/engine/core/rendering/RenderBlock.cpp
index e4f0aef..1c66659 100644
--- a/sky/engine/core/rendering/RenderBlock.cpp
+++ b/sky/engine/core/rendering/RenderBlock.cpp
@@ -49,7 +49,6 @@
#include "sky/engine/core/rendering/style/RenderStyle.h"
#include "sky/engine/platform/geometry/FloatQuad.h"
#include "sky/engine/platform/geometry/TransformState.h"
-#include "sky/engine/platform/graphics/GraphicsContextCullSaver.h"
#include "sky/engine/platform/graphics/GraphicsContextStateSaver.h"
#include "sky/engine/wtf/StdLibExtras.h"
#include "sky/engine/wtf/TemporaryChange.h"
@@ -597,13 +596,6 @@
bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset, contentsClipBehavior);
{
- GraphicsContextCullSaver cullSaver(*paintInfo.context);
- // Cull if we have more than one child and we didn't already clip.
- bool shouldCull = document().settings()->containerCullingEnabled() && !pushedClip && !isDocumentElement()
- && firstChild() && lastChild() && firstChild() != lastChild();
- if (shouldCull)
- cullSaver.cull(overflowBox);
-
paintObject(paintInfo, adjustedPaintOffset);
}
if (pushedClip)
diff --git a/sky/engine/platform/graphics/GraphicsContext.cpp b/sky/engine/platform/graphics/GraphicsContext.cpp
index 8f17728..2a7fb35 100644
--- a/sky/engine/platform/graphics/GraphicsContext.cpp
+++ b/sky/engine/platform/graphics/GraphicsContext.cpp
@@ -1471,25 +1471,6 @@
m_canvas->clipRRect(rect, op, aa == AntiAliased);
}
-void GraphicsContext::beginCull(const FloatRect& rect)
-{
- if (contextDisabled())
- return;
-
- realizeCanvasSave();
- m_canvas->pushCull(rect);
-}
-
-void GraphicsContext::endCull()
-{
- if (contextDisabled())
- return;
-
- realizeCanvasSave();
-
- m_canvas->popCull();
-}
-
void GraphicsContext::rotate(float angleInRadians)
{
if (contextDisabled())
diff --git a/sky/engine/platform/graphics/GraphicsContext.h b/sky/engine/platform/graphics/GraphicsContext.h
index 6f59a2f..782fa23 100644
--- a/sky/engine/platform/graphics/GraphicsContext.h
+++ b/sky/engine/platform/graphics/GraphicsContext.h
@@ -325,9 +325,6 @@
void beginLayer(float opacity, CompositeOperator, const FloatRect* = 0, ColorFilter = ColorFilterNone, ImageFilter* = 0);
void endLayer();
- void beginCull(const FloatRect&);
- void endCull();
-
// Instead of being dispatched to the active canvas, draw commands following beginRecording()
// are stored in a display list that can be replayed at a later time.
void beginRecording(const FloatRect& bounds);
diff --git a/sky/engine/platform/graphics/GraphicsContextCullSaver.h b/sky/engine/platform/graphics/GraphicsContextCullSaver.h
deleted file mode 100644
index 7ea99f4..0000000
--- a/sky/engine/platform/graphics/GraphicsContextCullSaver.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef GraphicsContextCullSaver_h
-#define GraphicsContextCullSaver_h
-
-#include "sky/engine/platform/graphics/GraphicsContext.h"
-
-namespace blink {
-
-class FloatRect;
-
-class GraphicsContextCullSaver {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- GraphicsContextCullSaver(GraphicsContext& context)
- : m_context(context)
- , m_cullApplied(false)
- {
- }
-
- GraphicsContextCullSaver(GraphicsContext& context, const FloatRect& rect)
- : m_context(context)
- , m_cullApplied(true)
- {
- context.beginCull(rect);
- }
-
- ~GraphicsContextCullSaver()
- {
- if (m_cullApplied)
- m_context.endCull();
- }
-
- void cull(const FloatRect& rect)
- {
- ASSERT(!m_cullApplied);
- m_context.beginCull(rect);
- m_cullApplied = true;
- }
-
-private:
- GraphicsContext& m_context;
- bool m_cullApplied;
-};
-
-} // namespace blink
-
-#endif // GraphicsContextCullSaver_h
diff --git a/sky/engine/platform/graphics/GraphicsContextRecorder.cpp b/sky/engine/platform/graphics/GraphicsContextRecorder.cpp
index 6b8851b..05d82f6 100644
--- a/sky/engine/platform/graphics/GraphicsContextRecorder.cpp
+++ b/sky/engine/platform/graphics/GraphicsContextRecorder.cpp
@@ -100,10 +100,9 @@
PassOwnPtr<Vector<char> > GraphicsContextSnapshot::replay(unsigned fromStep, unsigned toStep, double scale) const
{
- int width = ceil(scale * m_picture->width());
- int height = ceil(scale * m_picture->height());
+ const SkIRect bounds = m_picture->cullRect().roundOut();
SkBitmap bitmap;
- bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height));
+ bitmap.allocPixels(SkImageInfo::MakeN32Premul(bounds.width(), bounds.height()));
{
ReplayingCanvas canvas(bitmap, fromStep, toStep);
canvas.scale(scale, scale);
@@ -122,8 +121,9 @@
{
OwnPtr<GraphicsContextSnapshot::Timings> timings = adoptPtr(new GraphicsContextSnapshot::Timings());
timings->reserveCapacity(minRepeatCount);
+ const SkIRect bounds = m_picture->cullRect().roundOut();
SkBitmap bitmap;
- bitmap.allocPixels(SkImageInfo::MakeN32Premul(m_picture->width(), m_picture->height()));
+ bitmap.allocPixels(SkImageInfo::MakeN32Premul(bounds.width(), bounds.height()));
OwnPtr<ProfilingCanvas> canvas = adoptPtr(new ProfilingCanvas(bitmap));
double now = WTF::monotonicallyIncreasingTime();
@@ -144,7 +144,8 @@
PassRefPtr<JSONArray> GraphicsContextSnapshot::snapshotCommandLog() const
{
- LoggingCanvas canvas(m_picture->width(), m_picture->height());
+ const SkIRect bounds = m_picture->cullRect().roundOut();
+ LoggingCanvas canvas(bounds.width(), bounds.height());
m_picture->draw(&canvas);
return canvas.log();
}
diff --git a/sky/engine/platform/graphics/InterceptingCanvas.h b/sky/engine/platform/graphics/InterceptingCanvas.h
index a3e9ba5..32e50a4 100644
--- a/sky/engine/platform/graphics/InterceptingCanvas.h
+++ b/sky/engine/platform/graphics/InterceptingCanvas.h
@@ -48,7 +48,6 @@
virtual void drawPath(const SkPath&, const SkPaint&) override = 0;
virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint* = 0) override = 0;
virtual void drawBitmapRectToRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*, DrawBitmapRectFlags) override = 0;
- virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&, const SkPaint* = 0) override = 0;
virtual void drawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, const SkPaint*) override = 0;
virtual void drawSprite(const SkBitmap&, int left, int top, const SkPaint* = 0) override = 0;
virtual void drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], const SkPoint texs[],
@@ -63,8 +62,6 @@
virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint&) override = 0;
virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint&) override = 0;
virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath&, const SkMatrix*, const SkPaint&) override = 0;
- virtual void onPushCull(const SkRect& cullRect) override = 0;
- virtual void onPopCull() override = 0;
virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override = 0;
virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override = 0;
virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override = 0;
diff --git a/sky/engine/platform/graphics/LoggingCanvas.cpp b/sky/engine/platform/graphics/LoggingCanvas.cpp
index 18adab9..8cb941f 100644
--- a/sky/engine/platform/graphics/LoggingCanvas.cpp
+++ b/sky/engine/platform/graphics/LoggingCanvas.cpp
@@ -160,16 +160,6 @@
this->SkCanvas::drawBitmapRectToRect(bitmap, src, dst, paint, flags);
}
-void LoggingCanvas::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, const SkPaint* paint)
-{
- AutoLogger logger(this);
- RefPtr<JSONObject> params = logger.logItemWithParams("drawBitmapMatrix");
- params->setObject("bitmap", objectForSkBitmap(bitmap));
- params->setArray("matrix", arrayForSkMatrix(m));
- params->setObject("paint", objectForSkPaint(*paint));
- this->SkCanvas::drawBitmapMatrix(bitmap, m, paint);
-}
-
void LoggingCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, const SkPaint* paint)
{
AutoLogger logger(this);
@@ -288,21 +278,6 @@
this->SkCanvas::onDrawTextOnPath(text, byteLength, path, matrix, paint);
}
-void LoggingCanvas::onPushCull(const SkRect& cullRect)
-{
- AutoLogger logger(this);
- RefPtr<JSONObject> params = logger.logItemWithParams("pushCull");
- params->setObject("cullRect", objectForSkRect(cullRect));
- this->SkCanvas::onPushCull(cullRect);
-}
-
-void LoggingCanvas::onPopCull()
-{
- AutoLogger logger(this);
- logger.logItem("popCull");
- this->SkCanvas::onPopCull();
-}
-
void LoggingCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle style)
{
AutoLogger logger(this);
@@ -461,9 +436,10 @@
PassRefPtr<JSONObject> LoggingCanvas::objectForSkPicture(const SkPicture& picture)
{
+ const SkIRect bounds = picture.cullRect().roundOut();
RefPtr<JSONObject> pictureItem = JSONObject::create();
- pictureItem->setNumber("width", picture.width());
- pictureItem->setNumber("height", picture.height());
+ pictureItem->setNumber("width", bounds.width());
+ pictureItem->setNumber("height", bounds.height());
return pictureItem.release();
}
diff --git a/sky/engine/platform/graphics/LoggingCanvas.h b/sky/engine/platform/graphics/LoggingCanvas.h
index 3483015..6abb7a3 100644
--- a/sky/engine/platform/graphics/LoggingCanvas.h
+++ b/sky/engine/platform/graphics/LoggingCanvas.h
@@ -49,7 +49,6 @@
virtual void drawPath(const SkPath&, const SkPaint&) override;
virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint* = 0) override;
virtual void drawBitmapRectToRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*, DrawBitmapRectFlags) override;
- virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&, const SkPaint* = 0) override;
virtual void drawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, const SkPaint*) override;
virtual void drawSprite(const SkBitmap&, int left, int top, const SkPaint* = 0) override;
virtual void drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], const SkPoint texs[],
@@ -64,8 +63,6 @@
virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint&) override;
virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint&) override;
virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath&, const SkMatrix*, const SkPaint&) override;
- virtual void onPushCull(const SkRect& cullRect) override;
- virtual void onPopCull() override;
virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override;
diff --git a/sky/engine/platform/graphics/ProfilingCanvas.cpp b/sky/engine/platform/graphics/ProfilingCanvas.cpp
index 2940339..728a5c0 100644
--- a/sky/engine/platform/graphics/ProfilingCanvas.cpp
+++ b/sky/engine/platform/graphics/ProfilingCanvas.cpp
@@ -118,12 +118,6 @@
this->SkCanvas::drawBitmapRectToRect(bitmap, src, dst, paint, flags);
}
-void ProfilingCanvas::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, const SkPaint* paint)
-{
- AutoStamper stamper(this);
- this->SkCanvas::drawBitmapMatrix(bitmap, m, paint);
-}
-
void ProfilingCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, const SkPaint* paint)
{
AutoStamper stamper(this);
@@ -197,18 +191,6 @@
this->SkCanvas::onDrawTextOnPath(text, byteLength, path, matrix, paint);
}
-void ProfilingCanvas::onPushCull(const SkRect& cullRect)
-{
- AutoStamper stamper(this);
- this->SkCanvas::onPushCull(cullRect);
-}
-
-void ProfilingCanvas::onPopCull()
-{
- AutoStamper stamper(this);
- this->SkCanvas::onPopCull();
-}
-
void ProfilingCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle)
{
AutoStamper stamper(this);
diff --git a/sky/engine/platform/graphics/ProfilingCanvas.h b/sky/engine/platform/graphics/ProfilingCanvas.h
index b390ab4..4ec11f2 100644
--- a/sky/engine/platform/graphics/ProfilingCanvas.h
+++ b/sky/engine/platform/graphics/ProfilingCanvas.h
@@ -49,7 +49,6 @@
virtual void drawPath(const SkPath&, const SkPaint&) override;
virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint* = 0) override;
virtual void drawBitmapRectToRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*, DrawBitmapRectFlags) override;
- virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&, const SkPaint* = 0) override;
virtual void drawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, const SkPaint*) override;
virtual void drawSprite(const SkBitmap&, int left, int top, const SkPaint* = 0) override;
virtual void drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], const SkPoint texs[],
@@ -64,8 +63,6 @@
virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint&) override;
virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint&) override;
virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath&, const SkMatrix*, const SkPaint&) override;
- virtual void onPushCull(const SkRect& cullRect) override;
- virtual void onPopCull() override;
virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override;
diff --git a/sky/engine/platform/graphics/ReplayingCanvas.cpp b/sky/engine/platform/graphics/ReplayingCanvas.cpp
index 3c13a10..dbb2d19 100644
--- a/sky/engine/platform/graphics/ReplayingCanvas.cpp
+++ b/sky/engine/platform/graphics/ReplayingCanvas.cpp
@@ -132,12 +132,6 @@
this->SkCanvas::drawBitmapRectToRect(bitmap, src, dst, paint, flags);
}
-void ReplayingCanvas::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, const SkPaint* paint)
-{
- AutoReplayer replayer(this);
- this->SkCanvas::drawBitmapMatrix(bitmap, m, paint);
-}
-
void ReplayingCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, const SkPaint* paint)
{
AutoReplayer replayer(this);
@@ -211,18 +205,6 @@
this->SkCanvas::onDrawTextOnPath(text, byteLength, path, matrix, paint);
}
-void ReplayingCanvas::onPushCull(const SkRect& cullRect)
-{
- AutoReplayer replayer(this);
- this->SkCanvas::onPushCull(cullRect);
-}
-
-void ReplayingCanvas::onPopCull()
-{
- AutoReplayer replayer(this);
- this->SkCanvas::onPopCull();
-}
-
void ReplayingCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle)
{
AutoReplayer replayer(this);
diff --git a/sky/engine/platform/graphics/ReplayingCanvas.h b/sky/engine/platform/graphics/ReplayingCanvas.h
index a8e9541..4939db6 100644
--- a/sky/engine/platform/graphics/ReplayingCanvas.h
+++ b/sky/engine/platform/graphics/ReplayingCanvas.h
@@ -51,7 +51,6 @@
virtual void drawPath(const SkPath&, const SkPaint&) override;
virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint* = 0) override;
virtual void drawBitmapRectToRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*, DrawBitmapRectFlags) override;
- virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&, const SkPaint* = 0) override;
virtual void drawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, const SkPaint*) override;
virtual void drawSprite(const SkBitmap&, int left, int top, const SkPaint* = 0) override;
virtual void drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], const SkPoint texs[],
@@ -66,8 +65,6 @@
virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint&) override;
virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint&) override;
virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath&, const SkMatrix*, const SkPaint&) override;
- virtual void onPushCull(const SkRect& cullRect) override;
- virtual void onPopCull() override;
virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override;
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 0927e93..42cc7c7 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -362,71 +362,5 @@
{ "test": "content_unittests", "args": ["--enable-browser-side-navigation"] },
{ "test": "content_browsertests", "args": ["--enable-browser-side-navigation"] }
]
- },
- "Linux ChromeOS MSan Tests": {
- "gtest_tests": [
- "accessibility_unittests",
- "app_list_unittests",
- "app_shell_browsertests",
- "aura_unittests",
- "base_unittests",
- "cacheinvalidation_unittests",
- "cast_unittests",
- "cc_unittests",
- "chromedriver_unittests",
- "components_unittests",
- "content_browsertests",
- "content_unittests",
- "crypto_unittests",
- "dbus_unittests",
- "device_unittests",
- "display_unittests",
- "events_unittests",
- "extensions_unittests",
- "gcm_unit_tests",
- "gfx_unittests",
- "google_apis_unittests",
- "gpu_unittests",
- "interactive_ui_tests",
- "ipc_mojo_unittests",
- "ipc_tests",
- "jingle_unittests",
- "media_unittests",
- "mojo_common_unittests",
- "mojo_public_bindings_unittests",
- "mojo_public_environment_unittests",
- "mojo_public_system_unittests",
- "mojo_public_utility_unittests",
- "mojo_system_unittests",
- "nacl_loader_unittests",
- "net_unittests",
- "ppapi_unittests",
- "printing_unittests",
- "remoting_unittests",
- "sandbox_linux_unittests",
- "sql_unittests",
- "sync_unit_tests",
- "ui_base_unittests",
- "ui_touch_selection_unittests",
- "unit_tests",
- "url_unittests",
- "views_unittests",
- "wm_unittests"
- ]
- },
- "Linux ChromeOS MSan Browser (1)": {
- "gtest_tests": [
- {"test": "browser_tests", "shard_index": 0, "total_shards": 3}
- ]
- },
- "Linux ChromeOS MSan Browser (2)": {
- "gtest_tests": [
- {"test": "browser_tests", "shard_index": 1, "total_shards": 3}
- ]
- },
- "Linux ChromeOS MSan Browser (3)": {
- "gtest_tests": [
- {"test": "browser_tests", "shard_index": 2, "total_shards": 3}
- ]
}
}
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index 39bfb16..d9f5f96 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -1,8 +1,18 @@
{
"Linux Tests": {
"gtest_tests": [
- "accessibility_unittests",
- "app_list_unittests",
+ {
+ "test": "accessibility_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "app_list_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"app_shell_browsertests",
"app_shell_unittests",
"aura_unittests",
@@ -41,10 +51,20 @@
"dbus_unittests",
"device_unittests",
"display_unittests",
- "events_unittests",
+ {
+ "test": "events_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"extensions_unittests",
"gcm_unit_tests",
- "gfx_unittests",
+ {
+ "test": "gfx_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"google_apis_unittests",
"gpu_unittests",
{
@@ -75,7 +95,12 @@
"remoting_unittests",
"sandbox_linux_unittests",
"sql_unittests",
- "ui_base_unittests",
+ {
+ "test": "ui_base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"ui_touch_selection_unittests",
{
"test": "sync_integration_tests",
@@ -111,8 +136,18 @@
},
"Linux Tests (dbg)(1)(32)": {
"gtest_tests": [
- "accessibility_unittests",
- "app_list_unittests",
+ {
+ "test": "accessibility_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "app_list_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"app_shell_browsertests",
"app_shell_unittests",
"aura_unittests",
@@ -151,10 +186,20 @@
"dbus_unittests",
"device_unittests",
"display_unittests",
- "events_unittests",
+ {
+ "test": "events_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"extensions_unittests",
"gcm_unit_tests",
- "gfx_unittests",
+ {
+ "test": "gfx_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"google_apis_unittests",
"gpu_unittests",
{
@@ -185,7 +230,12 @@
"remoting_unittests",
"sandbox_linux_unittests",
"sql_unittests",
- "ui_base_unittests",
+ {
+ "test": "ui_base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"ui_touch_selection_unittests",
{
"test": "sync_integration_tests",
@@ -213,8 +263,18 @@
},
"Linux Tests (dbg)(1)": {
"gtest_tests": [
- "accessibility_unittests",
- "app_list_unittests",
+ {
+ "test": "accessibility_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "app_list_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"app_shell_browsertests",
"app_shell_unittests",
"aura_unittests",
@@ -253,10 +313,20 @@
"dbus_unittests",
"device_unittests",
"display_unittests",
- "events_unittests",
+ {
+ "test": "events_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"extensions_unittests",
"gcm_unit_tests",
- "gfx_unittests",
+ {
+ "test": "gfx_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"google_apis_unittests",
"gpu_unittests",
{
@@ -291,7 +361,12 @@
"args": ["--test-launcher-print-test-stdio=always"]
},
"sql_unittests",
- "ui_base_unittests",
+ {
+ "test": "ui_base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"ui_touch_selection_unittests",
{
"test": "sync_integration_tests",
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index 0ea46e9..8a20416 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -1,8 +1,18 @@
{
"Mac10.6 Tests": {
"gtest_tests": [
- "accessibility_unittests",
- "app_list_unittests",
+ {
+ "test": "accessibility_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "app_list_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
{
"test": "base_unittests",
"swarming": {
@@ -36,7 +46,12 @@
"crypto_unittests",
"extensions_unittests",
"gcm_unit_tests",
- "gfx_unittests",
+ {
+ "test": "gfx_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"gpu_unittests",
"google_apis_unittests",
{
@@ -48,7 +63,12 @@
"ipc_tests",
"jingle_unittests",
"media_unittests",
- "message_center_unittests",
+ {
+ "test": "message_center_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"mojo_common_unittests",
"mojo_public_bindings_unittests",
"mojo_public_environment_unittests",
@@ -73,7 +93,12 @@
}
},
"sync_unit_tests",
- "ui_base_unittests",
+ {
+ "test": "ui_base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
{
"test": "unit_tests",
"swarming": {
@@ -99,8 +124,18 @@
},
"Mac10.8 Tests": {
"gtest_tests": [
- "accessibility_unittests",
- "app_list_unittests",
+ {
+ "test": "accessibility_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "app_list_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
{
"test": "base_unittests",
"swarming": {
@@ -134,7 +169,12 @@
"crypto_unittests",
"extensions_unittests",
"gcm_unit_tests",
- "gfx_unittests",
+ {
+ "test": "gfx_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"gpu_unittests",
"google_apis_unittests",
{
@@ -146,7 +186,12 @@
"ipc_tests",
"jingle_unittests",
"media_unittests",
- "message_center_unittests",
+ {
+ "test": "message_center_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"mojo_common_unittests",
"mojo_public_bindings_unittests",
"mojo_public_environment_unittests",
@@ -171,7 +216,12 @@
}
},
"sync_unit_tests",
- "ui_base_unittests",
+ {
+ "test": "ui_base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
{
"test": "unit_tests",
"swarming": {
@@ -197,8 +247,18 @@
},
"Mac10.9 Tests": {
"gtest_tests": [
- "accessibility_unittests",
- "app_list_unittests",
+ {
+ "test": "accessibility_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "app_list_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
{
"test": "base_unittests",
"swarming": {
@@ -232,7 +292,12 @@
"crypto_unittests",
"extensions_unittests",
"gcm_unit_tests",
- "gfx_unittests",
+ {
+ "test": "gfx_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"gpu_unittests",
"google_apis_unittests",
{
@@ -244,7 +309,12 @@
"ipc_tests",
"jingle_unittests",
"media_unittests",
- "message_center_unittests",
+ {
+ "test": "message_center_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"mojo_common_unittests",
"mojo_public_bindings_unittests",
"mojo_public_environment_unittests",
@@ -269,7 +339,12 @@
}
},
"sync_unit_tests",
- "ui_base_unittests",
+ {
+ "test": "ui_base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
{
"test": "unit_tests",
"swarming": {
@@ -295,8 +370,18 @@
},
"Mac10.9 Tests (dbg)": {
"gtest_tests": [
- "accessibility_unittests",
- "app_list_unittests",
+ {
+ "test": "accessibility_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "app_list_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
{
"test": "base_unittests",
"swarming": {
@@ -330,7 +415,12 @@
"crypto_unittests",
"extensions_unittests",
"gcm_unit_tests",
- "gfx_unittests",
+ {
+ "test": "gfx_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"gpu_unittests",
"google_apis_unittests",
{
@@ -343,7 +433,12 @@
"ipc_tests",
"jingle_unittests",
"media_unittests",
- "message_center_unittests",
+ {
+ "test": "message_center_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"mojo_common_unittests",
"mojo_public_bindings_unittests",
"mojo_public_environment_unittests",
@@ -368,7 +463,12 @@
}
},
"sync_unit_tests",
- "ui_base_unittests",
+ {
+ "test": "ui_base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
{
"test": "unit_tests",
"swarming": {
diff --git a/testing/buildbot/chromium.memory.fyi.json b/testing/buildbot/chromium.memory.fyi.json
index 1db2fb5..3852f7a 100644
--- a/testing/buildbot/chromium.memory.fyi.json
+++ b/testing/buildbot/chromium.memory.fyi.json
@@ -64,5 +64,70 @@
"gtest_tests": [
{"test": "browser_tests", "shard_index": 2, "total_shards": 3}
]
+ },
+ "Linux ChromeOS MSan Tests": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ "app_shell_browsertests",
+ "aura_unittests",
+ "base_unittests",
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ "content_browsertests",
+ "content_unittests",
+ "crypto_unittests",
+ "dbus_unittests",
+ "device_unittests",
+ "display_unittests",
+ "events_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "interactive_ui_tests",
+ "ipc_mojo_unittests",
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "mojo_common_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_system_unittests",
+ "nacl_loader_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "sql_unittests",
+ "sync_unit_tests",
+ "ui_base_unittests",
+ "unit_tests",
+ "url_unittests",
+ "views_unittests",
+ "wm_unittests"
+ ]
+ },
+ "Linux ChromeOS MSan Browser (1)": {
+ "gtest_tests": [
+ {"test": "browser_tests", "shard_index": 0, "total_shards": 3}
+ ]
+ },
+ "Linux ChromeOS MSan Browser (2)": {
+ "gtest_tests": [
+ {"test": "browser_tests", "shard_index": 1, "total_shards": 3}
+ ]
+ },
+ "Linux ChromeOS MSan Browser (3)": {
+ "gtest_tests": [
+ {"test": "browser_tests", "shard_index": 2, "total_shards": 3}
+ ]
}
}
diff --git a/testing/buildbot/chromium_trybot.json b/testing/buildbot/chromium_trybot.json
index 9a0e4af..7925d5d 100644
--- a/testing/buildbot/chromium_trybot.json
+++ b/testing/buildbot/chromium_trybot.json
@@ -3,12 +3,22 @@
"all"
],
"gtest_tests": [
- "accessibility_unittests",
+ {
+ "test": "accessibility_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
{
"test": "app_installer_unittests",
"platforms": ["win"]
},
- "app_list_unittests",
+ {
+ "test": "app_list_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
{
"test": "ash_unittests",
"chromium_configs": [
@@ -84,13 +94,23 @@
"platforms": ["linux"]
},
"device_unittests",
- "events_unittests",
+ {
+ "test": "events_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
{
"test": "extensions_unittests",
"platforms": ["win", "mac", "linux"]
},
"gcm_unit_tests",
- "gfx_unittests",
+ {
+ "test": "gfx_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"google_apis_unittests",
"gpu_unittests",
{
@@ -116,7 +136,12 @@
},
"media_perftests",
"media_unittests",
- "message_center_unittests",
+ {
+ "test": "message_center_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"mojo_common_unittests",
"mojo_public_bindings_unittests",
"mojo_public_environment_unittests",
@@ -157,7 +182,12 @@
}
},
"sync_unit_tests",
- "ui_base_unittests",
+ {
+ "test": "ui_base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
"ui_touch_selection_unittests",
{
"test": "unit_tests",
diff --git a/third_party/cython/rules.gni b/third_party/cython/rules.gni
index 53125fe..5cfea1a 100644
--- a/third_party/cython/rules.gni
+++ b/third_party/cython/rules.gni
@@ -2,34 +2,37 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-template("python_binary_module_sources") {
+template("python_binary_source_set") {
# Only available on linux for now.
assert(is_linux)
- assert(defined(invoker.sources))
+ assert(defined(invoker.cython_sources) || defined(invoker.sources))
- cython_root = "//third_party/cython"
- cython_script = "$cython_root/src/cython.py"
- cython_output = "${target_out_dir}/${target_name}.cc"
-
- generator_target_name = target_name + "_cython_compiler"
config_name = target_name + "_python_config"
target_visibility = [ ":$target_name" ]
- action(generator_target_name) {
- visibility = target_visibility
- script = cython_script
- sources = invoker.sources
- outputs = [
- cython_output,
- ]
- args = [
- "--cplus",
- "-I",
- rebase_path("//", root_build_dir),
- "-o",
- rebase_path(cython_output, root_build_dir),
- ] + rebase_path(sources, root_build_dir)
+ if (defined(invoker.cython_sources)) {
+ generator_target_name = target_name + "_cython_compiler"
+
+ cython_root = "//third_party/cython"
+ cython_script = "$cython_root/src/cython.py"
+ cython_output = "${target_out_dir}/${target_name}.cc"
+
+ action(generator_target_name) {
+ visibility = target_visibility
+ script = cython_script
+ sources = invoker.cython_sources
+ outputs = [
+ cython_output,
+ ]
+ args = [
+ "--cplus",
+ "-I",
+ rebase_path("//", root_build_dir),
+ "-o",
+ rebase_path(cython_output, root_build_dir),
+ ] + rebase_path(sources, root_build_dir)
+ }
}
config(config_name) {
@@ -45,35 +48,40 @@
}
source_set(target_name) {
- deps = [
- ":$generator_target_name",
- ]
if (defined(invoker.visibility)) {
visibility = invoker.visibility
}
+ sources = []
+ if (defined(invoker.cython_sources)) {
+ sources += [ cython_output ]
+ }
+ if (defined(invoker.sources)) {
+ sources += invoker.sources
+ }
+ if (defined(invoker.configs)) {
+ configs += invoker.configs
+ }
+ all_dependent_configs = [ ":$config_name" ]
+ deps = []
+ if (defined(invoker.cython_sources)) {
+ deps += [ ":$generator_target_name" ]
+ }
if (defined(invoker.deps)) {
deps += invoker.deps
}
if (defined(invoker.datadeps)) {
datadeps = invoker.datadeps
}
- sources = [
- cython_output,
- ]
- if (defined(invoker.additional_sources)) {
- sources += invoker.additional_sources
- }
- if (defined(invoker.configs)) {
- configs += invoker.configs
- }
- all_dependent_configs = [ ":$config_name" ]
}
}
template("python_binary_module") {
# Only available on linux for now.
assert(is_linux)
- assert(defined(invoker.sources))
+
+ has_sources = defined(invoker.cython_sources) || defined(invoker.sources)
+
+ assert(has_sources || defined(invoker.deps))
assert(defined(invoker.python_base_module))
sources_target_name = target_name + "_cython_sources"
@@ -91,31 +99,42 @@
":$target_name",
]
- python_binary_module_sources(sources_target_name) {
- visibility = target_visibility
- sources = invoker.sources
- if (defined(invoker.configs)) {
- configs = invoker.configs
+ if (has_sources) {
+ python_binary_source_set(sources_target_name) {
+ visibility = target_visibility
+ if (defined(invoker.cython_sources)) {
+ cython_sources = invoker.cython_sources
+ }
+ if (defined(invoker.sources)) {
+ sources = invoker.sources
+ }
+ if (defined(invoker.configs)) {
+ configs = invoker.configs
+ }
+ if (defined(invoker.deps)) {
+ deps = invoker.deps
+ }
+ if (defined(invoker.datadeps)) {
+ datadeps = invoker.datadeps
+ }
}
}
shared_library(shared_library_name) {
visibility = target_visibility
- deps = [
- ":$sources_target_name",
- ]
+ if (defined(invoker.configs)) {
+ configs += invoker.configs
+ }
+ deps = []
+ if (has_sources) {
+ deps += [ ":$sources_target_name" ]
+ }
if (defined(invoker.deps)) {
deps += invoker.deps
}
if (defined(invoker.datadeps)) {
datadeps = invoker.datadeps
}
- if (defined(invoker.additional_sources)) {
- sources = invoker.additional_sources
- }
- if (defined(invoker.configs)) {
- configs += invoker.configs
- }
}
copy(target_name) {
diff --git a/third_party/mesa/mesa.gyp b/third_party/mesa/mesa.gyp
index 056eb40..3db0d4c 100644
--- a/third_party/mesa/mesa.gyp
+++ b/third_party/mesa/mesa.gyp
@@ -132,6 +132,7 @@
'variables': {
'clang_warning_flags': [
'-Wno-tautological-constant-out-of-range-compare',
+ '-Wno-mismatched-tags', # Fixed upstream.
],
'clang_warning_flags_unset': [
# Don't warn about string->bool used in asserts.
@@ -269,6 +270,8 @@
'variables': {
'clang_warning_flags': [
'-Wno-tautological-constant-out-of-range-compare',
+ '-Wno-absolute-value', # Fires on st_atom_array.c, might be a bug
+ '-Wno-mismatched-tags', # Fixed upstream.
],
'clang_warning_flags_unset': [
# Don't warn about string->bool used in asserts.
diff --git a/tools/clang/blink_gc_plugin/CMakeLists.txt b/tools/clang/blink_gc_plugin/CMakeLists.txt
index 85ce4a9..c511edf 100644
--- a/tools/clang/blink_gc_plugin/CMakeLists.txt
+++ b/tools/clang/blink_gc_plugin/CMakeLists.txt
@@ -1,6 +1,6 @@
# This line is read by update.sh and other scripts in tools/clang/scripts
# Note: The spaces are significant.
-set(LIBRARYNAME BlinkGCPlugin_12)
+set(LIBRARYNAME BlinkGCPlugin_14)
add_llvm_loadable_module("lib${LIBRARYNAME}"
BlinkGCPlugin.cpp
diff --git a/tools/clang/plugins/tests/overridden_methods.txt b/tools/clang/plugins/tests/overridden_methods.txt
index 199876b..3ee0333 100644
--- a/tools/clang/plugins/tests/overridden_methods.txt
+++ b/tools/clang/plugins/tests/overridden_methods.txt
@@ -11,14 +11,14 @@
virtual void SomeConstMethod() const {}
^
override
-./overridden_methods.h:58:53: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+./overridden_methods.h:58:55: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
virtual void SomeMethodWithExceptionSpec() throw() {}
- ^
- override
-./overridden_methods.h:61:67: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+ ^
+ override
+./overridden_methods.h:61:69: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
virtual void SomeConstMethodWithExceptionSpec() const throw(int) {}
- ^
- override
+ ^
+ override
./overridden_methods.h:63:39: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
virtual void SomeNonPureBaseMethod() {}
^
@@ -43,14 +43,14 @@
virtual void SomeConstMethod() const {}
^
override
-overridden_methods.cpp:34:53: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+overridden_methods.cpp:34:55: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
virtual void SomeMethodWithExceptionSpec() throw() {}
- ^
- override
-overridden_methods.cpp:37:67: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+ ^
+ override
+overridden_methods.cpp:37:69: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
virtual void SomeConstMethodWithExceptionSpec() const throw(int) {}
- ^
- override
+ ^
+ override
overridden_methods.cpp:39:39: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
virtual void SomeNonPureBaseMethod() {}
^
diff --git a/tools/clang/plugins/tests/test.sh b/tools/clang/plugins/tests/test.sh
index 9f63f7a..63aa872 100755
--- a/tools/clang/plugins/tests/test.sh
+++ b/tools/clang/plugins/tests/test.sh
@@ -34,6 +34,7 @@
fi
local output="$("${CLANG_PATH}" -fsyntax-only -Wno-c++11-extensions \
+ -Wno-inconsistent-missing-override \
-Xclang -load -Xclang "${PLUGIN_PATH}" \
-Xclang -add-plugin -Xclang find-bad-constructs ${flags} ${1} 2>&1)"
local diffout="$(echo "${output}" | diff - "${2}")"
diff --git a/tools/clang/scripts/package.sh b/tools/clang/scripts/package.sh
index f00abb4..e0c0fcc 100755
--- a/tools/clang/scripts/package.sh
+++ b/tools/clang/scripts/package.sh
@@ -87,7 +87,7 @@
${extra_flags} 2>&1 | tee -a buildlog.txt
R=$("${LLVM_BIN_DIR}/clang" --version | \
- sed -ne 's/clang version .*(\([0-9]*\))/\1/p')
+ sed -ne 's/clang version .*(trunk \([0-9]*\))/\1/p')
PDIR=clang-$R
rm -rf $PDIR
diff --git a/tools/clang/scripts/repackage.sh b/tools/clang/scripts/repackage.sh
index c92447a..e19ab7e 100755
--- a/tools/clang/scripts/repackage.sh
+++ b/tools/clang/scripts/repackage.sh
@@ -30,7 +30,7 @@
"$THIS_DIR"/package.sh $@
R=$("${LLVM_BIN_DIR}/clang" --version | \
- sed -ne 's/clang version .*(\([0-9]*\))/\1/p')
+ sed -ne 's/clang version .*(trunk \([0-9]*\))/\1/p')
PDIR=clang-$R
if [ ! -f "$PDIR.tgz" ]; then
diff --git a/tools/clang/scripts/update.sh b/tools/clang/scripts/update.sh
index ad534ad..b585440 100755
--- a/tools/clang/scripts/update.sh
+++ b/tools/clang/scripts/update.sh
@@ -8,7 +8,7 @@
# Do NOT CHANGE this if you don't know what you're doing -- see
# https://code.google.com/p/chromium/wiki/UpdatingClang
# Reverting problematic clang rolls is safe, though.
-CLANG_REVISION=218707
+CLANG_REVISION=223109
THIS_DIR="$(dirname "${0}")"
LLVM_DIR="${THIS_DIR}/../../../third_party/llvm"
@@ -238,8 +238,15 @@
"${LLVM_DIR}/test/DebugInfo/gmlt.ll" \
"${LLVM_DIR}/lib/CodeGen/SpillPlacement.cpp" \
"${LLVM_DIR}/lib/CodeGen/SpillPlacement.h" \
+ "${LLVM_DIR}/lib/Transforms/Instrumentation/MemorySanitizer.cpp" \
+ "${CLANG_DIR}/test/Driver/env.c" \
+ "${CLANG_DIR}/lib/Frontend/InitPreprocessor.cpp" \
+ "${CLANG_DIR}/test/Frontend/exceptions.c" \
+ "${CLANG_DIR}/test/Preprocessor/predefined-exceptions.m" \
+ "${LLVM_DIR}/test/Bindings/Go/go.test" \
; do
if [[ -e "${i}" ]]; then
+ rm -f "${i}" # For unversioned files.
svn revert "${i}"
fi;
done
@@ -317,179 +324,143 @@
patch -p0
popd
-# Apply r218742: test: XFAIL the non-darwin gmlt test on darwin
-# Back-ported becase the test was renamed.
+# Apply r223211: "Revert r222997."
pushd "${LLVM_DIR}"
cat << 'EOF' |
---- a/test/DebugInfo/gmlt.ll
-+++ b/test/DebugInfo/gmlt.ll
-@@ -1,2 +1,5 @@
- ; REQUIRES: object-emission
- ; RUN: %llc_dwarf -O0 -filetype=obj < %S/Inputs/gmlt.ll | llvm-dwarfdump - | FileCheck %S/Inputs/gmlt.ll
-+
-+; There's a darwin specific test in X86/gmlt, so it's okay to XFAIL this here.
-+; XFAIL: darwin
+--- a/lib/Transforms/Instrumentation/MemorySanitizer.cpp
++++ b/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+@@ -921,8 +921,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
+ Value *OriginPtr =
+ getOriginPtrForArgument(&FArg, EntryIRB, ArgOffset);
+ setOrigin(A, EntryIRB.CreateLoad(OriginPtr));
+- } else {
+- setOrigin(A, getCleanOrigin());
+ }
+ }
+ ArgOffset += RoundUpToAlignment(Size, kShadowTLSAlignment);
+@@ -942,13 +940,15 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
+ /// \brief Get the origin for a value.
+ Value *getOrigin(Value *V) {
+ if (!MS.TrackOrigins) return nullptr;
+- if (!PropagateShadow) return getCleanOrigin();
+- if (isa<Constant>(V)) return getCleanOrigin();
+- assert((isa<Instruction>(V) || isa<Argument>(V)) &&
+- "Unexpected value type in getOrigin()");
+- Value *Origin = OriginMap[V];
+- assert(Origin && "Missing origin");
+- return Origin;
++ if (isa<Instruction>(V) || isa<Argument>(V)) {
++ Value *Origin = OriginMap[V];
++ if (!Origin) {
++ DEBUG(dbgs() << "NO ORIGIN: " << *V << "\n");
++ Origin = getCleanOrigin();
++ }
++ return Origin;
++ }
++ return getCleanOrigin();
+ }
+
+ /// \brief Get the origin for i-th argument of the instruction I.
+@@ -1088,7 +1088,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
+ IRB.CreateStore(getCleanShadow(&I), ShadowPtr);
+
+ setShadow(&I, getCleanShadow(&I));
+- setOrigin(&I, getCleanOrigin());
+ }
+
+ void visitAtomicRMWInst(AtomicRMWInst &I) {
EOF
patch -p1
popd
-# Apply r218921; fixes spill placement compile-time regression.
-pushd "${LLVM_DIR}"
+# Apply r223219: "Preserve LD_LIBRARY_PATH when using the 'env' command"
+pushd "${CLANG_DIR}"
cat << 'EOF' |
---- a/lib/CodeGen/SpillPlacement.cpp
-+++ b/lib/CodeGen/SpillPlacement.cpp
-@@ -61,27 +61,6 @@ void SpillPlacement::getAnalysisUsage(AnalysisUsage &AU) const {
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-
--namespace {
--static ManagedStatic<BlockFrequency> Threshold;
--}
--
--/// Decision threshold. A node gets the output value 0 if the weighted sum of
--/// its inputs falls in the open interval (-Threshold;Threshold).
--static BlockFrequency getThreshold() { return *Threshold; }
--
--/// \brief Set the threshold for a given entry frequency.
--///
--/// Set the threshold relative to \c Entry. Since the threshold is used as a
--/// bound on the open interval (-Threshold;Threshold), 1 is the minimum
--/// threshold.
--static void setThreshold(const BlockFrequency &Entry) {
-- // Apparently 2 is a good threshold when Entry==2^14, but we need to scale
-- // it. Divide by 2^13, rounding as appropriate.
-- uint64_t Freq = Entry.getFrequency();
-- uint64_t Scaled = (Freq >> 13) + bool(Freq & (1 << 12));
-- *Threshold = std::max(UINT64_C(1), Scaled);
--}
--
- /// Node - Each edge bundle corresponds to a Hopfield node.
- ///
- /// The node contains precomputed frequency data that only depends on the CFG,
-@@ -127,9 +106,9 @@ struct SpillPlacement::Node {
-
- /// clear - Reset per-query data, but preserve frequencies that only depend on
- // the CFG.
-- void clear() {
-+ void clear(const BlockFrequency &Threshold) {
- BiasN = BiasP = Value = 0;
-- SumLinkWeights = getThreshold();
-+ SumLinkWeights = Threshold;
- Links.clear();
- }
-
-@@ -167,7 +146,7 @@ struct SpillPlacement::Node {
-
- /// update - Recompute Value from Bias and Links. Return true when node
- /// preference changes.
-- bool update(const Node nodes[]) {
-+ bool update(const Node nodes[], const BlockFrequency &Threshold) {
- // Compute the weighted sum of inputs.
- BlockFrequency SumN = BiasN;
- BlockFrequency SumP = BiasP;
-@@ -187,9 +166,9 @@ struct SpillPlacement::Node {
- // 2. It helps tame rounding errors when the links nominally sum to 0.
- //
- bool Before = preferReg();
-- if (SumN >= SumP + getThreshold())
-+ if (SumN >= SumP + Threshold)
- Value = -1;
-- else if (SumP >= SumN + getThreshold())
-+ else if (SumP >= SumN + Threshold)
- Value = 1;
- else
- Value = 0;
-@@ -228,7 +207,7 @@ void SpillPlacement::activate(unsigned n) {
- if (ActiveNodes->test(n))
- return;
- ActiveNodes->set(n);
-- nodes[n].clear();
-+ nodes[n].clear(Threshold);
-
- // Very large bundles usually come from big switches, indirect branches,
- // landing pads, or loops with many 'continue' statements. It is difficult to
-@@ -245,6 +224,18 @@ void SpillPlacement::activate(unsigned n) {
- }
- }
-
-+/// \brief Set the threshold for a given entry frequency.
-+///
-+/// Set the threshold relative to \c Entry. Since the threshold is used as a
-+/// bound on the open interval (-Threshold;Threshold), 1 is the minimum
-+/// threshold.
-+void SpillPlacement::setThreshold(const BlockFrequency &Entry) {
-+ // Apparently 2 is a good threshold when Entry==2^14, but we need to scale
-+ // it. Divide by 2^13, rounding as appropriate.
-+ uint64_t Freq = Entry.getFrequency();
-+ uint64_t Scaled = (Freq >> 13) + bool(Freq & (1 << 12));
-+ Threshold = std::max(UINT64_C(1), Scaled);
-+}
-
- /// addConstraints - Compute node biases and weights from a set of constraints.
- /// Set a bit in NodeMask for each active node.
-@@ -311,7 +302,7 @@ bool SpillPlacement::scanActiveBundles() {
- Linked.clear();
- RecentPositive.clear();
- for (int n = ActiveNodes->find_first(); n>=0; n = ActiveNodes->find_next(n)) {
-- nodes[n].update(nodes);
-+ nodes[n].update(nodes, Threshold);
- // A node that must spill, or a node without any links is not going to
- // change its value ever again, so exclude it from iterations.
- if (nodes[n].mustSpill())
-@@ -331,7 +322,7 @@ void SpillPlacement::iterate() {
- // First update the recently positive nodes. They have likely received new
- // negative bias that will turn them off.
- while (!RecentPositive.empty())
-- nodes[RecentPositive.pop_back_val()].update(nodes);
-+ nodes[RecentPositive.pop_back_val()].update(nodes, Threshold);
-
- if (Linked.empty())
- return;
-@@ -350,7 +341,7 @@ void SpillPlacement::iterate() {
- iteration == 0 ? Linked.rbegin() : std::next(Linked.rbegin()),
- E = Linked.rend(); I != E; ++I) {
- unsigned n = *I;
-- if (nodes[n].update(nodes)) {
-+ if (nodes[n].update(nodes, Threshold)) {
- Changed = true;
- if (nodes[n].preferReg())
- RecentPositive.push_back(n);
-@@ -364,7 +355,7 @@ void SpillPlacement::iterate() {
- for (SmallVectorImpl<unsigned>::const_iterator I =
- std::next(Linked.begin()), E = Linked.end(); I != E; ++I) {
- unsigned n = *I;
-- if (nodes[n].update(nodes)) {
-+ if (nodes[n].update(nodes, Threshold)) {
- Changed = true;
- if (nodes[n].preferReg())
- RecentPositive.push_back(n);
-diff --git a/lib/CodeGen/SpillPlacement.h b/lib/CodeGen/SpillPlacement.h
-index 03cf5cd..622361e 100644
---- a/lib/CodeGen/SpillPlacement.h
-+++ b/lib/CodeGen/SpillPlacement.h
-@@ -62,6 +62,10 @@ class SpillPlacement : public MachineFunctionPass {
- // Block frequencies are computed once. Indexed by block number.
- SmallVector<BlockFrequency, 8> BlockFrequencies;
-
-+ /// Decision threshold. A node gets the output value 0 if the weighted sum of
-+ /// its inputs falls in the open interval (-Threshold;Threshold).
-+ BlockFrequency Threshold;
-+
- public:
- static char ID; // Pass identification, replacement for typeid.
-
-@@ -152,6 +156,7 @@ private:
- void releaseMemory() override;
-
- void activate(unsigned);
-+ void setThreshold(const BlockFrequency &Entry);
- };
-
- } // end namespace llvm
+--- a/test/Driver/env.c
++++ b/test/Driver/env.c
+@@ -5,12 +5,14 @@
+ // REQUIRES: shell
+ //
+ // The PATH variable is heavily used when trying to find a linker.
+-// RUN: env -i LC_ALL=C %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
++// RUN: env -i LC_ALL=C LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+ // RUN: --target=i386-unknown-linux \
+ // RUN: --sysroot=%S/Inputs/basic_linux_tree \
+ // RUN: | FileCheck --check-prefix=CHECK-LD-32 %s
+ //
+-// RUN: env -i LC_ALL=C PATH="" %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
++// RUN: env -i LC_ALL=C PATH="" LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \
++// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+ // RUN: --target=i386-unknown-linux \
+ // RUN: --sysroot=%S/Inputs/basic_linux_tree \
+ // RUN: | FileCheck --check-prefix=CHECK-LD-32 %s
EOF
patch -p1
popd
+# Revert r220714: "Frontend: Define __EXCEPTIONS if -fexceptions is passed"
+pushd "${CLANG_DIR}"
+cat << 'EOF' |
+--- a/lib/Frontend/InitPreprocessor.cpp
++++ b/lib/Frontend/InitPreprocessor.cpp
+@@ -566,7 +566,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
+ Builder.defineMacro("__BLOCKS__");
+ }
+
+- if (!LangOpts.MSVCCompat && LangOpts.Exceptions)
++ if (!LangOpts.MSVCCompat && LangOpts.CXXExceptions)
+ Builder.defineMacro("__EXCEPTIONS");
+ if (!LangOpts.MSVCCompat && LangOpts.RTTI)
+ Builder.defineMacro("__GXX_RTTI");
+diff --git a/test/Frontend/exceptions.c b/test/Frontend/exceptions.c
+index 981b5b9..4bbaaa3 100644
+--- a/test/Frontend/exceptions.c
++++ b/test/Frontend/exceptions.c
+@@ -1,9 +1,6 @@
+-// RUN: %clang_cc1 -fms-compatibility -fexceptions -fcxx-exceptions -DMS_MODE -verify %s
++// RUN: %clang_cc1 -fms-compatibility -fexceptions -fcxx-exceptions -verify %s
+ // expected-no-diagnostics
+
+-// RUN: %clang_cc1 -fms-compatibility -fexceptions -verify %s
+-// expected-no-diagnostics
+-
+-#if defined(MS_MODE) && defined(__EXCEPTIONS)
++#if defined(__EXCEPTIONS)
+ #error __EXCEPTIONS should not be defined.
+ #endif
+diff --git a/test/Preprocessor/predefined-exceptions.m b/test/Preprocessor/predefined-exceptions.m
+index 0791075..c13f429 100644
+--- a/test/Preprocessor/predefined-exceptions.m
++++ b/test/Preprocessor/predefined-exceptions.m
+@@ -1,6 +1,6 @@
+ // RUN: %clang_cc1 -x objective-c -fobjc-exceptions -fexceptions -E -dM %s | FileCheck -check-prefix=CHECK-OBJC-NOCXX %s
+ // CHECK-OBJC-NOCXX: #define OBJC_ZEROCOST_EXCEPTIONS 1
+-// CHECK-OBJC-NOCXX: #define __EXCEPTIONS 1
++// CHECK-OBJC-NOCXX-NOT: #define __EXCEPTIONS 1
+
+ // RUN: %clang_cc1 -x objective-c++ -fobjc-exceptions -fexceptions -fcxx-exceptions -E -dM %s | FileCheck -check-prefix=CHECK-OBJC-CXX %s
+ // CHECK-OBJC-CXX: #define OBJC_ZEROCOST_EXCEPTIONS 1
+EOF
+patch -p1
+popd
+
+# This Go bindings test doesn't work after the bootstrap build on Linux. (PR21552)
+pushd "${LLVM_DIR}"
+cat << 'EOF' |
+Index: test/Bindings/Go/go.test
+===================================================================
+--- test/Bindings/Go/go.test (revision 223109)
++++ test/Bindings/Go/go.test (working copy)
+@@ -1,3 +1,3 @@
+-; RUN: llvm-go test llvm.org/llvm/bindings/go/llvm
++; RUN: true
+
+ ; REQUIRES: shell
+EOF
+patch -p0
+popd
+
# Echo all commands.
set -x
diff --git a/tools/valgrind/chrome_tests.py b/tools/valgrind/chrome_tests.py
index 677cb63..e43c605 100755
--- a/tools/valgrind/chrome_tests.py
+++ b/tools/valgrind/chrome_tests.py
@@ -362,9 +362,6 @@
def TestExtensions(self):
return self.SimpleTest("extensions", "extensions_unittests")
- def TestFFmpeg(self):
- return self.SimpleTest("chrome", "ffmpeg_unittests")
-
def TestFFmpegRegressions(self):
return self.SimpleTest("chrome", "ffmpeg_regression_tests")
@@ -678,7 +675,6 @@
"display": TestDisplay, "display_unittests": TestDisplay,
"events": TestEvents, "events_unittests": TestEvents,
"extensions": TestExtensions, "extensions_unittests": TestExtensions,
- "ffmpeg": TestFFmpeg, "ffmpeg_unittests": TestFFmpeg,
"ffmpeg_regression_tests": TestFFmpegRegressions,
"gcm": TestGCM, "gcm_unit_tests": TestGCM,
"gin": TestGin, "gin_unittests": TestGin,
diff --git a/tools/valgrind/drmemory/suppressions.txt b/tools/valgrind/drmemory/suppressions.txt
index 4310d8a..4a6b5a9 100644
--- a/tools/valgrind/drmemory/suppressions.txt
+++ b/tools/valgrind/drmemory/suppressions.txt
@@ -669,3 +669,15 @@
content.dll!content::RenderFrameProxy::OnDeleteProxy
content.dll!content::RenderFrameProxy::OnMessageReceived
content.dll!content::MessageRouter::RouteMessage
+
+HANDLE LEAK
+name=http://crbug.com/441785
+system call NtCreateSection
+*!CreateFileMappingW
+*!base::SharedMemory::Create
+*!base::SharedMemory::CreateAnonymous
+*!content::ChildThread::AllocateSharedMemory
+*!content::ChildSharedBitmapManager::AllocateSharedMemoryBitmap
+*!content::ChildSharedBitmapManager::AllocateSharedBitmap
+*!cc::ResourceProvider::CreateBitmap
+*!cc::ResourceProvider::Create*Resource
diff --git a/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory_win32.txt b/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory_win32.txt
index 14cbe8b..3fd0cf4 100644
--- a/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory_win32.txt
+++ b/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory_win32.txt
@@ -17,6 +17,7 @@
RenderViewImplTest.ReloadWhileSwappedOut
RenderViewImplTest.SendSwapOutACK
RenderViewImplTest.StaleNavigationsIgnored
+RenderFrameHostManagerTest.RestoreFileAccessForHistoryNavigation
ResourceFetcherTests.ResourceFetcher404
ResourceFetcherTests.ResourceFetcherDidFail
ResourceFetcherTests.ResourceFetcherDownload
diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt
index 3f1ea1b..ad58793 100644
--- a/tools/valgrind/memcheck/suppressions.txt
+++ b/tools/valgrind/memcheck/suppressions.txt
@@ -3533,3 +3533,11 @@
...
fun:_ZN3gpu22InProcessCommandBuffer21InitializeOnGpuThreadERKNS0_27InitializeOnGpuThreadParamsE
}
+{
+ bug_441333
+ Memcheck:Uninitialized
+ fun:av_packet_unpack_dictionary
+ fun:add_metadata_from_side_data
+ fun:avcodec_decode_*
+ fun:avcodec_decode_*
+}
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index 58297e6..7fd7fe9 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -108,7 +108,7 @@
draw_on_compositing_end_(false),
swap_state_(SWAP_NONE),
layer_animator_collection_(this),
- schedule_draw_factory_(this) {
+ weak_ptr_factory_(this) {
root_web_layer_ = cc::Layer::Create();
CommandLine* command_line = CommandLine::ForCurrentProcess();
@@ -210,10 +210,27 @@
defer_draw_scheduling_ = true;
task_runner_->PostTask(
FROM_HERE,
- base::Bind(&Compositor::Draw, schedule_draw_factory_.GetWeakPtr()));
+ base::Bind(&Compositor::Draw, weak_ptr_factory_.GetWeakPtr()));
}
}
+void Compositor::DidInitializeOutputSurface() {
+ num_failed_recreate_attempts_ = 0;
+}
+
+void Compositor::DidFailToInitializeOutputSurface() {
+ num_failed_recreate_attempts_++;
+
+ // Tolerate a certain number of recreation failures to work around races
+ // in the output-surface-lost machinery.
+ if (num_failed_recreate_attempts_ >= MAX_OUTPUT_SURFACE_RETRIES)
+ LOG(FATAL) << "Failed to create a fallback OutputSurface.";
+
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(&Compositor::RequestNewOutputSurface,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
void Compositor::SetRootLayer(Layer* root_layer) {
if (root_layer_ == root_layer)
return;
@@ -367,9 +384,11 @@
disable_schedule_composite_ = false;
}
-void Compositor::RequestNewOutputSurface(bool fallback) {
- host_->SetOutputSurface(
- context_factory_->CreateOutputSurface(this, fallback));
+void Compositor::RequestNewOutputSurface() {
+ bool fallback =
+ num_failed_recreate_attempts_ >= OUTPUT_SURFACE_RETRIES_BEFORE_FALLBACK;
+ context_factory_->CreateOutputSurface(weak_ptr_factory_.GetWeakPtr().get(),
+ fallback);
}
void Compositor::DidCommit() {
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index a937886..d679551 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -73,7 +73,7 @@
Compositor* compositor, bool software_fallback) = 0;
// Creates a reflector that copies the content of the |mirrored_compositor|
- // onto |mirroing_layer|.
+ // onto |mirroring_layer|.
virtual scoped_refptr<Reflector> CreateReflector(
Compositor* mirrored_compositor,
Layer* mirroring_layer) = 0;
@@ -249,8 +249,9 @@
void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
float page_scale,
float top_controls_delta) override {}
- void RequestNewOutputSurface(bool fallback) override;
- void DidInitializeOutputSurface() override {}
+ void RequestNewOutputSurface() override;
+ void DidInitializeOutputSurface() override;
+ void DidFailToInitializeOutputSurface() override;
void WillCommit() override {}
void DidCommit() override;
void DidCommitAndDrawFrame() override;
@@ -286,6 +287,10 @@
friend class base::RefCounted<Compositor>;
friend class CompositorLock;
+ enum {
+ OUTPUT_SURFACE_RETRIES_BEFORE_FALLBACK = 4,
+ MAX_OUTPUT_SURFACE_RETRIES = 5,
+ };
// Called by CompositorLock.
void UnlockCompositor();
@@ -323,6 +328,8 @@
int last_started_frame_;
int last_ended_frame_;
+ int num_failed_recreate_attempts_;
+
bool disable_schedule_composite_;
CompositorLock* compositor_lock_;
@@ -338,7 +345,7 @@
LayerAnimatorCollection layer_animator_collection_;
- base::WeakPtrFactory<Compositor> schedule_draw_factory_;
+ base::WeakPtrFactory<Compositor> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(Compositor);
};
diff --git a/ui/gl/gl_context.cc b/ui/gl/gl_context.cc
index e358069..4cfcf73 100644
--- a/ui/gl/gl_context.cc
+++ b/ui/gl/gl_context.cc
@@ -52,7 +52,10 @@
return flag_.IsSet();
}
-GLContext::GLContext(GLShareGroup* share_group) : share_group_(share_group) {
+GLContext::GLContext(GLShareGroup* share_group) :
+ share_group_(share_group),
+ swap_interval_(1),
+ force_swap_interval_zero_(false) {
if (!share_group_.get())
share_group_ = new GLShareGroup;
@@ -178,6 +181,16 @@
state_restorer_ = make_scoped_ptr(state_restorer);
}
+void GLContext::SetSwapInterval(int interval) {
+ swap_interval_ = interval;
+ OnSetSwapInterval(force_swap_interval_zero_ ? 0 : swap_interval_);
+}
+
+void GLContext::ForceSwapIntervalZero(bool force) {
+ force_swap_interval_zero_ = force;
+ OnSetSwapInterval(force_swap_interval_zero_ ? 0 : swap_interval_);
+}
+
bool GLContext::WasAllocatedUsingRobustnessExtension() {
return false;
}
diff --git a/ui/gl/gl_context.h b/ui/gl/gl_context.h
index cdebd68..62cabcd 100644
--- a/ui/gl/gl_context.h
+++ b/ui/gl/gl_context.h
@@ -76,7 +76,11 @@
void SetGLStateRestorer(GLStateRestorer* state_restorer);
// Set swap interval. This context must be current.
- virtual void SetSwapInterval(int interval) = 0;
+ void SetSwapInterval(int interval);
+
+ // Forces the swap interval to zero (no vsync) regardless of any future values
+ // passed to SetSwapInterval.
+ void ForceSwapIntervalZero(bool force);
// Returns space separated list of extensions. The context must be current.
virtual std::string GetExtensions();
@@ -169,6 +173,8 @@
// Returns the last real (non-virtual) GLContext made current.
static GLContext* GetRealCurrent();
+ virtual void OnSetSwapInterval(int interval) = 0;
+
private:
friend class base::RefCounted<GLContext>;
@@ -182,6 +188,9 @@
std::vector<scoped_refptr<FlushEvent> > flush_events_;
+ int swap_interval_;
+ bool force_swap_interval_zero_;
+
DISALLOW_COPY_AND_ASSIGN(GLContext);
};
diff --git a/ui/gl/gl_context_android.cc b/ui/gl/gl_context_android.cc
index 7f9cf2d..76b9238 100644
--- a/ui/gl/gl_context_android.cc
+++ b/ui/gl/gl_context_android.cc
@@ -33,7 +33,7 @@
virtual void ReleaseCurrent(GLSurface* surface) override {}
virtual bool IsCurrent(GLSurface* surface) override { return true; }
virtual void* GetHandle() override { return NULL; }
- virtual void SetSwapInterval(int interval) override {}
+ virtual void OnSetSwapInterval(int interval) override {}
virtual std::string GetExtensions() override;
protected:
diff --git a/ui/gl/gl_context_cgl.cc b/ui/gl/gl_context_cgl.cc
index 277780a..723e97e 100644
--- a/ui/gl/gl_context_cgl.cc
+++ b/ui/gl/gl_context_cgl.cc
@@ -238,7 +238,7 @@
return context_;
}
-void GLContextCGL::SetSwapInterval(int interval) {
+void GLContextCGL::OnSetSwapInterval(int interval) {
DCHECK(IsCurrent(NULL));
}
diff --git a/ui/gl/gl_context_cgl.h b/ui/gl/gl_context_cgl.h
index 456ea08..88813b3 100644
--- a/ui/gl/gl_context_cgl.h
+++ b/ui/gl/gl_context_cgl.h
@@ -26,7 +26,7 @@
void ReleaseCurrent(GLSurface* surface) override;
bool IsCurrent(GLSurface* surface) override;
void* GetHandle() override;
- void SetSwapInterval(int interval) override;
+ void OnSetSwapInterval(int interval) override;
bool GetTotalGpuMemory(size_t* bytes) override;
void SetSafeToForceGpuSwitch() override;
bool ForceGpuSwitchIfNeeded() override;
diff --git a/ui/gl/gl_context_egl.cc b/ui/gl/gl_context_egl.cc
index 733ad8d..5dd1aaf 100644
--- a/ui/gl/gl_context_egl.cc
+++ b/ui/gl/gl_context_egl.cc
@@ -172,7 +172,7 @@
return context_;
}
-void GLContextEGL::SetSwapInterval(int interval) {
+void GLContextEGL::OnSetSwapInterval(int interval) {
DCHECK(IsCurrent(NULL) && GLSurface::GetCurrent());
// This is a surfaceless context. eglSwapInterval doesn't take any effect in
diff --git a/ui/gl/gl_context_egl.h b/ui/gl/gl_context_egl.h
index 9f071e2..99a4481 100644
--- a/ui/gl/gl_context_egl.h
+++ b/ui/gl/gl_context_egl.h
@@ -31,7 +31,7 @@
void ReleaseCurrent(GLSurface* surface) override;
bool IsCurrent(GLSurface* surface) override;
void* GetHandle() override;
- void SetSwapInterval(int interval) override;
+ void OnSetSwapInterval(int interval) override;
std::string GetExtensions() override;
bool WasAllocatedUsingRobustnessExtension() override;
bool GetTotalGpuMemory(size_t* bytes) override;
diff --git a/ui/gl/gl_context_glx.cc b/ui/gl/gl_context_glx.cc
index 9b6cfb4..a16daf3 100644
--- a/ui/gl/gl_context_glx.cc
+++ b/ui/gl/gl_context_glx.cc
@@ -163,7 +163,7 @@
return context_;
}
-void GLContextGLX::SetSwapInterval(int interval) {
+void GLContextGLX::OnSetSwapInterval(int interval) {
DCHECK(IsCurrent(NULL));
if (HasExtension("GLX_EXT_swap_control") &&
g_driver_glx.fn.glXSwapIntervalEXTFn) {
diff --git a/ui/gl/gl_context_glx.h b/ui/gl/gl_context_glx.h
index fe3d754..6973542 100644
--- a/ui/gl/gl_context_glx.h
+++ b/ui/gl/gl_context_glx.h
@@ -31,7 +31,7 @@
void ReleaseCurrent(GLSurface* surface) override;
bool IsCurrent(GLSurface* surface) override;
void* GetHandle() override;
- void SetSwapInterval(int interval) override;
+ void OnSetSwapInterval(int interval) override;
std::string GetExtensions() override;
bool GetTotalGpuMemory(size_t* bytes) override;
bool WasAllocatedUsingRobustnessExtension() override;
diff --git a/ui/gl/gl_context_osmesa.cc b/ui/gl/gl_context_osmesa.cc
index 524fe42..d41a493 100644
--- a/ui/gl/gl_context_osmesa.cc
+++ b/ui/gl/gl_context_osmesa.cc
@@ -123,7 +123,7 @@
return context_;
}
-void GLContextOSMesa::SetSwapInterval(int interval) {
+void GLContextOSMesa::OnSetSwapInterval(int interval) {
DCHECK(IsCurrent(NULL));
}
diff --git a/ui/gl/gl_context_osmesa.h b/ui/gl/gl_context_osmesa.h
index 0ae32db..9ce37d7 100644
--- a/ui/gl/gl_context_osmesa.h
+++ b/ui/gl/gl_context_osmesa.h
@@ -29,7 +29,7 @@
void ReleaseCurrent(GLSurface* surface) override;
bool IsCurrent(GLSurface* surface) override;
void* GetHandle() override;
- void SetSwapInterval(int interval) override;
+ void OnSetSwapInterval(int interval) override;
protected:
~GLContextOSMesa() override;
diff --git a/ui/gl/gl_context_stub.cc b/ui/gl/gl_context_stub.cc
index faf957b..ff3a85d 100644
--- a/ui/gl/gl_context_stub.cc
+++ b/ui/gl/gl_context_stub.cc
@@ -33,7 +33,7 @@
return NULL;
}
-void GLContextStub::SetSwapInterval(int interval) {
+void GLContextStub::OnSetSwapInterval(int interval) {
}
std::string GLContextStub::GetExtensions() {
diff --git a/ui/gl/gl_context_stub.h b/ui/gl/gl_context_stub.h
index 1a7eb24..b4eef93 100644
--- a/ui/gl/gl_context_stub.h
+++ b/ui/gl/gl_context_stub.h
@@ -22,7 +22,7 @@
void ReleaseCurrent(GLSurface* surface) override;
bool IsCurrent(GLSurface* surface) override;
void* GetHandle() override;
- void SetSwapInterval(int interval) override;
+ void OnSetSwapInterval(int interval) override;
std::string GetExtensions() override;
std::string GetGLRenderer() override;
diff --git a/ui/gl/gl_context_wgl.cc b/ui/gl/gl_context_wgl.cc
index abe47e4..2f34cd3 100644
--- a/ui/gl/gl_context_wgl.cc
+++ b/ui/gl/gl_context_wgl.cc
@@ -131,7 +131,7 @@
return context_;
}
-void GLContextWGL::SetSwapInterval(int interval) {
+void GLContextWGL::OnSetSwapInterval(int interval) {
DCHECK(IsCurrent(NULL));
if (gfx::g_driver_wgl.ext.b_WGL_EXT_swap_control) {
wglSwapIntervalEXT(interval);
diff --git a/ui/gl/gl_context_wgl.h b/ui/gl/gl_context_wgl.h
index 13a274b..d97e568 100644
--- a/ui/gl/gl_context_wgl.h
+++ b/ui/gl/gl_context_wgl.h
@@ -28,7 +28,7 @@
virtual void ReleaseCurrent(GLSurface* surface);
virtual bool IsCurrent(GLSurface* surface);
virtual void* GetHandle();
- virtual void SetSwapInterval(int interval);
+ virtual void OnSetSwapInterval(int interval);
virtual std::string GetExtensions();
private:
diff --git a/ui/gl/gl_surface.cc b/ui/gl/gl_surface.cc
index 00e224d..1d5598e 100644
--- a/ui/gl/gl_surface.cc
+++ b/ui/gl/gl_surface.cc
@@ -200,6 +200,9 @@
return true;
}
+void GLSurface::NotifyWasBound() {
+}
+
bool GLSurface::SetBackbufferAllocation(bool allocated) {
return true;
}
diff --git a/ui/gl/gl_surface.h b/ui/gl/gl_surface.h
index 1351638..c218267 100644
--- a/ui/gl/gl_surface.h
+++ b/ui/gl/gl_surface.h
@@ -88,6 +88,10 @@
// on error.
virtual bool OnMakeCurrent(GLContext* context);
+ // Called when the surface is bound as the current framebuffer for the
+ // current context.
+ virtual void NotifyWasBound();
+
// Used for explicit buffer management.
virtual bool SetBackbufferAllocation(bool allocated);
virtual void SetFrontbufferAllocation(bool allocated);
diff --git a/ui/gl/gl_switches.cc b/ui/gl/gl_switches.cc
index 936daf6..479ff69 100644
--- a/ui/gl/gl_switches.cc
+++ b/ui/gl/gl_switches.cc
@@ -58,10 +58,6 @@
// On Windows only: use the WARP software rasterizer in the GPU process.
const char kUseWarp[] = "use-warp";
-// Include ANGLE's intermediate representation (AST) output in shader
-// compilation info logs.
-const char kGLShaderIntermOutput[] = "gl-shader-interm-output";
-
// Disables GL drawing operations which produce pixel output. With this
// the GL output will not be correct but tests will run faster.
const char kDisableGLDrawingForTests[] = "disable-gl-drawing-for-tests";
@@ -82,7 +78,6 @@
kDisableGLDrawingForTests,
kOverrideUseGLWithOSMesaForTests,
kUseWarp,
- kGLShaderIntermOutput
};
const int kGLSwitchesCopiedFromGpuProcessHostNumSwitches =
arraysize(kGLSwitchesCopiedFromGpuProcessHost);
diff --git a/ui/gl/gl_switches.h b/ui/gl/gl_switches.h
index 115ee36..ce27df0 100644
--- a/ui/gl/gl_switches.h
+++ b/ui/gl/gl_switches.h
@@ -37,8 +37,6 @@
GL_EXPORT extern const char kUseGpuInTests[];
GL_EXPORT extern const char kUseWarp[];
-GL_EXPORT extern const char kGLShaderIntermOutput[];
-
// These flags are used by the test harness code, not passed in by users.
GL_EXPORT extern const char kDisableGLDrawingForTests[];
GL_EXPORT extern const char kOverrideUseGLWithOSMesaForTests[];