diff --git a/DEPS b/DEPS index 1011036..985ea54 100644 --- a/DEPS +++ b/DEPS
@@ -39,11 +39,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '7ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103', + 'skia_revision': '5931922997b8904b1243240120014c016064b9fa', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '88d3129d9b98d5cfb94655d622f6505291d87cb4', + 'v8_revision': 'fcdcfb5615f8af96516156abe920e0dcbf64b565', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other.
diff --git a/cc/output/shader.cc b/cc/output/shader.cc index f356c7c8..de1ddd4 100644 --- a/cc/output/shader.cc +++ b/cc/output/shader.cc
@@ -2105,15 +2105,8 @@ unsigned program, int* base_uniform_index) { static const char* uniforms[] = { - "y_texture", - "u_texture", - "v_texture", - "a_texture", - "alpha", - "cc_matrix", - "yuv_adj", - "ya_clamp_rect", - "uv_clamp_rect", + "y_texture", "u_texture", "v_texture", "a_texture", "alpha", + "yuv_matrix", "yuv_adj", "ya_clamp_rect", "uv_clamp_rect", }; int locations[arraysize(uniforms)];
diff --git a/chrome/VERSION b/chrome/VERSION index 3246460..00b5e795 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=49 MINOR=0 -BUILD=2572 +BUILD=2573 PATCH=0
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 0b99f9b..189065b 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -7664.0.0 \ No newline at end of file +7666.0.0 \ No newline at end of file
diff --git a/components/scheduler/base/real_time_domain.cc b/components/scheduler/base/real_time_domain.cc index 8a57a041..c3b4505 100644 --- a/components/scheduler/base/real_time_domain.cc +++ b/components/scheduler/base/real_time_domain.cc
@@ -10,29 +10,59 @@ namespace scheduler { -RealTimeDomain::RealTimeDomain( - TaskQueueManagerDelegate* task_queue_manager_delegate, - base::Closure do_work_closure) - : task_queue_manager_delegate_(task_queue_manager_delegate), - do_work_closure_(do_work_closure) { - DCHECK(task_queue_manager_delegate_); -} +RealTimeDomain::RealTimeDomain() : weak_factory_(this) {} RealTimeDomain::~RealTimeDomain() {} +void RealTimeDomain::OnRegisterWithTaskQueueManager( + TaskQueueManagerDelegate* task_queue_manager_delegate, + base::Closure do_work_closure) { + task_queue_manager_delegate_ = task_queue_manager_delegate; + do_work_closure_ = do_work_closure; + DCHECK(task_queue_manager_delegate_); +} + LazyNow RealTimeDomain::CreateLazyNow() { + DCHECK(task_queue_manager_delegate_); return LazyNow(task_queue_manager_delegate_); } -void RealTimeDomain::RequestWakeup(base::TimeDelta delay) { - task_queue_manager_delegate_->PostDelayedTask(FROM_HERE, do_work_closure_, - delay); +void RealTimeDomain::RequestWakeup(LazyNow* lazy_now, base::TimeDelta delay) { + PostWrappedDoWork(lazy_now->Now(), lazy_now->Now() + delay); } bool RealTimeDomain::MaybeAdvanceTime() { + base::TimeTicks next_run_time; + if (!NextScheduledRunTime(&next_run_time)) + return false; + + DCHECK(task_queue_manager_delegate_); + base::TimeTicks now = task_queue_manager_delegate_->NowTicks(); + if (now >= next_run_time) + return true; + + PostWrappedDoWork(now, next_run_time); return false; } +void RealTimeDomain::PostWrappedDoWork(base::TimeTicks now, + base::TimeTicks run_time) { + DCHECK_GE(run_time, now); + DCHECK(task_queue_manager_delegate_); + if (pending_wakeups_.insert(run_time).second) { + task_queue_manager_delegate_->PostDelayedTask( + FROM_HERE, + base::Bind(&RealTimeDomain::WrappedDoWorkTask, + weak_factory_.GetWeakPtr(), run_time), + run_time - now); + } +} + +void RealTimeDomain::WrappedDoWorkTask(base::TimeTicks run_time) { + pending_wakeups_.erase(run_time); + do_work_closure_.Run(); +} + void RealTimeDomain::AsValueIntoInternal( base::trace_event::TracedValue* state) const {}
diff --git a/components/scheduler/base/real_time_domain.h b/components/scheduler/base/real_time_domain.h index f4f9ba8..f382fad 100644 --- a/components/scheduler/base/real_time_domain.h +++ b/components/scheduler/base/real_time_domain.h
@@ -5,7 +5,8 @@ #ifndef COMPONENTS_SCHEDULER_BASE_REAL_TIME_DOMAIN_H_ #define COMPONENTS_SCHEDULER_BASE_REAL_TIME_DOMAIN_H_ -#include "base/callback.h" +#include <set> + #include "base/macros.h" #include "components/scheduler/base/time_domain.h" #include "components/scheduler/scheduler_export.h" @@ -15,8 +16,7 @@ class SCHEDULER_EXPORT RealTimeDomain : public TimeDomain { public: - RealTimeDomain(TaskQueueManagerDelegate* task_queue_manager_delegate, - base::Closure do_work_closure); + RealTimeDomain(); // TimeDomain implementation: LazyNow CreateLazyNow() override; @@ -24,13 +24,21 @@ const char* GetName() const override; protected: - void RequestWakeup(base::TimeDelta delay) override; + void OnRegisterWithTaskQueueManager( + TaskQueueManagerDelegate* task_queue_manager_delegate, + base::Closure do_work_closure) override; + void RequestWakeup(LazyNow* lazy_now, base::TimeDelta delay) override; void AsValueIntoInternal( base::trace_event::TracedValue* state) const override; private: + void PostWrappedDoWork(base::TimeTicks now, base::TimeTicks run_time); + void WrappedDoWorkTask(base::TimeTicks run_time); + TaskQueueManagerDelegate* task_queue_manager_delegate_; // NOT OWNED + std::set<base::TimeTicks> pending_wakeups_; base::Closure do_work_closure_; + base::WeakPtrFactory<RealTimeDomain> weak_factory_; ~RealTimeDomain() override;
diff --git a/components/scheduler/base/task_queue_impl.cc b/components/scheduler/base/task_queue_impl.cc index a09e84d..0ad965b 100644 --- a/components/scheduler/base/task_queue_impl.cc +++ b/components/scheduler/base/task_queue_impl.cc
@@ -325,10 +325,6 @@ return; if (any_thread().incoming_queue.empty()) any_thread().time_domain->RegisterAsUpdatableTaskQueue(this); - if (any_thread().pump_policy == PumpPolicy::AUTO && - any_thread().incoming_queue.empty()) { - any_thread().task_queue_manager->MaybePostDoWorkOnMainRunner(); - } // TODO(alexclarke): consider std::move() when allowed. any_thread().incoming_queue.push(pending_task); any_thread().incoming_queue.back().set_enqueue_order(
diff --git a/components/scheduler/base/task_queue_manager.cc b/components/scheduler/base/task_queue_manager.cc index 4a3602e..b9df8756 100644 --- a/components/scheduler/base/task_queue_manager.cc +++ b/components/scheduler/base/task_queue_manager.cc
@@ -43,8 +43,8 @@ do_work_closure_ = base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), false); - real_time_domain_ = - make_scoped_refptr(new RealTimeDomain(delegate.get(), do_work_closure_)); + // TODO(alexclarke): Change this to be a parameter that's passed in. + real_time_domain_ = make_scoped_refptr(new RealTimeDomain()); RegisterTimeDomain(real_time_domain_); } @@ -61,6 +61,8 @@ void TaskQueueManager::RegisterTimeDomain( const scoped_refptr<TimeDomain>& time_domain) { time_domains_.insert(time_domain); + time_domain->OnRegisterWithTaskQueueManager(delegate_.get(), + do_work_closure_); } void TaskQueueManager::UnregisterTimeDomain(
diff --git a/components/scheduler/base/task_queue_manager_unittest.cc b/components/scheduler/base/task_queue_manager_unittest.cc index d5ad8e5..251ac56 100644 --- a/components/scheduler/base/task_queue_manager_unittest.cc +++ b/components/scheduler/base/task_queue_manager_unittest.cc
@@ -1458,4 +1458,28 @@ manager_->UnregisterTimeDomain(domain_b); } +namespace { +void ChromiumRunloopInspectionTask( + scoped_refptr<cc::OrderedSimpleTaskRunner> test_task_runner) { + EXPECT_EQ(1u, test_task_runner->NumPendingTasks()); +} +} // namespace + +TEST_F(TaskQueueManagerTest, NumberOfPendingTasksOnChromiumRunLoop) { + Initialize(1u); + + // NOTE because tasks posted to the chromiumrun loop are not cancellable, we + // will end up with a lot more tasks posted if the delayed tasks were posted + // in the reverse order. + // TODO(alexclarke): Consider talking to the message pump directly. + test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); + for (int i = 1; i < 100; i++) { + runners_[0]->PostDelayedTask( + FROM_HERE, + base::Bind(&ChromiumRunloopInspectionTask, test_task_runner_), + base::TimeDelta::FromMilliseconds(i)); + } + test_task_runner_->RunUntilIdle(); +} + } // namespace scheduler
diff --git a/components/scheduler/base/time_domain.cc b/components/scheduler/base/time_domain.cc index 825812e..2abfb52 100644 --- a/components/scheduler/base/time_domain.cc +++ b/components/scheduler/base/time_domain.cc
@@ -12,7 +12,7 @@ namespace scheduler { -TimeDomain::TimeDomain() : weak_factory_(this) {} +TimeDomain::TimeDomain() {} TimeDomain::~TimeDomain() {} @@ -31,7 +31,7 @@ } } - // |newly_updatable_| might contain |task_queue|, we use + // |newly_updatable_| might contain |queue|, we use // MoveNewlyUpdatableQueuesIntoUpdatableQueueSet to flush it out. MoveNewlyUpdatableQueuesIntoUpdatableQueueSet(); updatable_queue_set_.erase(queue); @@ -66,12 +66,12 @@ base::TimeTicks delayed_run_time, LazyNow* lazy_now) { DCHECK(main_thread_checker_.CalledOnValidThread()); - // Dedupe wakeups. - if (delayed_wakeup_multimap_.find(delayed_run_time) == - delayed_wakeup_multimap_.end()) { + + if (delayed_wakeup_multimap_.empty() || + delayed_run_time < delayed_wakeup_multimap_.begin()->first) { base::TimeDelta delay = std::max(base::TimeDelta(), delayed_run_time - lazy_now->Now()); - RequestWakeup(delay); + RequestWakeup(lazy_now, delay); } delayed_wakeup_multimap_.insert(std::make_pair(delayed_run_time, queue)); }
diff --git a/components/scheduler/base/time_domain.h b/components/scheduler/base/time_domain.h index b01f05d9..476a68e 100644 --- a/components/scheduler/base/time_domain.h +++ b/components/scheduler/base/time_domain.h
@@ -7,6 +7,7 @@ #include <map> +#include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" @@ -20,6 +21,7 @@ class TaskQueueImpl; } // internal class TaskQueueManager; +class TaskQueueManagerDelegate; class SCHEDULER_EXPORT TimeDomain : public base::RefCounted<TimeDomain> { public: @@ -79,9 +81,14 @@ void UpdateWorkQueues(bool should_trigger_wakeup, const internal::TaskQueueImpl::Task* previous_task); + // Called by the TaskQueueManager when the TimeDomain is registered. + virtual void OnRegisterWithTaskQueueManager( + TaskQueueManagerDelegate* task_queue_manager_delegate, + base::Closure do_work_closure) = 0; + // The implementaion will secedule task processing to run with |delay| with // respect to the TimeDomain's time source. - virtual void RequestWakeup(base::TimeDelta delay) = 0; + virtual void RequestWakeup(LazyNow* lazy_now, base::TimeDelta delay) = 0; // For implementation specific tracing. virtual void AsValueIntoInternal( @@ -109,7 +116,6 @@ std::set<internal::TaskQueueImpl*> updatable_queue_set_; base::ThreadChecker main_thread_checker_; - base::WeakPtrFactory<TimeDomain> weak_factory_; DISALLOW_COPY_AND_ASSIGN(TimeDomain); };
diff --git a/components/scheduler/base/time_domain_unittest.cc b/components/scheduler/base/time_domain_unittest.cc index 75e5459..d41305a 100644 --- a/components/scheduler/base/time_domain_unittest.cc +++ b/components/scheduler/base/time_domain_unittest.cc
@@ -13,6 +13,7 @@ #include "testing/gmock/include/gmock/gmock.h" using testing::_; +using testing::Mock; namespace scheduler { @@ -34,10 +35,12 @@ base::trace_event::TracedValue* state) const override {} bool MaybeAdvanceTime() override { return false; } - const char* GetName() const override { return "Test"; } + void OnRegisterWithTaskQueueManager( + TaskQueueManagerDelegate* task_queue_manager_delegate, + base::Closure do_work_closure) override {} - MOCK_METHOD1(RequestWakeup, void(base::TimeDelta delay)); + MOCK_METHOD2(RequestWakeup, void(LazyNow* lazy_now, base::TimeDelta delay)); void SetNow(base::TimeTicks now) { now_ = now; } @@ -67,7 +70,7 @@ TEST_F(TimeDomainTest, ScheduleDelayedWork) { base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); base::TimeTicks delayed_runtime = time_domain_->Now() + delay; - EXPECT_CALL(*time_domain_.get(), RequestWakeup(delay)); + EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay)); LazyNow lazy_now = time_domain_->CreateLazyNow(); time_domain_->ScheduleDelayedWork(task_queue_.get(), time_domain_->Now() + delay, &lazy_now); @@ -81,13 +84,41 @@ EXPECT_EQ(task_queue_.get(), next_task_queue); } +TEST_F(TimeDomainTest, RequestWakeup_OnlyCalledForEarlierTasks) { + base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); + base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(20); + base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(30); + base::TimeDelta delay4 = base::TimeDelta::FromMilliseconds(1); + + // RequestWakeup should always be called if there are no other wakeups. + EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay1)); + LazyNow lazy_now = time_domain_->CreateLazyNow(); + time_domain_->ScheduleDelayedWork(task_queue_.get(), + time_domain_->Now() + delay1, &lazy_now); + + Mock::VerifyAndClearExpectations(time_domain_.get()); + + // RequestWakeup should not be called when scheduling later tasks. + EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(0); + time_domain_->ScheduleDelayedWork(task_queue_.get(), + time_domain_->Now() + delay2, &lazy_now); + time_domain_->ScheduleDelayedWork(task_queue_.get(), + time_domain_->Now() + delay3, &lazy_now); + + // RequestWakeup should be called when scheduling earlier tasks. + Mock::VerifyAndClearExpectations(time_domain_.get()); + EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay4)); + time_domain_->ScheduleDelayedWork(task_queue_.get(), + time_domain_->Now() + delay4, &lazy_now); +} + TEST_F(TimeDomainTest, UnregisterQueue) { scoped_refptr<internal::TaskQueueImpl> task_queue2_ = make_scoped_refptr(new internal::TaskQueueImpl( nullptr, time_domain_, TaskQueue::Spec("test_queue2"), "test.category", "test.category")); - EXPECT_CALL(*time_domain_.get(), RequestWakeup(_)).Times(2); + EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(1); LazyNow lazy_now = time_domain_->CreateLazyNow(); time_domain_->ScheduleDelayedWork( task_queue_.get(), @@ -132,7 +163,7 @@ // MoveReadyDelayedTasksToIncomingQueue as expected. base::TimeDelta delay = base::TimeDelta::FromMilliseconds(50); base::TimeTicks delayed_runtime = time_domain_->Now() + delay; - EXPECT_CALL(*time_domain_.get(), RequestWakeup(delay)); + EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay)); LazyNow lazy_now = time_domain_->CreateLazyNow(); time_domain_->ScheduleDelayedWork(dummy_queue.get(), delayed_runtime, &lazy_now);
diff --git a/components/scheduler/base/virtual_time_domain.cc b/components/scheduler/base/virtual_time_domain.cc index fdd997c..3251039 100644 --- a/components/scheduler/base/virtual_time_domain.cc +++ b/components/scheduler/base/virtual_time_domain.cc
@@ -15,13 +15,22 @@ VirtualTimeDomain::~VirtualTimeDomain() {} +void VirtualTimeDomain::OnRegisterWithTaskQueueManager( + TaskQueueManagerDelegate* task_queue_manager_delegate, + base::Closure do_work_closure) { + task_queue_manager_delegate_ = task_queue_manager_delegate; + do_work_closure_ = do_work_closure; + DCHECK(task_queue_manager_delegate_); +} + LazyNow VirtualTimeDomain::CreateLazyNow() { base::AutoLock lock(lock_); return LazyNow(now_); } -void VirtualTimeDomain::RequestWakeup(base::TimeDelta delay) { - // We don't need to do anything here because AdvanceTo triggers delayed tasks. +void VirtualTimeDomain::RequestWakeup(LazyNow* lazy_now, + base::TimeDelta delay) { + // We don't need to do anything here because AdvanceTo posts a DoWork. } bool VirtualTimeDomain::MaybeAdvanceTime() { @@ -35,8 +44,7 @@ base::AutoLock lock(lock_); DCHECK_GE(now, now_); now_ = now; - LazyNow lazy_now(now_); - WakeupReadyDelayedQueues(&lazy_now); + task_queue_manager_delegate_->PostTask(FROM_HERE, do_work_closure_); } const char* VirtualTimeDomain::GetName() const {
diff --git a/components/scheduler/base/virtual_time_domain.h b/components/scheduler/base/virtual_time_domain.h index 2e38414..ce1f99a 100644 --- a/components/scheduler/base/virtual_time_domain.h +++ b/components/scheduler/base/virtual_time_domain.h
@@ -27,7 +27,10 @@ void AdvanceTo(base::TimeTicks now); protected: - void RequestWakeup(base::TimeDelta delay) override; + void OnRegisterWithTaskQueueManager( + TaskQueueManagerDelegate* task_queue_manager_delegate, + base::Closure do_work_closure) override; + void RequestWakeup(LazyNow* lazy_now, base::TimeDelta delay) override; void AsValueIntoInternal( base::trace_event::TracedValue* state) const override; @@ -35,6 +38,9 @@ mutable base::Lock lock_; // Protects |now_|. base::TimeTicks now_; + TaskQueueManagerDelegate* task_queue_manager_delegate_; // NOT OWNED + base::Closure do_work_closure_; + ~VirtualTimeDomain() override; DISALLOW_COPY_AND_ASSIGN(VirtualTimeDomain);
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_bind_uniform_location.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_bind_uniform_location.txt index ef4e662..eb2f272 100644 --- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_bind_uniform_location.txt +++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_bind_uniform_location.txt
@@ -104,7 +104,8 @@ to a program object. Hence it is allowed to bind any name (except a name starting with "gl_") to an index, including a name that is never used as a uniform in any shader object. Assigned bindings for uniform variables - that do not exist or are not active are ignored. + that do not exist or are not active are ignored. Using such bindings + behaves as if passed location was -1. It is possible for an application to bind more than one uniform name to the same location. This is referred to as aliasing. This will only work @@ -126,4 +127,7 @@ 7/20/2012 Documented the extension 9/8/2015 Require program link to fail if two statically used uniforms are bound to the same location. + 11/6/2015 Require inactive and non-existing, bound uniform locations + to behave like location -1. +
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 7f13556..4b870d3 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -603,16 +603,6 @@ 'GL_RENDERBUFFER', ], }, - 'InvalidateFrameBufferTarget': { - 'type': 'GLenum', - 'valid': [ - 'GL_FRAMEBUFFER', - ], - 'invalid': [ - 'GL_DRAW_FRAMEBUFFER' , - 'GL_READ_FRAMEBUFFER' , - ], - }, 'RenderBufferTarget': { 'type': 'GLenum', 'valid': [
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 0fa8726..d6cac7e 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -1472,9 +1472,9 @@ const GLenum* attachments) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInvalidateFramebuffer(" - << GLES2Util::GetStringInvalidateFrameBufferTarget(target) - << ", " << count << ", " - << static_cast<const void*>(attachments) << ")"); + << GLES2Util::GetStringFrameBufferTarget(target) << ", " + << count << ", " << static_cast<const void*>(attachments) + << ")"); GPU_CLIENT_LOG_CODE_BLOCK({ for (GLsizei i = 0; i < count; ++i) { GPU_CLIENT_LOG(" " << i << ": " << attachments[0 + i * 1]); @@ -1497,10 +1497,10 @@ GLsizei height) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInvalidateSubFramebuffer(" - << GLES2Util::GetStringInvalidateFrameBufferTarget(target) - << ", " << count << ", " - << static_cast<const void*>(attachments) << ", " << x - << ", " << y << ", " << width << ", " << height << ")"); + << GLES2Util::GetStringFrameBufferTarget(target) << ", " + << count << ", " << static_cast<const void*>(attachments) + << ", " << x << ", " << y << ", " << width << ", " + << height << ")"); GPU_CLIENT_LOG_CODE_BLOCK({ for (GLsizei i = 0; i < count; ++i) { GPU_CLIENT_LOG(" " << i << ": " << attachments[0 + i * 1]);
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index e31f1a8..0457731 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -124,8 +124,8 @@ GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenumVertexAttribute pname, GLuint* params); GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenumVertexPointer pname, void** pointer); GL_APICALL void GL_APIENTRY glHint (GLenumHintTarget target, GLenumHintMode mode); -GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenumInvalidateFrameBufferTarget target, GLsizeiNotNegative count, const GLenum* attachments); -GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenumInvalidateFrameBufferTarget target, GLsizeiNotNegative count, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenumFrameBufferTarget target, GLsizeiNotNegative count, const GLenum* attachments); +GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenumFrameBufferTarget target, GLsizeiNotNegative count, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLidBuffer buffer); GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenumCapability cap); GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLidFramebuffer framebuffer);
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h index e37d8c5d..fc26129 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
@@ -44,7 +44,6 @@ static std::string GetStringIndexedBufferTarget(uint32_t value); static std::string GetStringIndexedGLState(uint32_t value); static std::string GetStringInternalFormatParameter(uint32_t value); -static std::string GetStringInvalidateFrameBufferTarget(uint32_t value); static std::string GetStringMapBufferAccess(uint32_t value); static std::string GetStringMatrixMode(uint32_t value); static std::string GetStringPathCoordType(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 169a8bb..411d7b4 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -4007,14 +4007,6 @@ arraysize(string_table), value); } -std::string GLES2Util::GetStringInvalidateFrameBufferTarget(uint32_t value) { - static const EnumToString string_table[] = { - {GL_FRAMEBUFFER, "GL_FRAMEBUFFER"}, - }; - return GLES2Util::GetQualifiedEnumString(string_table, - arraysize(string_table), value); -} - std::string GLES2Util::GetStringMapBufferAccess(uint32_t value) { static const EnumToString string_table[] = { {GL_MAP_READ_BIT, "GL_MAP_READ_BIT"},
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 20b3fb7..c01034a 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -6814,7 +6814,8 @@ if (!CheckCurrentProgram(function_name)) { return false; } - return location != -1; + return !state_.current_program->IsInactiveUniformLocationByFakeLocation( + location); } bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc index 4901ba1..2d37097 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
@@ -475,10 +475,6 @@ .WillOnce(SetArgumentPointee<2>(0)); EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _)) .WillOnce(SetArgumentPointee<2>(0)); - EXPECT_CALL( - *gl_, - GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORM_MAX_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(0)); Program* program = GetProgram(client_program_id_); ASSERT_TRUE(program != NULL); @@ -589,10 +585,6 @@ .WillOnce(SetArgumentPointee<2>(0)); EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _)) .WillOnce(SetArgumentPointee<2>(0)); - EXPECT_CALL( - *gl_, - GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORM_MAX_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(0)); cmds::AttachShader attach_cmd; attach_cmd.Init(client_program_id_, kClientVertexShaderId);
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h index ac58e82..5194672 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
@@ -44,7 +44,6 @@ ValueValidator<GLenum> indexed_buffer_target; ValueValidator<GLenum> indexed_g_l_state; ValueValidator<GLenum> internal_format_parameter; -ValueValidator<GLenum> invalidate_frame_buffer_target; ValueValidator<GLenum> map_buffer_access; ValueValidator<GLenum> matrix_mode; ValueValidator<GLenum> path_coord_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 867e1940..981d100 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -395,10 +395,6 @@ GL_NUM_SAMPLE_COUNTS, GL_SAMPLES, }; -static const GLenum valid_invalidate_frame_buffer_target_table[] = { - GL_FRAMEBUFFER, -}; - static const GLenum valid_map_buffer_access_table[] = { GL_MAP_READ_BIT, GL_MAP_WRITE_BIT, @@ -1025,9 +1021,6 @@ internal_format_parameter( valid_internal_format_parameter_table, arraysize(valid_internal_format_parameter_table)), - invalidate_frame_buffer_target( - valid_invalidate_frame_buffer_target_table, - arraysize(valid_invalidate_frame_buffer_target_table)), map_buffer_access(valid_map_buffer_access_table, arraysize(valid_map_buffer_access_table)), matrix_mode(valid_matrix_mode_table, arraysize(valid_matrix_mode_table)),
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc index 233eb4e..dc60003 100644 --- a/gpu/command_buffer/service/program_manager.cc +++ b/gpu/command_buffer/service/program_manager.cc
@@ -119,20 +119,22 @@ Program::UniformInfo::UniformInfo() : size(0), type(GL_NONE), + accepts_api_type(0), fake_location_base(0), - is_array(false) { -} + is_array(false) {} -Program::UniformInfo::UniformInfo(GLsizei _size, +Program::UniformInfo::UniformInfo(const std::string& client_name, + int client_location_base, GLenum _type, - int _fake_location_base, - const std::string& _name) - : size(_size), + bool _is_array, + const std::vector<GLint>& service_locations) + : size(service_locations.size()), type(_type), accepts_api_type(0), - fake_location_base(_fake_location_base), - is_array(false), - name(_name) { + fake_location_base(client_location_base), + is_array(_is_array), + name(client_name), + element_locations(service_locations) { switch (type) { case GL_INT: accepts_api_type = kUniform1i; @@ -238,8 +240,13 @@ NOTREACHED() << "Unhandled UniformInfo type " << type; break; } -} + DCHECK_LT(0, size); + DCHECK(is_array || size == 1); + size_t num_texture_units = IsSampler() ? static_cast<size_t>(size) : 0u; + texture_units.clear(); + texture_units.resize(num_texture_units, 0); +} Program::UniformInfo::~UniformInfo() {} bool ProgramManager::IsInvalidPrefix(const char* name, size_t length) { @@ -258,7 +265,6 @@ valid_(false), link_status_(false), uniforms_cleared_(false), - num_uniforms_(0), transform_feedback_buffer_mode_(GL_NONE) { manager_->StartTracking(this); } @@ -266,11 +272,11 @@ void Program::Reset() { valid_ = false; link_status_ = false; - num_uniforms_ = 0; max_uniform_name_length_ = 0; max_attrib_name_length_ = 0; attrib_infos_.clear(); uniform_infos_.clear(); + uniform_locations_.clear(); fragment_input_infos_.clear(); sampler_indices_.clear(); attrib_location_to_index_map_.clear(); @@ -322,11 +328,7 @@ return; } uniforms_cleared_ = true; - for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { - const UniformInfo& uniform_info = uniform_infos_[ii]; - if (!uniform_info.IsValid()) { - continue; - } + for (const UniformInfo& uniform_info : uniform_infos_) { GLint location = uniform_info.element_locations[0]; GLsizei size = uniform_info.size; uint32 unit_size = @@ -444,22 +446,6 @@ } } -namespace { - -struct UniformData { - UniformData() : size(-1), type(GL_NONE), location(0), added(false) { - } - std::string queried_name; - std::string corrected_name; - std::string original_name; - GLsizei size; - GLenum type; - GLint location; - bool added; -}; - -} // anonymous namespace - void Program::Update() { Reset(); UpdateLogInfo(); @@ -515,88 +501,18 @@ } } #endif - - max_len = 0; - GLint num_uniforms = 0; - glGetProgramiv(service_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); - glGetProgramiv(service_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len); - DCHECK(num_uniforms <= 0 || max_len > 0); - name_buffer.reset(new char[max_len]); - - // Reads all the names. - std::vector<UniformData> uniform_data; - for (GLint ii = 0; ii < num_uniforms; ++ii) { - GLsizei length = 0; - UniformData data; - glGetActiveUniform( - service_id_, ii, max_len, &length, - &data.size, &data.type, name_buffer.get()); - DCHECK(length < max_len); - DCHECK(length == 0 || name_buffer[length] == '\0'); - data.queried_name = std::string(name_buffer.get()); - GetCorrectedUniformData(data.queried_name, &data.corrected_name, - &data.original_name, &data.size, &data.type); - uniform_data.push_back(data); - } - - // NOTE: We don't care if 2 uniforms are bound to the same location. - // One of them will take preference. The spec allows this, same as - // BindAttribLocation. - // - // The reason we don't check is if we were to fail we'd have to - // restore the previous program but since we've already linked successfully - // at this point the previous program is gone. - - // Assigns the uniforms with bindings. - size_t next_available_index = 0; - for (size_t ii = 0; ii < uniform_data.size(); ++ii) { - UniformData& data = uniform_data[ii]; - // Force builtin uniforms (gl_DepthRange) to have invalid location. - if (ProgramManager::IsInvalidPrefix(data.queried_name.c_str(), - data.queried_name.size())) { - data.location = -1; - } else { - data.location = - glGetUniformLocation(service_id_, data.queried_name.c_str()); - } - // remove "[0]" - std::string short_name; - int element_index = 0; - bool good = GetUniformNameSansElement(data.original_name, &element_index, - &short_name); - DCHECK(good); - LocationMap::const_iterator it = bind_uniform_location_map_.find( - short_name); - if (it != bind_uniform_location_map_.end()) { - AddUniformInfo( - data.size, data.type, data.location, it->second, data.corrected_name, - data.original_name, &next_available_index); - data.added = true; - } - } - - // Assigns the uniforms that were not bound. - for (size_t ii = 0; ii < uniform_data.size(); ++ii) { - const UniformData& data = uniform_data[ii]; - if (!data.added) { - AddUniformInfo( - data.size, data.type, data.location, -1, data.corrected_name, - data.original_name, &next_available_index); - } - } + UpdateUniforms(); #if !defined(NDEBUG) if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableGPUServiceLoggingGPU)) { DVLOG(1) << "----: uniforms for service_id: " << service_id(); - for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { - const UniformInfo& info = uniform_infos_[ii]; - if (info.IsValid()) { - DVLOG(1) << ii << ": loc = " << info.element_locations[0] - << ", size = " << info.size - << ", type = " << GLES2Util::GetStringEnum(info.type) - << ", name = " << info.name; - } + size_t ii = 0; + for (const UniformInfo& info : uniform_infos_) { + DVLOG(1) << ii++ << ": loc = " << info.element_locations[0] + << ", size = " << info.size + << ", type = " << GLES2Util::GetStringEnum(info.type) + << ", name = " << info.name; } } #endif @@ -606,6 +522,144 @@ valid_ = true; } +void Program::UpdateUniforms() { + // Reserve each client-bound uniform location. This way unbound uniforms will + // not be allocated to locations that user expects bound uniforms to be, even + // if the expected uniforms are optimized away by the driver. + for (const auto& binding : bind_uniform_location_map_) { + if (binding.second < 0) + continue; + size_t client_location = static_cast<size_t>(binding.second); + if (uniform_locations_.size() <= client_location) + uniform_locations_.resize(client_location + 1); + uniform_locations_[client_location].SetInactive(); + } + + GLint num_uniforms = 0; + glGetProgramiv(service_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); + if (num_uniforms <= 0) + return; + + uniform_infos_.resize(num_uniforms); + + GLint name_buffer_length = 0; + glGetProgramiv(service_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, + &name_buffer_length); + DCHECK(name_buffer_length > 0); + scoped_ptr<char[]> name_buffer(new char[name_buffer_length]); + + size_t unused_client_location_cursor = 0; + + for (GLint uniform_index = 0; uniform_index < num_uniforms; ++uniform_index) { + GLsizei name_length = 0; + GLsizei size = 0; + GLenum type = GL_NONE; + glGetActiveUniform(service_id_, uniform_index, name_buffer_length, + &name_length, &size, &type, name_buffer.get()); + DCHECK(name_length < name_buffer_length); + DCHECK(name_length == 0 || name_buffer[name_length] == '\0'); + std::string service_name(name_buffer.get(), name_length); + + GLint service_location = -1; + // Force builtin uniforms (gl_DepthRange) to have invalid location. + if (!ProgramManager::IsInvalidPrefix(service_name.c_str(), + service_name.size())) { + service_location = + glGetUniformLocation(service_id_, service_name.c_str()); + } + + // Determine the client name of the uniform and whether it is an array + // or not. + bool is_array = false; + std::string client_name; + for (size_t i = 0; i < kMaxAttachedShaders && client_name.empty(); ++i) { + const auto& shader = attached_shaders_[i]; + if (!shader) + continue; + const sh::ShaderVariable* info = nullptr; + const sh::Uniform* uniform = shader->GetUniformInfo(service_name); + if (uniform && + uniform->findInfoByMappedName(service_name, &info, &client_name)) { + DCHECK(!client_name.empty()); + is_array = info->arraySize > 0; + type = info->type; + size = std::max(1u, info->arraySize); + } + } + if (client_name.empty()) { + // This happens only in cases where we do not have ANGLE or run unit tests + // (or ANGLE has a severe bug). + client_name = service_name; + GLSLArrayName parsed_service_name(service_name); + is_array = size > 1 || parsed_service_name.IsArrayName(); + } + + std::string service_base_name = service_name; + std::string client_base_name = client_name; + if (is_array) { + // Some drivers incorrectly return an uniform name of size-1 array without + // "[0]". In this case, we correct the service name by appending "[0]" to + // it. + GLSLArrayName parsed_service_name(service_name); + if (parsed_service_name.IsArrayName()) { + service_base_name = parsed_service_name.base_name(); + GLSLArrayName parsed_client_name(client_name); + client_base_name = parsed_client_name.base_name(); + } else { + service_name += "[0]"; + client_name += "[0]"; + } + } + + // Assign a location for the uniform: use either client-bound + // location or automatically assigned to an unused location. + size_t client_location_base = 0; + LocationMap::const_iterator it = + bind_uniform_location_map_.find(client_base_name); + if (it != bind_uniform_location_map_.end()) { + client_location_base = it->second; + } else { + while (unused_client_location_cursor < uniform_locations_.size() && + !uniform_locations_[unused_client_location_cursor].IsUnused()) + unused_client_location_cursor++; + if (unused_client_location_cursor == uniform_locations_.size()) + uniform_locations_.resize(unused_client_location_cursor + 1); + client_location_base = unused_client_location_cursor; + unused_client_location_cursor++; + } + + // Populate the uniform list entry. + std::vector<GLint> service_locations; + service_locations.resize(size); + service_locations[0] = service_location; + + if (size > 1) { + for (GLsizei ii = 1; ii < size; ++ii) { + std::string element_name(service_base_name + "[" + + base::IntToString(ii) + "]"); + service_locations[ii] = + glGetUniformLocation(service_id_, element_name.c_str()); + } + } + + UniformInfo& info = uniform_infos_[uniform_index]; + info = UniformInfo(client_name, client_location_base, type, is_array, + service_locations); + if (info.IsSampler()) { + sampler_indices_.push_back(uniform_index); + } + + // Populate the uniform location list entry. + // Before linking, we already validated that no two statically used uniforms + // are bound to the same location. + DCHECK(!uniform_locations_[client_location_base].IsActive()); + uniform_locations_[client_location_base].SetActive(&info); + + max_uniform_name_length_ = std::max(max_uniform_name_length_, + static_cast<GLsizei>(info.name.size())); + } +} + void Program::UpdateFragmentInputs() { if (!feature_info().feature_flags().chromium_path_rendering) return; @@ -921,11 +975,7 @@ const std::string& name) const { GLSLArrayName parsed_name(name); - for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { - const UniformInfo& info = uniform_infos_[ii]; - if (!info.IsValid()) { - continue; - } + for (const UniformInfo& info : uniform_infos_) { if (info.name == name || (info.is_array && info.name.compare(0, info.name.size() - 3, name) == 0)) { @@ -935,7 +985,6 @@ size_t open_pos = info.name.find_last_of('['); if (info.name.compare(0, open_pos, parsed_name.base_name()) == 0) { int index = parsed_name.element_index(); - DCHECK(index >= 0); if (index < info.size) { DCHECK_GT(static_cast<int>(info.element_locations.size()), index); if (info.element_locations[index] == -1) @@ -965,25 +1014,34 @@ GLint fake_location, GLint* real_location, GLint* array_index) const { DCHECK(real_location); DCHECK(array_index); - if (fake_location < 0) { - return NULL; - } + if (fake_location < 0) + return nullptr; + size_t location_index = + GetUniformLocationIndexFromFakeLocation(fake_location); + if (location_index >= uniform_locations_.size()) + return nullptr; - GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location); - if (uniform_index >= 0 && - static_cast<size_t>(uniform_index) < uniform_infos_.size()) { - const UniformInfo& uniform_info = uniform_infos_[uniform_index]; - if (!uniform_info.IsValid()) { - return NULL; - } - GLint element_index = GetArrayElementIndexFromFakeLocation(fake_location); - if (element_index < uniform_info.size) { - *real_location = uniform_info.element_locations[element_index]; - *array_index = element_index; - return &uniform_info; - } - } - return NULL; + if (!uniform_locations_[location_index].IsActive()) + return nullptr; + + const UniformInfo* info = uniform_locations_[location_index].uniform(); + size_t element_index = GetArrayElementIndexFromFakeLocation(fake_location); + if (static_cast<GLsizei>(element_index) >= info->size) + return nullptr; + *real_location = info->element_locations[element_index]; + *array_index = element_index; + return info; +} + +bool Program::IsInactiveUniformLocationByFakeLocation( + GLint fake_location) const { + if (fake_location < 0) + return true; + size_t location_index = + GetUniformLocationIndexFromFakeLocation(fake_location); + if (location_index >= uniform_locations_.size()) + return false; + return uniform_locations_[location_index].IsInactive(); } const std::string* Program::GetAttribMappedName( @@ -1063,41 +1121,6 @@ bind_fragment_input_location_map_[name + "[0]"] = location; } -// Note: This is only valid to call right after a program has been linked -// successfully. -void Program::GetCorrectedUniformData( - const std::string& name, - std::string* corrected_name, std::string* original_name, - GLsizei* size, GLenum* type) const { - DCHECK(corrected_name && original_name && size && type); - for (auto shader : attached_shaders_) { - if (!shader) - continue; - const sh::ShaderVariable* info = NULL; - const sh::Uniform* uniform = shader->GetUniformInfo(name); - bool found = false; - if (uniform) - found = uniform->findInfoByMappedName(name, &info, original_name); - if (found) { - const std::string kArraySpec("[0]"); - if (info->arraySize > 0 && - !base::EndsWith(name, kArraySpec, base::CompareCase::SENSITIVE)) { - *corrected_name = name + kArraySpec; - *original_name += kArraySpec; - } else { - *corrected_name = name; - } - *type = info->type; - *size = std::max(1u, info->arraySize); - return; - } - } - // TODO(zmo): this path should never be reached unless there is a serious - // bug in the driver or in ANGLE translator. - *corrected_name = name; - *original_name = name; -} - void Program::GetVertexAttribData( const std::string& name, std::string* original_name, GLenum* type) const { DCHECK(original_name); @@ -1181,81 +1204,13 @@ } } -void Program::AddUniformInfo( - GLsizei size, GLenum type, GLint location, GLint fake_base_location, - const std::string& name, const std::string& original_name, - size_t* next_available_index) { - DCHECK(next_available_index); - const char* kArraySpec = "[0]"; - size_t uniform_index = - fake_base_location >= 0 ? fake_base_location : *next_available_index; - if (uniform_infos_.size() < uniform_index + 1) { - uniform_infos_.resize(uniform_index + 1); - } - - // Before linking, we already validated that no two statically used uniforms - // are bound to the same location. - DCHECK(!uniform_infos_[uniform_index].IsValid()); - - uniform_infos_[uniform_index] = UniformInfo( - size, type, uniform_index, original_name); - ++num_uniforms_; - - UniformInfo& info = uniform_infos_[uniform_index]; - info.element_locations.resize(size); - info.element_locations[0] = location; - DCHECK_LE(0, size); - size_t num_texture_units = info.IsSampler() ? static_cast<size_t>(size) : 0u; - info.texture_units.clear(); - info.texture_units.resize(num_texture_units, 0); - - if (size > 1) { - // Go through the array element locations looking for a match. - // We can skip the first element because it's the same as the - // the location without the array operators. - size_t array_pos = name.rfind(kArraySpec); - std::string base_name = name; - if (name.size() > 3) { - if (array_pos != name.size() - 3) { - info.name = name + kArraySpec; - } else { - base_name = name.substr(0, name.size() - 3); - } - } - for (GLsizei ii = 1; ii < info.size; ++ii) { - std::string element_name(base_name + "[" + base::IntToString(ii) + "]"); - info.element_locations[ii] = - glGetUniformLocation(service_id_, element_name.c_str()); - } - } - - info.is_array = - (size > 1 || - (info.name.size() > 3 && - info.name.rfind(kArraySpec) == info.name.size() - 3)); - - if (info.IsSampler()) { - sampler_indices_.push_back(info.fake_location_base); - } - max_uniform_name_length_ = - std::max(max_uniform_name_length_, - static_cast<GLsizei>(info.name.size())); - - while (*next_available_index < uniform_infos_.size() && - uniform_infos_[*next_available_index].IsValid()) { - *next_available_index = *next_available_index + 1; - } -} - const Program::UniformInfo* Program::GetUniformInfo( GLint index) const { if (static_cast<size_t>(index) >= uniform_infos_.size()) { return NULL; } - - const UniformInfo& info = uniform_infos_[index]; - return info.IsValid() ? &info : NULL; + return &uniform_infos_[index]; } bool Program::SetSamplers( @@ -1264,27 +1219,29 @@ if (fake_location < 0) { return true; } - GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location); - if (uniform_index >= 0 && - static_cast<size_t>(uniform_index) < uniform_infos_.size()) { - UniformInfo& info = uniform_infos_[uniform_index]; - if (!info.IsValid()) { - return false; - } - GLint element_index = GetArrayElementIndexFromFakeLocation(fake_location); - if (element_index < info.size) { - count = std::min(info.size - element_index, count); - if (info.IsSampler() && count > 0) { - for (GLsizei ii = 0; ii < count; ++ii) { - if (value[ii] < 0 || value[ii] >= num_texture_units) { - return false; - } - } - std::copy(value, value + count, - info.texture_units.begin() + element_index); - return true; + size_t location_index = + GetUniformLocationIndexFromFakeLocation(fake_location); + if (location_index >= uniform_infos_.size()) + return false; + + if (!uniform_locations_[location_index].IsActive()) + return false; + + UniformInfo* info = uniform_locations_[location_index].uniform(); + + size_t element_index = GetArrayElementIndexFromFakeLocation(fake_location); + if (static_cast<GLsizei>(element_index) >= info->size) + return true; + count = std::min(info->size - static_cast<GLsizei>(element_index), count); + if (info->IsSampler() && count > 0) { + for (GLsizei ii = 0; ii < count; ++ii) { + if (value[ii] < 0 || value[ii] >= num_texture_units) { + return false; } } + std::copy(value, value + count, + info->texture_units.begin() + element_index); + return true; } return true; } @@ -1299,7 +1256,7 @@ *params = max_attrib_name_length_ + 1; break; case GL_ACTIVE_UNIFORMS: - *params = num_uniforms_; + *params = uniform_infos_.size(); break; case GL_ACTIVE_UNIFORM_MAX_LENGTH: // Notice +1 to accomodate NULL terminator. @@ -1661,15 +1618,12 @@ total_string_size += info.name.size(); } - for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { - const UniformInfo& info = uniform_infos_[ii]; - if (info.IsValid()) { - num_locations += info.element_locations.size(); - total_string_size += info.name.size(); - } + for (const UniformInfo& info : uniform_infos_) { + num_locations += info.element_locations.size(); + total_string_size += info.name.size(); } - uint32 num_inputs = attrib_infos_.size() + num_uniforms_; + uint32 num_inputs = attrib_infos_.size() + uniform_infos_.size(); uint32 input_size = num_inputs * sizeof(ProgramInput); uint32 location_size = num_locations * sizeof(int32); uint32 size = sizeof(ProgramInfoHeader) + @@ -1691,7 +1645,7 @@ header->link_status = link_status_; header->num_attribs = attrib_infos_.size(); - header->num_uniforms = num_uniforms_; + header->num_uniforms = uniform_infos_.size(); for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { const VertexAttrib& info = attrib_infos_[ii]; @@ -1706,26 +1660,26 @@ ++inputs; } - for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { - const UniformInfo& info = uniform_infos_[ii]; - if (info.IsValid()) { - inputs->size = info.size; - inputs->type = info.type; - inputs->location_offset = ComputeOffset(header, locations); - inputs->name_offset = ComputeOffset(header, strings); - inputs->name_length = info.name.size(); - DCHECK(static_cast<size_t>(info.size) == info.element_locations.size()); - for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { - if (info.element_locations[jj] == -1) - *locations++ = -1; - else - *locations++ = ProgramManager::MakeFakeLocation(ii, jj); - } - memcpy(strings, info.name.c_str(), info.name.size()); - strings += info.name.size(); - ++inputs; + for (const UniformInfo& info : uniform_infos_) { + inputs->size = info.size; + inputs->type = info.type; + inputs->location_offset = ComputeOffset(header, locations); + inputs->name_offset = ComputeOffset(header, strings); + inputs->name_length = info.name.size(); + DCHECK(static_cast<size_t>(info.size) == info.element_locations.size()); + for (size_t jj = 0; jj < info.element_locations.size(); ++jj) { + if (info.element_locations[jj] == -1) + *locations++ = -1; + else + *locations++ = + ProgramManager::MakeFakeLocation(info.fake_location_base, jj); } + memcpy(strings, info.name.c_str(), info.name.size()); + strings += info.name.size(); + ++inputs; } + // NOTE: currently we do not pass inactive uniform binding locations + // through the program info call. // NOTE: currently we do not pass fragment input infos through the program // info call, because they are not exposed through any getter function.
diff --git a/gpu/command_buffer/service/program_manager.h b/gpu/command_buffer/service/program_manager.h index 737c849..daecf4d 100644 --- a/gpu/command_buffer/service/program_manager.h +++ b/gpu/command_buffer/service/program_manager.h
@@ -73,15 +73,12 @@ struct UniformInfo { UniformInfo(); - UniformInfo( - GLsizei _size, GLenum _type, GLint _fake_location_base, - const std::string& _name); + UniformInfo(const std::string& client_name, + GLint client_location_base, + GLenum _type, + bool _is_array, + const std::vector<GLint>& service_locations); ~UniformInfo(); - - bool IsValid() const { - return size != 0; - } - bool IsSampler() const { return type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB || type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES; @@ -110,7 +107,37 @@ std::string name; }; + class UniformLocationEntry { + public: + UniformLocationEntry() : uniform_(nullptr), inactive_(false) {} + bool IsUnused() const { return !uniform_ && !inactive_; } + bool IsInactive() const { return inactive_; } + bool IsActive() const { return uniform_ != nullptr; } + void SetInactive() { + uniform_ = nullptr; + inactive_ = true; + } + void SetActive(UniformInfo* uniform) { + DCHECK(uniform); + uniform_ = uniform; + inactive_ = false; + } + const UniformInfo* uniform() const { + DCHECK(IsActive()); + return uniform_; + } + UniformInfo* uniform() { + DCHECK(IsActive()); + return uniform_; + } + + private: + UniformInfo* uniform_; // Pointer to uniform_info_ vector entry. + bool inactive_; + }; + typedef std::vector<UniformInfo> UniformInfoVector; + typedef std::vector<UniformLocationEntry> UniformLocationVector; typedef std::vector<VertexAttrib> AttribInfoVector; typedef std::vector<FragmentInputInfo> FragmentInputInfoVector; typedef std::vector<int> SamplerIndices; @@ -172,6 +199,10 @@ const UniformInfo* GetUniformInfoByFakeLocation( GLint fake_location, GLint* real_location, GLint* array_index) const; + // Returns true if |fake_location| is a location for an inactive uniform, + // -1 for bound, non-existing uniform. + bool IsInactiveUniformLocationByFakeLocation(GLint fake_location) const; + // Gets all the program info. void GetProgramInfo( ProgramManager* manager, CommonDecoder::Bucket* bucket) const; @@ -333,6 +364,7 @@ // Updates the program info after a successful link. void Update(); + void UpdateUniforms(); void UpdateFragmentInputs(); // Process the program log, replacing the hashed names with original names. @@ -367,33 +399,20 @@ // Returns false upon failure. bool ExecuteTransformFeedbackVaryingsCall(); - void AddUniformInfo( - GLsizei size, GLenum type, GLint location, GLint fake_base_location, - const std::string& name, const std::string& original_name, - size_t* next_available_index); - - // Query uniform data returned by ANGLE translator by the mapped name. - // Some drivers incorrectly return an uniform name of size-1 array without - // "[0]". In this case, we correct the name by appending "[0]" to it. - void GetCorrectedUniformData( - const std::string& name, - std::string* corrected_name, std::string* original_name, - GLsizei* size, GLenum* type) const; - // Query VertexAttrib data returned by ANGLE translator by the mapped name. void GetVertexAttribData( const std::string& name, std::string* original_name, GLenum* type) const; void DetachShaders(ShaderManager* manager); - static inline GLint GetUniformInfoIndexFromFakeLocation( + static inline size_t GetUniformLocationIndexFromFakeLocation( GLint fake_location) { - return fake_location & 0xFFFF; + return static_cast<size_t>(fake_location & 0xFFFF); } - static inline GLint GetArrayElementIndexFromFakeLocation( + static inline size_t GetArrayElementIndexFromFakeLocation( GLint fake_location) { - return (fake_location >> 16) & 0xFFFF; + return static_cast<size_t>((fake_location >> 16) & 0xFFFF); } const FeatureInfo& feature_info() const; @@ -414,6 +433,7 @@ // Uniform info by index. UniformInfoVector uniform_infos_; + UniformLocationVector uniform_locations_; // The indices of the uniforms that are samplers. SamplerIndices sampler_indices_; @@ -439,10 +459,6 @@ // True if the uniforms have been cleared. bool uniforms_cleared_; - // This is different than uniform_infos_.size() because - // that is a sparce array. - GLint num_uniforms_; - // Log info scoped_ptr<std::string> log_info_;
diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc index c9beda9..2c8fc25 100644 --- a/gpu/command_buffer/service/test_helper.cc +++ b/gpu/command_buffer/service/test_helper.cc
@@ -735,53 +735,43 @@ .WillOnce(SetArgumentPointee<2>(num_uniforms)) .RetiresOnSaturation(); - size_t max_uniform_len = 0; - for (size_t ii = 0; ii < num_uniforms; ++ii) { - size_t len = strlen(uniforms[ii].name) + 1; - max_uniform_len = std::max(max_uniform_len, len); - } - EXPECT_CALL(*gl, - GetProgramiv(service_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, _)) - .WillOnce(SetArgumentPointee<2>(max_uniform_len)) - .RetiresOnSaturation(); - for (size_t ii = 0; ii < num_uniforms; ++ii) { - const UniformInfo& info = uniforms[ii]; - EXPECT_CALL(*gl, - GetActiveUniform(service_id, ii, - max_uniform_len, _, _, _, _)) - .WillOnce(DoAll( - SetArgumentPointee<3>(strlen(info.name)), - SetArgumentPointee<4>(info.size), - SetArgumentPointee<5>(info.type), - SetArrayArgument<6>(info.name, - info.name + strlen(info.name) + 1))) + if (num_uniforms > 0) { + size_t max_uniform_len = 0; + for (size_t ii = 0; ii < num_uniforms; ++ii) { + size_t len = strlen(uniforms[ii].name) + 1; + max_uniform_len = std::max(max_uniform_len, len); + } + EXPECT_CALL(*gl, GetProgramiv(service_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, _)) + .WillOnce(SetArgumentPointee<2>(max_uniform_len)) .RetiresOnSaturation(); - } - - for (int pass = 0; pass < 2; ++pass) { for (size_t ii = 0; ii < num_uniforms; ++ii) { const UniformInfo& info = uniforms[ii]; - if (pass == 0 && info.real_location != -1) { + EXPECT_CALL(*gl, + GetActiveUniform(service_id, ii, max_uniform_len, _, _, _, _)) + .WillOnce(DoAll(SetArgumentPointee<3>(strlen(info.name)), + SetArgumentPointee<4>(info.size), + SetArgumentPointee<5>(info.type), + SetArrayArgument<6>( + info.name, info.name + strlen(info.name) + 1))) + .RetiresOnSaturation(); + + if (info.real_location != -1) { EXPECT_CALL(*gl, GetUniformLocation(service_id, StrEq(info.name))) .WillOnce(Return(info.real_location)) .RetiresOnSaturation(); } - if ((pass == 0 && info.desired_location >= 0) || - (pass == 1 && info.desired_location < 0)) { - if (info.size > 1) { - std::string base_name = info.name; - size_t array_pos = base_name.rfind("[0]"); - if (base_name.size() > 3 && array_pos == base_name.size() - 3) { - base_name = base_name.substr(0, base_name.size() - 3); - } - for (GLsizei jj = 1; jj < info.size; ++jj) { - std::string element_name( - std::string(base_name) + "[" + base::IntToString(jj) + "]"); - EXPECT_CALL(*gl, GetUniformLocation( - service_id, StrEq(element_name))) - .WillOnce(Return(info.real_location + jj * 2)) - .RetiresOnSaturation(); - } + if (info.size > 1) { + std::string base_name = info.name; + size_t array_pos = base_name.rfind("[0]"); + if (base_name.size() > 3 && array_pos == base_name.size() - 3) { + base_name = base_name.substr(0, base_name.size() - 3); + } + for (GLsizei jj = 1; jj < info.size; ++jj) { + std::string element_name(std::string(base_name) + "[" + + base::IntToString(jj) + "]"); + EXPECT_CALL(*gl, GetUniformLocation(service_id, StrEq(element_name))) + .WillOnce(Return(info.real_location + jj * 2)) + .RetiresOnSaturation(); } } }
diff --git a/gpu/command_buffer/tests/gl_bind_uniform_location_unittest.cc b/gpu/command_buffer/tests/gl_bind_uniform_location_unittest.cc index d688c69..5c19cf0 100644 --- a/gpu/command_buffer/tests/gl_bind_uniform_location_unittest.cc +++ b/gpu/command_buffer/tests/gl_bind_uniform_location_unittest.cc
@@ -268,6 +268,98 @@ } +TEST_P(BindUniformLocationTest, UnusedUniformUpdate) { + ASSERT_TRUE(GLTestHelper::HasExtension("GL_CHROMIUM_bind_uniform_location")); + + // clang-format off + static const char* kVertexShaderString = SHADER( + attribute vec4 a_position; + void main() { + gl_Position = a_position; + } + ); + static const char* kFragmentShaderString = SHADER( + precision mediump float; + uniform vec4 u_colorA; + uniform float u_colorU; + uniform vec4 u_colorC; + void main() { + gl_FragColor = u_colorA + u_colorC; + } + ); + // clang-format on + const GLint kColorULocation = 1; + const GLint kNonexistingLocation = 5; + const GLint kUnboundLocation = 6; + + GLuint vertex_shader = + GLTestHelper::LoadShader(GL_VERTEX_SHADER, kVertexShaderString); + GLuint fragment_shader = + GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, kFragmentShaderString); + GLuint program = glCreateProgram(); + glBindUniformLocationCHROMIUM(program, kColorULocation, "u_colorU"); + // The non-existing uniform should behave like existing, but optimized away + // uniform. + glBindUniformLocationCHROMIUM(program, kNonexistingLocation, "nonexisting"); + // Let A and C be assigned automatic locations. + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + GLint linked = 0; + glGetProgramiv(program, GL_LINK_STATUS, &linked); + EXPECT_EQ(1, linked); + glUseProgram(program); + + // No errors on bound locations, since caller does not know + // if the driver optimizes them away or not. + glUniform1f(kColorULocation, 0.25f); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + // No errors on bound locations of names that do not exist + // in the shader. Otherwise it would be inconsistent wrt the + // optimization case. + glUniform1f(kNonexistingLocation, 0.25f); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + // The above are equal to updating -1. + glUniform1f(-1, 0.25f); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + // No errors when updating with other type either. + // The type can not be known with the non-existing case. + glUniform2f(kColorULocation, 0.25f, 0.25f); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + glUniform2f(kNonexistingLocation, 0.25f, 0.25f); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + glUniform2f(-1, 0.25f, 0.25f); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + // Ensure that driver or ANGLE has optimized the variable + // away and the test tests what it is supposed to. + EXPECT_EQ(-1, glGetUniformLocation(program, "u_colorU")); + + // The bound location gets marked as used and the driver + // does not allocate other variables to that location. + EXPECT_NE(kColorULocation, glGetUniformLocation(program, "u_colorA")); + EXPECT_NE(kColorULocation, glGetUniformLocation(program, "u_colorC")); + EXPECT_NE(kNonexistingLocation, glGetUniformLocation(program, "u_colorA")); + EXPECT_NE(kNonexistingLocation, glGetUniformLocation(program, "u_colorC")); + + // Unintuitive: while specifying value works, getting the value does not. + GLfloat get_result = 0.0f; + glGetUniformfv(program, kColorULocation, &get_result); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); + glGetUniformfv(program, kNonexistingLocation, &get_result); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); + glGetUniformfv(program, -1, &get_result); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); + + // Updating an unbound, non-existing location still causes + // an error. + glUniform1f(kUnboundLocation, 0.25f); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); +} + INSTANTIATE_TEST_CASE_P(WithAndWithoutShaderNameMapping, BindUniformLocationTest, ::testing::Bool());
diff --git a/ios/chrome/browser/application_context_impl.cc b/ios/chrome/browser/application_context_impl.cc index 3d42d10..9a6380d 100644 --- a/ios/chrome/browser/application_context_impl.cc +++ b/ios/chrome/browser/application_context_impl.cc
@@ -87,7 +87,7 @@ variations_service->OnAppEnterForeground(); std::vector<ios::ChromeBrowserState*> loaded_browser_state = - GetChromeBrowserStateManager()->GetLoadedChromeBrowserStates(); + GetChromeBrowserStateManager()->GetLoadedBrowserStates(); for (ios::ChromeBrowserState* browser_state : loaded_browser_state) { browser_state->SetExitType(ios::ChromeBrowserState::EXIT_CRASHED); } @@ -97,7 +97,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); // Mark all the ChromeBrowserStates as clean and persist history. std::vector<ios::ChromeBrowserState*> loaded_browser_state = - GetChromeBrowserStateManager()->GetLoadedChromeBrowserStates(); + GetChromeBrowserStateManager()->GetLoadedBrowserStates(); for (ios::ChromeBrowserState* browser_state : loaded_browser_state) { if (history::HistoryService* history_service = ios::HistoryServiceFactory::GetForBrowserStateIfExists(
diff --git a/ios/chrome/browser/signin/ios_chrome_signin_status_metrics_provider_delegate.cc b/ios/chrome/browser/signin/ios_chrome_signin_status_metrics_provider_delegate.cc index 4ee19343..a6c5bb0 100644 --- a/ios/chrome/browser/signin/ios_chrome_signin_status_metrics_provider_delegate.cc +++ b/ios/chrome/browser/signin/ios_chrome_signin_status_metrics_provider_delegate.cc
@@ -74,5 +74,5 @@ IOSChromeSigninStatusMetricsProviderDelegate::GetLoadedChromeBrowserStates() { return GetApplicationContext() ->GetChromeBrowserStateManager() - ->GetLoadedChromeBrowserStates(); + ->GetLoadedBrowserStates(); }
diff --git a/ios/chrome/browser/sync/glue/sync_start_util.cc b/ios/chrome/browser/sync/glue/sync_start_util.cc index 93753bf..22123a3 100644 --- a/ios/chrome/browser/sync/glue/sync_start_util.cc +++ b/ios/chrome/browser/sync/glue/sync_start_util.cc
@@ -28,7 +28,7 @@ } ios::ChromeBrowserState* browser_state = - browser_state_manager->GetChromeBrowserState(browser_state_path); + browser_state_manager->GetBrowserState(browser_state_path); if (!browser_state) { DVLOG(2) << "ChromeBrowserState not found, can't start sync."; return;
diff --git a/ios/public/provider/chrome/browser/browser_state/chrome_browser_state_manager.h b/ios/public/provider/chrome/browser/browser_state/chrome_browser_state_manager.h index 3e548da..e5c28c3 100644 --- a/ios/public/provider/chrome/browser/browser_state/chrome_browser_state_manager.h +++ b/ios/public/provider/chrome/browser/browser_state/chrome_browser_state_manager.h
@@ -32,14 +32,13 @@ // Returns the ChromeBrowserState associated with |path|, creating one if // necessary. - virtual ChromeBrowserState* GetChromeBrowserState( - const base::FilePath& path) = 0; + virtual ChromeBrowserState* GetBrowserState(const base::FilePath& path) = 0; // Returns the BrowserStateInfoCache associated with this manager. virtual BrowserStateInfoCache* GetBrowserStateInfoCache() = 0; // Returns the list of loaded ChromeBrowserStates. - virtual std::vector<ChromeBrowserState*> GetLoadedChromeBrowserStates() = 0; + virtual std::vector<ChromeBrowserState*> GetLoadedBrowserStates() = 0; protected: ChromeBrowserStateManager() {}
diff --git a/net/base/chunked_upload_data_stream.cc b/net/base/chunked_upload_data_stream.cc index 6ba40c5..52cf4856 100644 --- a/net/base/chunked_upload_data_stream.cc +++ b/net/base/chunked_upload_data_stream.cc
@@ -28,7 +28,8 @@ DCHECK(data_len > 0 || is_done); if (data_len > 0) { DCHECK(data); - upload_data_.push_back(new std::vector<char>(data, data + data_len)); + upload_data_.push_back( + make_scoped_ptr(new std::vector<char>(data, data + data_len))); } all_data_appended_ = is_done; @@ -74,7 +75,7 @@ // Copy as much data as possible from |upload_data_| to |buf|. int bytes_read = 0; while (read_index_ < upload_data_.size() && bytes_read < buf_len) { - std::vector<char>* data = upload_data_[read_index_]; + std::vector<char>* data = upload_data_[read_index_].get(); size_t bytes_to_read = std::min(static_cast<size_t>(buf_len - bytes_read), data->size() - read_offset_);
diff --git a/net/base/chunked_upload_data_stream.h b/net/base/chunked_upload_data_stream.h index b79108ca..6f7d284 100644 --- a/net/base/chunked_upload_data_stream.h +++ b/net/base/chunked_upload_data_stream.h
@@ -9,7 +9,6 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_vector.h" #include "net/base/completion_callback.h" #include "net/base/net_export.h" #include "net/base/upload_data_stream.h" @@ -48,7 +47,7 @@ // True once all data has been appended to the stream. bool all_data_appended_; - ScopedVector<std::vector<char>> upload_data_; + std::vector<scoped_ptr<std::vector<char>>> upload_data_; // Buffer to write the next read's data to. Only set when a call to // ReadInternal reads no data.
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index 2a7e469c..adb4705 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc
@@ -333,6 +333,7 @@ void HttpNetworkSession::GetNpnProtos(NextProtoVector* npn_protos) const { if (HttpStreamFactory::spdy_enabled() && params_.enable_npn) { *npn_protos = next_protos_; + DisableHTTP2(npn_protos); } else { npn_protos->clear(); }
diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index 32dd905..6f8b203 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h
@@ -116,8 +116,6 @@ FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, ResetStateForRestart); - FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, EnableNPN); - FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, DisableNPN); FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateReceived); FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index b33d9ba..54c689b 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -81,7 +81,6 @@ #include "net/ssl/ssl_private_key.h" #include "net/test/cert_test_util.h" #include "net/websockets/websocket_handshake_stream_base.h" -#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" #include "url/gurl.h" @@ -15467,29 +15466,4 @@ trans->GetTotalReceivedBytes()); } -TEST_P(HttpNetworkTransactionTest, EnableNPN) { - session_deps_.next_protos = NextProtosDefaults(); - session_deps_.enable_npn = true; - - scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - - EXPECT_THAT(trans.server_ssl_config_.alpn_protos, - testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11)); - EXPECT_THAT(trans.server_ssl_config_.npn_protos, - testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11)); -} - -TEST_P(HttpNetworkTransactionTest, DisableNPN) { - session_deps_.next_protos = NextProtosDefaults(); - session_deps_.enable_npn = false; - - scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - - EXPECT_THAT(trans.server_ssl_config_.alpn_protos, - testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11)); - EXPECT_TRUE(trans.server_ssl_config_.npn_protos.empty()); -} - } // namespace net
diff --git a/net/log/net_log_unittest.cc b/net/log/net_log_unittest.cc index 0046b46..fd2a2925 100644 --- a/net/log/net_log_unittest.cc +++ b/net/log/net_log_unittest.cc
@@ -5,7 +5,6 @@ #include "net/log/net_log.h" #include "base/bind.h" -#include "base/memory/scoped_vector.h" #include "base/synchronization/waitable_event.h" #include "base/threading/simple_thread.h" #include "base/values.h" @@ -128,17 +127,19 @@ } void OnAddEntry(const NetLog::Entry& entry) override { - base::Value* value = entry.ToValue(); - base::DictionaryValue* dict = NULL; - ASSERT_TRUE(value->GetAsDictionary(&dict)); - values_.push_back(dict); + scoped_ptr<base::DictionaryValue> dict = + base::DictionaryValue::From(make_scoped_ptr(entry.ToValue())); + ASSERT_TRUE(dict); + values_.push_back(std::move(dict)); } size_t GetNumValues() const { return values_.size(); } - base::DictionaryValue* GetValue(size_t index) const { return values_[index]; } + base::DictionaryValue* GetValue(size_t index) const { + return values_[index].get(); + } private: - ScopedVector<base::DictionaryValue> values_; + std::vector<scoped_ptr<base::DictionaryValue>> values_; }; void AddEvent(NetLog* net_log) {
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc index 6b58813..133f7b1 100644 --- a/net/socket/client_socket_pool_base_unittest.cc +++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -726,7 +726,9 @@ TestSocketRequest* request(int i) { return test_base_.request(i); } size_t requests_size() const { return test_base_.requests_size(); } - ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); } + std::vector<scoped_ptr<TestSocketRequest>>* requests() { + return test_base_.requests(); + } size_t completion_count() const { return test_base_.completion_count(); } TestNetLog net_log_;
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc index c2230d7..93fcf3d 100644 --- a/net/socket/socket_test_util.cc +++ b/net/socket/socket_test_util.cc
@@ -1785,19 +1785,18 @@ return kIndexOutOfBounds; for (size_t i = 0; i < request_order_.size(); i++) - if (requests_[index] == request_order_[i]) + if (requests_[index].get() == request_order_[i]) return i + 1; return kRequestNotFound; } bool ClientSocketPoolTest::ReleaseOneConnection(KeepAlive keep_alive) { - ScopedVector<TestSocketRequest>::iterator i; - for (i = requests_.begin(); i != requests_.end(); ++i) { - if ((*i)->handle()->is_initialized()) { + for (scoped_ptr<TestSocketRequest>& it : requests_) { + if (it->handle()->is_initialized()) { if (keep_alive == NO_KEEP_ALIVE) - (*i)->handle()->socket()->Disconnect(); - (*i)->handle()->Reset(); + it->handle()->socket()->Disconnect(); + it->handle()->Reset(); base::RunLoop().RunUntilIdle(); return true; } @@ -1902,16 +1901,15 @@ client_socket_factory_->CreateTransportClientSocket( AddressList(), net_log.net_log(), NetLog::Source()); MockConnectJob* job = new MockConnectJob(socket.Pass(), handle, callback); - job_list_.push_back(job); + job_list_.push_back(make_scoped_ptr(job)); handle->set_pool_id(1); return job->Connect(); } void MockTransportClientSocketPool::CancelRequest(const std::string& group_name, ClientSocketHandle* handle) { - std::vector<MockConnectJob*>::iterator i; - for (i = job_list_.begin(); i != job_list_.end(); ++i) { - if ((*i)->CancelHandle(handle)) { + for (scoped_ptr<MockConnectJob>& it : job_list_) { + if (it->CancelHandle(handle)) { cancel_count_++; break; }
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h index 92089b1..430b5225 100644 --- a/net/socket/socket_test_util.h +++ b/net/socket/socket_test_util.h
@@ -1029,9 +1029,9 @@ RequestPriority priority, const scoped_refptr<typename PoolType::SocketParams>& socket_params) { DCHECK(socket_pool); - TestSocketRequest* request = - new TestSocketRequest(&request_order_, &completion_count_); - requests_.push_back(request); + TestSocketRequest* request( + new TestSocketRequest(&request_order_, &completion_count_)); + requests_.push_back(make_scoped_ptr(request)); int rv = request->handle()->Init(group_name, socket_params, priority, @@ -1058,14 +1058,14 @@ // Note that this uses 0-based indices, while GetOrderOfRequest takes and // returns 0-based indices. - TestSocketRequest* request(int i) { return requests_[i]; } + TestSocketRequest* request(int i) { return requests_[i].get(); } size_t requests_size() const { return requests_.size(); } - ScopedVector<TestSocketRequest>* requests() { return &requests_; } + std::vector<scoped_ptr<TestSocketRequest>>* requests() { return &requests_; } size_t completion_count() const { return completion_count_; } private: - ScopedVector<TestSocketRequest> requests_; + std::vector<scoped_ptr<TestSocketRequest>> requests_; std::vector<TestSocketRequest*> request_order_; size_t completion_count_; @@ -1133,7 +1133,7 @@ private: ClientSocketFactory* client_socket_factory_; - ScopedVector<MockConnectJob> job_list_; + std::vector<scoped_ptr<MockConnectJob>> job_list_; RequestPriority last_request_priority_; int release_count_; int cancel_count_;
diff --git a/net/socket/socks_client_socket_pool_unittest.cc b/net/socket/socks_client_socket_pool_unittest.cc index e841c83..587f1fa 100644 --- a/net/socket/socks_client_socket_pool_unittest.cc +++ b/net/socket/socks_client_socket_pool_unittest.cc
@@ -109,7 +109,9 @@ return test_base_.GetOrderOfRequest(index); } - ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); } + std::vector<scoped_ptr<TestSocketRequest>>* requests() { + return test_base_.requests(); + } MockClientSocketFactory transport_client_socket_factory_; MockTransportClientSocketPool transport_socket_pool_;
diff --git a/net/socket/transport_client_socket_pool_unittest.cc b/net/socket/transport_client_socket_pool_unittest.cc index 1a00d46..5224e4ca 100644 --- a/net/socket/transport_client_socket_pool_unittest.cc +++ b/net/socket/transport_client_socket_pool_unittest.cc
@@ -86,7 +86,9 @@ test_base_.ReleaseAllConnections(keep_alive); } - ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); } + std::vector<scoped_ptr<TestSocketRequest>>* requests() { + return test_base_.requests(); + } size_t completion_count() const { return test_base_.completion_count(); } bool connect_backup_jobs_enabled_;
diff --git a/net/socket/websocket_transport_client_socket_pool_unittest.cc b/net/socket/websocket_transport_client_socket_pool_unittest.cc index 477fdb3..96aa84a9 100644 --- a/net/socket/websocket_transport_client_socket_pool_unittest.cc +++ b/net/socket/websocket_transport_client_socket_pool_unittest.cc
@@ -102,7 +102,9 @@ TestSocketRequest* request(int i) { return test_base_.request(i); } - ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); } + std::vector<scoped_ptr<TestSocketRequest>>* requests() { + return test_base_.requests(); + } size_t completion_count() const { return test_base_.completion_count(); } TestNetLog net_log_;
diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc index 637f6dbc..551ad6d 100644 --- a/net/spdy/spdy_stream.cc +++ b/net/spdy/spdy_stream.cc
@@ -178,8 +178,8 @@ while (!pending_recv_data_.empty()) { // Take ownership of the first element of |pending_recv_data_|. - scoped_ptr<SpdyBuffer> buffer(pending_recv_data_.front()); - pending_recv_data_.weak_erase(pending_recv_data_.begin()); + scoped_ptr<SpdyBuffer> buffer = std::move(pending_recv_data_.at(0)); + pending_recv_data_.erase(pending_recv_data_.begin()); bool eof = (buffer == NULL); @@ -484,7 +484,7 @@ // It should be valid for this to happen in the server push case. // We'll return received data when delegate gets attached to the stream. if (buffer) { - pending_recv_data_.push_back(buffer.Pass()); + pending_recv_data_.push_back(std::move(buffer)); } else { pending_recv_data_.push_back(NULL); // Note: we leave the stream open in the session until the stream
diff --git a/net/spdy/spdy_stream.h b/net/spdy/spdy_stream.h index 011363ab..faf06e3 100644 --- a/net/spdy/spdy_stream.h +++ b/net/spdy/spdy_stream.h
@@ -14,7 +14,6 @@ #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "net/base/io_buffer.h" #include "net/base/net_export.h" @@ -547,7 +546,7 @@ // after the data is fully read. Specifically, data received before the // delegate is attached must be buffered and later replayed. A remote FIN // is represented by a final, zero-length buffer. - ScopedVector<SpdyBuffer> pending_recv_data_; + std::vector<scoped_ptr<SpdyBuffer>> pending_recv_data_; // The time at which the request was made that resulted in this response. // For cached responses, this time could be "far" in the past.
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc index b1fcbee..27b8117 100644 --- a/net/spdy/spdy_test_util_common.cc +++ b/net/spdy/spdy_test_util_common.cc
@@ -383,7 +383,6 @@ enable_compression(false), enable_ping(false), enable_user_alternate_protocol_ports(false), - enable_npn(true), protocol(protocol), session_max_recv_window_size( SpdySession::GetDefaultInitialWindowSize(protocol)), @@ -442,7 +441,6 @@ params.enable_spdy_ping_based_connection_checking = session_deps->enable_ping; params.enable_user_alternate_protocol_ports = session_deps->enable_user_alternate_protocol_ports; - params.enable_npn = session_deps->enable_npn; params.spdy_default_protocol = session_deps->protocol; params.spdy_session_max_recv_window_size = session_deps->session_max_recv_window_size;
diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h index 5316e31..33c8b33 100644 --- a/net/spdy/spdy_test_util_common.h +++ b/net/spdy/spdy_test_util_common.h
@@ -197,7 +197,6 @@ bool enable_compression; bool enable_ping; bool enable_user_alternate_protocol_ports; - bool enable_npn; NextProto protocol; size_t session_max_recv_window_size; size_t stream_max_recv_window_size;
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flex-property-parsing-expected.txt b/third_party/WebKit/LayoutTests/css3/flexbox/flex-property-parsing-expected.txt index b314b212..3f93757 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/flex-property-parsing-expected.txt +++ b/third_party/WebKit/LayoutTests/css3/flexbox/flex-property-parsing-expected.txt
@@ -69,6 +69,10 @@ PASS getComputedStyle(flexitem).flex is "1.75 2 3px" PASS flexitem.style.flex is "1 2 3px" PASS getComputedStyle(flexitem).flex is "1 2 3px" +PASS flexitem.style.flex is "4 3 calc(20px + 40%)" +PASS getComputedStyle(flexitem).flex is "4 3 calc(20px + 40%)" +PASS flexitem.style.flex is "1 2 calc(10px + 50%)" +PASS getComputedStyle(flexitem).flex is "1 2 calc(10px + 50%)" PASS flexitem.style.flex is "0 0 auto" PASS getComputedStyle(flexitem).flex is "0 0 auto" PASS flexitem.style.flex is "0 1 auto"
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flex-property-parsing.html b/third_party/WebKit/LayoutTests/css3/flexbox/flex-property-parsing.html index ddf5fca..3ddb4c78 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/flex-property-parsing.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/flex-property-parsing.html
@@ -149,6 +149,14 @@ shouldBeEqualToString('flexitem.style.flex', '1 2 3px'); shouldBeEqualToString('getComputedStyle(flexitem).flex', '1 2 3px'); +flexitem.style.flex = 'calc(20px + 40%) 4 3'; +shouldBeEqualToString('flexitem.style.flex', '4 3 calc(20px + 40%)'); +shouldBeEqualToString('getComputedStyle(flexitem).flex', '4 3 calc(20px + 40%)'); + +flexitem.style.flex = '1 2 calc(10px + 50%)'; +shouldBeEqualToString('flexitem.style.flex', '1 2 calc(10px + 50%)'); +shouldBeEqualToString('getComputedStyle(flexitem).flex', '1 2 calc(10px + 50%)'); + flexitem.style.flex = 'auto 0 0'; shouldBeEqualToString('flexitem.style.flex', '0 0 auto'); shouldBeEqualToString('getComputedStyle(flexitem).flex', '0 0 auto');
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/RTCIceCandidate-expected.txt b/third_party/WebKit/LayoutTests/fast/mediastream/RTCIceCandidate-expected.txt index d078f79..24a3e3a 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/RTCIceCandidate-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/mediastream/RTCIceCandidate-expected.txt
@@ -20,6 +20,8 @@ PASS candidate.candidate is "bar" PASS candidate.sdpMid is "foo" PASS candidate.sdpMLineIndex is 0 +PASS candidate.candidate is "null" +PASS candidate.sdpMid is "null" PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/RTCIceCandidate.html b/third_party/WebKit/LayoutTests/fast/mediastream/RTCIceCandidate.html index 235f670..be05c73 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/RTCIceCandidate.html +++ b/third_party/WebKit/LayoutTests/fast/mediastream/RTCIceCandidate.html
@@ -38,6 +38,10 @@ shouldBeEqualToString('candidate.sdpMid', 'foo'); shouldBe('candidate.sdpMLineIndex', '0'); +candidate.candidate = null; +candidate.sdpMid = null; +shouldBeEqualToString('candidate.candidate', 'null'); +shouldBeEqualToString('candidate.sdpMid', 'null'); window.successfullyParsed = true; </script>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/nested-one-line-in-inner-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/nested-one-line-in-inner-expected.txt new file mode 100644 index 0000000..b41178a --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/nested-one-line-in-inner-expected.txt
@@ -0,0 +1,5 @@ +Test that an inner multicol with only one line makes the outer multicol tall enough to contain it. + +There should be a blue square below. + + PASS
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/nested-one-line-in-inner.html b/third_party/WebKit/LayoutTests/fast/multicol/nested-one-line-in-inner.html new file mode 100644 index 0000000..498fc19 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/nested-one-line-in-inner.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<script src="../../resources/check-layout.js"></script> +<p>Test that an inner multicol with only one line makes the outer multicol tall enough to contain it.</p> +<p>There should be a blue square below.</p> +<div id="outer" style="-webkit-columns:4; line-height:80px;" data-expected-height="80"> + <div style="-webkit-columns:4;" data-expected-height="80"> + <div style="display:inline-block; vertical-align:top; width:80px; height:80px; background:blue;"></div> + </div> +</div> +<script> + checkLayout("#outer"); +</script>
diff --git a/third_party/WebKit/LayoutTests/nfc/idl-NFC.html b/third_party/WebKit/LayoutTests/nfc/idl-NFC.html index d098e0f5..1ca2eebe 100644 --- a/third_party/WebKit/LayoutTests/nfc/idl-NFC.html +++ b/third_party/WebKit/LayoutTests/nfc/idl-NFC.html
@@ -7,5 +7,14 @@ 'the constructor should not be callable with "new"'); assert_throws(null, function() { NFC(); }, 'the constructor should not be callable'); + + // Test that navigator.nfc.push exists + assert_true('push' in navigator.nfc); + // Test that navigator.nfc.cancelPush exists + assert_true('cancelPush' in navigator.nfc); + // Test that navigator.nfc.watch exists + assert_true('watch' in navigator.nfc); + // Test that navigator.nfc.cancelWatch exists + assert_true('cancelWatch' in navigator.nfc); }, 'NFC IDL test'); </script>
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index 77c6b6e..33715ca 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -3419,8 +3419,11 @@ getter type method constructor interface NFC + method cancelPush + method cancelWatch method constructor - method requestAdapter + method push + method watch interface NamedNodeMap getter length method constructor
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp b/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp index d364936..f22770b3 100644 --- a/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp +++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp
@@ -556,6 +556,7 @@ case CSSPrimitiveValue::UnitType::Inches: case CSSPrimitiveValue::UnitType::Points: case CSSPrimitiveValue::UnitType::Picas: + case CSSPrimitiveValue::UnitType::UserUnits: lengthType = UnitTypePixels; return true; case CSSPrimitiveValue::UnitType::Ems:
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp index 6b4eaaf..b3b7bb3 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -184,7 +184,7 @@ bool consumeNumberRaw(double& result) { - if (!m_calcValue) + if (!m_calcValue || m_calcValue->category() != CalcNumber) return false; m_sourceRange = m_range; result = m_calcValue->doubleValue(); @@ -280,10 +280,13 @@ case CSSPrimitiveValue::UnitType::Points: case CSSPrimitiveValue::UnitType::Picas: case CSSPrimitiveValue::UnitType::UserUnits: + break; case CSSPrimitiveValue::UnitType::ViewportWidth: case CSSPrimitiveValue::UnitType::ViewportHeight: case CSSPrimitiveValue::UnitType::ViewportMin: case CSSPrimitiveValue::UnitType::ViewportMax: + if (cssParserMode == SVGAttributeMode) + return nullptr; break; default: return nullptr; @@ -301,6 +304,8 @@ unitType = CSSPrimitiveValue::UnitType::UserUnits; return cssValuePool().createValue(range.consumeIncludingWhitespace().numericValue(), unitType); } + if (cssParserMode == SVGAttributeMode) + return nullptr; CalcParser calcParser(range, valueRange); if (calcParser.value() && calcParser.value()->category() == CalcLength) return calcParser.consumeValue(); @@ -1850,6 +1855,22 @@ return consumeLengthOrPercent(range, cssParserMode, ValueRangeNonNegative); } +static PassRefPtrWillBeRawPtr<CSSValue> consumeStrokeDasharray(CSSParserTokenRange& range) +{ + CSSValueID id = range.peek().id(); + if (id == CSSValueNone) + return consumeIdent(range); + + RefPtrWillBeRawPtr<CSSValueList> dashes = CSSValueList::createCommaSeparated(); + do { + RefPtrWillBeRawPtr<CSSPrimitiveValue> dash = consumeLengthOrPercent(range, SVGAttributeMode, ValueRangeNonNegative, UnitlessQuirk::Allow); + if (!dash || (consumeCommaIncludingWhitespace(range) && range.atEnd())) + return nullptr; + dashes->append(dash.release()); + } while (!range.atEnd()); + return dashes.release(); +} + PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID unresolvedProperty) { CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); @@ -2025,6 +2046,8 @@ case CSSPropertyFlexGrow: case CSSPropertyFlexShrink: return consumeNumber(m_range, ValueRangeNonNegative); + case CSSPropertyStrokeDasharray: + return consumeStrokeDasharray(m_range); default: return nullptr; }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h index 774a41e..a642fd9 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
@@ -199,7 +199,6 @@ PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFaceSrc(); bool parseSVGValue(CSSPropertyID propId, bool important); - PassRefPtrWillBeRawPtr<CSSValue> parseSVGStrokeDasharray(); // CSS3 Parsing Routines (for properties specific to CSS3) bool parseBorderImageShorthand(CSSPropertyID, bool important);
diff --git a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp index 9079aee..fcecfbd8 100644 --- a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
@@ -1153,6 +1153,7 @@ case CSSPropertyFlexGrow: case CSSPropertyFlexShrink: case CSSPropertyFlexFlow: + case CSSPropertyStrokeDasharray: validPrimitive = false; break; @@ -5441,12 +5442,6 @@ case CSSPropertyRy: validPrimitive = validUnit(value, FLength | FPercent, SVGAttributeMode); break; - case CSSPropertyStrokeDasharray: // none | <dasharray> | inherit - if (id == CSSValueNone) - validPrimitive = true; - else - parsedValue = parseSVGStrokeDasharray(); - break; default: // If you crash here, it's because you added a css property and are not handling it @@ -5481,30 +5476,4 @@ return true; } -PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSVGStrokeDasharray() -{ - RefPtrWillBeRawPtr<CSSValueList> ret = CSSValueList::createCommaSeparated(); - CSSParserValue* value = m_valueList->current(); - bool validPrimitive = true; - while (value) { - validPrimitive = validUnit(value, FLength | FPercent | FNonNeg, SVGAttributeMode); - if (!validPrimitive) - break; - if (value->id) - ret->append(CSSPrimitiveValue::createIdentifier(value->id)); - else if (value->unit() >= CSSPrimitiveValue::UnitType::Number && value->unit() <= CSSPrimitiveValue::UnitType::Kilohertz) - ret->append(CSSPrimitiveValue::create(value->fValue, value->unit())); - else if (value->unit() == CSSPrimitiveValue::UnitType::Rems || value->unit() == CSSPrimitiveValue::UnitType::Chs) - ret->append(CSSPrimitiveValue::create(value->fValue, value->unit())); - value = m_valueList->next(); - bool commaConsumed = consumeComma(m_valueList); - value = m_valueList->current(); - if (commaConsumed && !value) - return nullptr; - } - if (!validPrimitive) - return nullptr; - return ret.release(); -} - } // namespace blink
diff --git a/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp b/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp index 60009f4..3b6f8aae 100644 --- a/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp +++ b/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp
@@ -38,9 +38,27 @@ namespace blink { +BaseChooserOnlyDateAndTimeInputType::BaseChooserOnlyDateAndTimeInputType(HTMLInputElement& element) + : BaseDateAndTimeInputType(element) +{ +#if ENABLE(OILPAN) + ThreadState::current()->registerPreFinalizer(this); +#endif +} + BaseChooserOnlyDateAndTimeInputType::~BaseChooserOnlyDateAndTimeInputType() { +#if !ENABLE(OILPAN) closeDateTimeChooser(); +#endif + ASSERT(!m_dateTimeChooser); +} + +DEFINE_TRACE(BaseChooserOnlyDateAndTimeInputType) +{ + visitor->trace(m_dateTimeChooser); + BaseDateAndTimeInputType::trace(visitor); + DateTimeChooserClient::trace(visitor); } void BaseChooserOnlyDateAndTimeInputType::handleDOMActivateEvent(Event*)
diff --git a/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h b/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h index ce37c913..492e76f 100644 --- a/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h +++ b/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h
@@ -31,14 +31,19 @@ #include "core/html/forms/BaseDateAndTimeInputType.h" #include "core/html/forms/DateTimeChooser.h" #include "core/html/forms/DateTimeChooserClient.h" +#include "platform/heap/Handle.h" namespace blink { class BaseChooserOnlyDateAndTimeInputType : public BaseDateAndTimeInputType, public DateTimeChooserClient { + WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(BaseChooserOnlyDateAndTimeInputType); + WILL_BE_USING_PRE_FINALIZER(BaseChooserOnlyDateAndTimeInputType, closeDateTimeChooser); protected: - BaseChooserOnlyDateAndTimeInputType(HTMLInputElement& element) : BaseDateAndTimeInputType(element) { } + BaseChooserOnlyDateAndTimeInputType(HTMLInputElement&); ~BaseChooserOnlyDateAndTimeInputType() override; + DECLARE_VIRTUAL_TRACE(); + private: void closeDateTimeChooser(); @@ -59,9 +64,10 @@ void didChooseValue(double) override; void didEndChooser() override; - RefPtr<DateTimeChooser> m_dateTimeChooser; + RefPtrWillBeMember<DateTimeChooser> m_dateTimeChooser; }; -} -#endif -#endif +} // namespace blink + +#endif // ENABLE(INPUT_MULTIPLE_FIELDS_UI) +#endif // BaseChooserOnlyDateAndTimeInputType_h
diff --git a/third_party/WebKit/Source/core/html/forms/DateInputType.h b/third_party/WebKit/Source/core/html/forms/DateInputType.h index 38002ce..6229b6ad 100644 --- a/third_party/WebKit/Source/core/html/forms/DateInputType.h +++ b/third_party/WebKit/Source/core/html/forms/DateInputType.h
@@ -47,7 +47,8 @@ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&); private: - DateInputType(HTMLInputElement&); + explicit DateInputType(HTMLInputElement&); + void countUsage() override; const AtomicString& formControlType() const override; StepRange createStepRange(AnyStepHandling) const override;
diff --git a/third_party/WebKit/Source/core/html/forms/DateTimeChooserClient.h b/third_party/WebKit/Source/core/html/forms/DateTimeChooserClient.h index dc9a846..9f8c1e9 100644 --- a/third_party/WebKit/Source/core/html/forms/DateTimeChooserClient.h +++ b/third_party/WebKit/Source/core/html/forms/DateTimeChooserClient.h
@@ -31,15 +31,17 @@ #ifndef DateTimeChooserClient_h #define DateTimeChooserClient_h -#include "wtf/text/WTFString.h" +#include "platform/heap/Handle.h" +#include "wtf/Forward.h" namespace blink { class Element; -class DateTimeChooserClient { +class DateTimeChooserClient : public WillBeGarbageCollectedMixin { public: virtual ~DateTimeChooserClient(); + DEFINE_INLINE_VIRTUAL_TRACE() { } virtual Element& ownerElement() const = 0; // Called when user picked a value.
diff --git a/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h b/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h index 538882f..d0db7d7 100644 --- a/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h +++ b/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h
@@ -49,7 +49,8 @@ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&); private: - DateTimeLocalInputType(HTMLInputElement& element) : BaseDateTimeLocalInputType(element) { } + explicit DateTimeLocalInputType(HTMLInputElement& element) : BaseDateTimeLocalInputType(element) { } + void countUsage() override; const AtomicString& formControlType() const override; double valueAsDate() const override;
diff --git a/third_party/WebKit/Source/core/html/forms/MonthInputType.h b/third_party/WebKit/Source/core/html/forms/MonthInputType.h index 3b1af1c..b491730 100644 --- a/third_party/WebKit/Source/core/html/forms/MonthInputType.h +++ b/third_party/WebKit/Source/core/html/forms/MonthInputType.h
@@ -47,7 +47,8 @@ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&); private: - MonthInputType(HTMLInputElement& element) : BaseMonthInputType(element) { } + explicit MonthInputType(HTMLInputElement& element) : BaseMonthInputType(element) { } + void countUsage() override; const AtomicString& formControlType() const override; double valueAsDate() const override;
diff --git a/third_party/WebKit/Source/core/html/forms/TimeInputType.h b/third_party/WebKit/Source/core/html/forms/TimeInputType.h index 25192ddb..85ac111 100644 --- a/third_party/WebKit/Source/core/html/forms/TimeInputType.h +++ b/third_party/WebKit/Source/core/html/forms/TimeInputType.h
@@ -47,7 +47,8 @@ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&); private: - TimeInputType(HTMLInputElement&); + explicit TimeInputType(HTMLInputElement&); + void countUsage() override; const AtomicString& formControlType() const override; Decimal defaultValueForStepUp() const override; @@ -56,8 +57,8 @@ bool setMillisecondToDateComponents(double, DateComponents*) const override; void warnIfValueIsInvalid(const String&) const override; String localizeValue(const String&) const override; -#if ENABLE(INPUT_MULTIPLE_FIELDS_UI) +#if ENABLE(INPUT_MULTIPLE_FIELDS_UI) // BaseMultipleFieldsDateAndTimeInputType functions String formatDateTimeFieldsState(const DateTimeFieldsState&) const override; void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const override;
diff --git a/third_party/WebKit/Source/core/html/forms/WeekInputType.h b/third_party/WebKit/Source/core/html/forms/WeekInputType.h index 32511ac1..98acfcb 100644 --- a/third_party/WebKit/Source/core/html/forms/WeekInputType.h +++ b/third_party/WebKit/Source/core/html/forms/WeekInputType.h
@@ -47,7 +47,8 @@ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&); private: - WeekInputType(HTMLInputElement& element) : BaseWeekInputType(element) { } + explicit WeekInputType(HTMLInputElement& element) : BaseWeekInputType(element) { } + void countUsage() override; const AtomicString& formControlType() const override; StepRange createStepRange(AnyStepHandling) const override;
diff --git a/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp b/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp index 9d60f71..22b03e5 100644 --- a/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp +++ b/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp
@@ -187,8 +187,9 @@ visitor->trace(m_pickerIndicatorOwner); visitor->trace(m_chooser); HTMLDivElement::trace(visitor); + DateTimeChooserClient::trace(visitor); } -} +} // namespace blink -#endif +#endif // ENABLE(INPUT_MULTIPLE_FIELDS_UI)
diff --git a/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h b/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h index fe14ee6..7ce6bfe 100644 --- a/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h +++ b/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h
@@ -41,6 +41,7 @@ class HTMLInputElement; class PickerIndicatorElement final : public HTMLDivElement, public DateTimeChooserClient { + WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(PickerIndicatorElement); public: // PickerIndicatorOwner implementer must call removePickerIndicatorOwner when // it doesn't handle event, e.g. at destruction.
diff --git a/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp b/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp index 989f2d8..3de1e264 100644 --- a/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp +++ b/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp
@@ -92,8 +92,7 @@ { unsigned index = contentRunIndexWithTallestColumns(); LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() : group().logicalTopInFlowThread(); - LayoutUnit logicalHeightEstimate = m_contentRuns[index].columnLogicalHeight(startOffset); - return std::max(logicalHeightEstimate, m_minimumColumnLogicalHeight); + return m_contentRuns[index].columnLogicalHeight(startOffset); } void InitialColumnHeightFinder::examineBoxAfterEntering(const LayoutBox& box) @@ -113,8 +112,13 @@ LayoutUnit unsplittableLogicalHeight = box.logicalHeight(); if (box.isFloating()) unsplittableLogicalHeight += box.marginBefore() + box.marginAfter(); - if (m_minimumColumnLogicalHeight < unsplittableLogicalHeight) - m_minimumColumnLogicalHeight = unsplittableLogicalHeight; + m_tallestUnbreakableLogicalHeight = std::max(m_tallestUnbreakableLogicalHeight, unsplittableLogicalHeight); + } else if (box.isLayoutBlockFlow()) { + if (LayoutMultiColumnFlowThread* innerFlowThread = toLayoutBlockFlow(box).multiColumnFlowThread()) { + LayoutUnit offsetInInnerFlowThread = flowThreadOffset() - innerFlowThread->blockOffsetInEnclosingFlowThread(); + LayoutUnit innerUnbreakableHeight = innerFlowThread->tallestUnbreakableLogicalHeight(offsetInInnerFlowThread); + m_tallestUnbreakableLogicalHeight = std::max(m_tallestUnbreakableLogicalHeight, innerUnbreakableHeight); + } } } @@ -138,8 +142,7 @@ LayoutUnit lineTop = line.lineTopWithLeading(); LayoutUnit lineTopInFlowThread = flowThreadOffset() + lineTop; LayoutUnit minimumLogialHeight = columnLogicalHeightRequirementForLine(line.block().styleRef(), line); - if (m_minimumColumnLogicalHeight < minimumLogialHeight) - m_minimumColumnLogicalHeight = minimumLogialHeight; + m_tallestUnbreakableLogicalHeight = std::max(m_tallestUnbreakableLogicalHeight, minimumLogialHeight); ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut()); if (isFirstAfterBreak(lineTopInFlowThread)) recordStrutBeforeOffset(lineTopInFlowThread, line.paginationStrut());
diff --git a/third_party/WebKit/Source/core/layout/ColumnBalancer.h b/third_party/WebKit/Source/core/layout/ColumnBalancer.h index 161f5a0..9bf1dacc 100644 --- a/third_party/WebKit/Source/core/layout/ColumnBalancer.h +++ b/third_party/WebKit/Source/core/layout/ColumnBalancer.h
@@ -62,16 +62,17 @@ // of this class, named MinimumSpaceShortageFinder. class InitialColumnHeightFinder final : public ColumnBalancer { public: - static LayoutUnit initialMinimalBalancedHeight(const MultiColumnFragmentainerGroup& group) - { - return InitialColumnHeightFinder(group).initialMinimalBalancedHeight(); - } - -private: InitialColumnHeightFinder(const MultiColumnFragmentainerGroup&); LayoutUnit initialMinimalBalancedHeight() const; + // Height of the tallest piece of unbreakable content. This is the minimum column logical height + // required to avoid fragmentation where it shouldn't occur (inside unbreakable content, between + // orphans and widows, etc.). This will be used as a hint to the column balancer to help set a + // good initial column height. + LayoutUnit tallestUnbreakableLogicalHeight() const { return m_tallestUnbreakableLogicalHeight; } + +private: void examineBoxAfterEntering(const LayoutBox&); void examineBoxBeforeLeaving(const LayoutBox&); void examineLine(const RootInlineBox&); @@ -139,7 +140,7 @@ // [1] http://www.w3.org/TR/css3-break/#parallel-flows Vector<LayoutUnit, 32> m_shortestStruts; - LayoutUnit m_minimumColumnLogicalHeight; + LayoutUnit m_tallestUnbreakableLogicalHeight; }; // If we have previously used InitialColumnHeightFinder to estimate an initial column height, and
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp index bd4bf8a..1286c81 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -716,9 +716,7 @@ // FIXME: Should really check if we're exceeding the page height before propagating the strut, but we don't // have all the information to do so (the strut only has the remaining amount to push). Gecko gets this wrong too // and pushes to the next page anyway, so not too concerned about it. - paginationStrut += logicalTop; - if (isFloating()) - paginationStrut += marginBefore(); // Floats' margins do not collapse with page or column boundaries. + paginationStrut += logicalTop + marginBeforeIfFloating(); setPaginationStrutPropagatedFromChild(paginationStrut); if (childBlockFlow) childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit()); @@ -762,14 +760,6 @@ return wantsStrutOnBlock && block.allowsPaginationStrut(); } -static LayoutUnit calculateStrutForPropagation(const LayoutBlockFlow& blockFlow, LayoutUnit lineLogicalOffset) -{ - LayoutUnit paginationStrut = std::max<LayoutUnit>(LayoutUnit(), lineLogicalOffset); - if (blockFlow.isFloating()) - paginationStrut += blockFlow.marginBefore(); // Floats' margins do not collapse with page or column boundaries. - return paginationStrut; -} - void LayoutBlockFlow::adjustLinePositionForPagination(RootInlineBox& lineBox, LayoutUnit& delta) { // TODO(mstensho): Pay attention to line overflow. It should be painted in the same column as @@ -813,7 +803,8 @@ // content-less portions (struts) at the beginning of a block before a break, if it can // be avoided. After all, that's the reason for setting struts on blocks and not lines // in the first place. - setPaginationStrutPropagatedFromChild(calculateStrutForPropagation(*this, remainingLogicalHeight + logicalOffset)); + LayoutUnit strut = remainingLogicalHeight + logicalOffset + marginBeforeIfFloating(); + setPaginationStrutPropagatedFromChild(strut); } else { logicalOffset += remainingLogicalHeight; delta += remainingLogicalHeight; @@ -828,15 +819,15 @@ // case it's a float) margin, we may want to set a strut on the block, so that everything // ends up in the next column or page. Setting a strut on the block is also important when // it comes to satisfying orphan requirements. - if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, remainingLogicalHeight)) - setPaginationStrutPropagatedFromChild(calculateStrutForPropagation(*this, logicalOffset)); + if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, remainingLogicalHeight)) { + LayoutUnit strut = logicalOffset + marginBeforeIfFloating(); + setPaginationStrutPropagatedFromChild(strut); + } } else if (lineBox == firstRootBox() && allowsPaginationStrut()) { // This is the first line in the block. The block may still start in the previous column or // page, and if that's the case, attempt to pull it over to where this line is, so that we // don't split the top border, padding, or (in case it's a float) margin. - LayoutUnit totalLogicalOffset = logicalOffset; - if (isFloating()) - totalLogicalOffset += marginBefore(); // Floats' margins do not collapse with page or column boundaries. + LayoutUnit totalLogicalOffset = logicalOffset + marginBeforeIfFloating(); LayoutUnit strut = remainingLogicalHeight + totalLogicalOffset - pageLogicalHeight; if (strut > 0) { // The block starts in a previous column or page. Set a strut on the block if there's @@ -2932,6 +2923,7 @@ void LayoutBlockFlow::setPaginationStrutPropagatedFromChild(LayoutUnit strut) { + strut = std::max(strut, LayoutUnit()); if (!m_rareData) { if (!strut) return;
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h index cb05410..ca222c0 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
@@ -516,6 +516,10 @@ LayoutUnit collapsedMarginBefore() const final { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); } LayoutUnit collapsedMarginAfter() const final { return maxPositiveMarginAfter() - maxNegativeMarginAfter(); } + // Floats' margins do not collapse with page or column boundaries, and we therefore need to + // treat them specially in some cases. + LayoutUnit marginBeforeIfFloating() const { return isFloating() ? marginBefore() : LayoutUnit(); } + LayoutUnit collapseMargins(LayoutBox& child, MarginInfo&, bool childIsSelfCollapsing, bool childDiscardMarginBefore, bool childDiscardMarginAfter); LayoutUnit clearFloatsIfNeeded(LayoutBox& child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos, bool childIsSelfCollapsing, bool childDiscardMargin); LayoutUnit estimateLogicalTopPosition(LayoutBox& child, const MarginInfo&, LayoutUnit& estimateWithoutPagination);
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp index 5e2ad6f..fc7e68b 100644 --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
@@ -262,6 +262,13 @@ destroy(); } +LayoutUnit LayoutMultiColumnFlowThread::tallestUnbreakableLogicalHeight(LayoutUnit offsetInFlowThread) const +{ + if (LayoutMultiColumnSet* multicolSet = columnSetAtBlockOffset(offsetInFlowThread)) + return multicolSet->tallestUnbreakableLogicalHeight(); + return LayoutUnit(); +} + LayoutSize LayoutMultiColumnFlowThread::columnOffset(const LayoutPoint& point) const { if (!hasValidColumnSetInfo())
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h index 057fec7..42acf66 100644 --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h
@@ -162,6 +162,8 @@ void setColumnHeightAvailable(LayoutUnit available) { m_columnHeightAvailable = available; } bool progressionIsInline() const { return m_progressionIsInline; } + LayoutUnit tallestUnbreakableLogicalHeight(LayoutUnit offsetInFlowThread) const; + LayoutSize columnOffset(const LayoutPoint&) const final; // Do we need to set a new width and lay out?
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp index 378540b..0b9ed3a 100644 --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
@@ -216,6 +216,8 @@ bool LayoutMultiColumnSet::recalculateColumnHeight(BalancedColumnHeightCalculation calculationMode) { + if (calculationMode == GuessFromFlowThreadPortion) + m_tallestUnbreakableLogicalHeight = LayoutUnit(); bool changed = false; for (auto& group : m_fragmentainerGroups) changed = group.recalculateColumnHeight(calculationMode) || changed;
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h index c5884e9..a167878 100644 --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h
@@ -82,6 +82,8 @@ LayoutUnit pageLogicalHeightForOffset(LayoutUnit) const; LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit, PageBoundaryRule) const; bool isPageLogicalHeightKnown() const; + LayoutUnit tallestUnbreakableLogicalHeight() const { return m_tallestUnbreakableLogicalHeight; } + void propagateTallestUnbreakableLogicalHeight(LayoutUnit value) { m_tallestUnbreakableLogicalHeight = std::max(value, m_tallestUnbreakableLogicalHeight); } LayoutFlowThread* flowThread() const { return m_flowThread; } @@ -168,6 +170,14 @@ MultiColumnFragmentainerGroupList m_fragmentainerGroups; LayoutFlowThread* m_flowThread; + + // Height of the tallest piece of unbreakable content. This is the minimum column logical height + // required to avoid fragmentation where it shouldn't occur (inside unbreakable content, between + // orphans and widows, etc.). We only store this so that outer fragmentation contexts (if any) + // can query this when calculating their own minimum. Note that we don't store this value in + // every fragmentainer group (but rather here, in the column set), since we only need the + // largest one among them. + LayoutUnit m_tallestUnbreakableLogicalHeight; }; DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutMultiColumnSet, isLayoutMultiColumnSet());
diff --git a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp index 09c64a88..431cc2d 100644 --- a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp +++ b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp
@@ -68,13 +68,25 @@ // balance the preceding rows, and that could potentially lead to an insane number of layout // passes as well. if (isLastGroup() && m_columnSet.heightIsAuto()) { - LayoutUnit newColumnHeight = calculateColumnHeight(calculationMode); + LayoutUnit newColumnHeight; + if (calculationMode == GuessFromFlowThreadPortion) { + // Initial balancing: Start with the lowest imaginable column height. Also calculate the + // height of the tallest piece of unbreakable content. Columns should never get any + // shorter than that (unless constrained by max-height). Propagate this to our + // containing column set, in case there is an outer multicol container that also needs + // to balance. After having calculated the initial column height, the multicol container + // needs another layout pass with the column height that we just calculated. + InitialColumnHeightFinder initialHeightFinder(*this); + LayoutUnit tallestUnbreakableLogicalHeight = initialHeightFinder.tallestUnbreakableLogicalHeight(); + m_columnSet.propagateTallestUnbreakableLogicalHeight(tallestUnbreakableLogicalHeight); + newColumnHeight = std::max(initialHeightFinder.initialMinimalBalancedHeight(), tallestUnbreakableLogicalHeight); + } else { + // Rebalancing: After having laid out again, we'll need to rebalance if the height + // wasn't enough and we're allowed to stretch it, and then re-lay out. There are further + // details on the column balancing machinery in ColumnBalancer and its derivates. + newColumnHeight = rebalanceColumnHeightIfNeeded(); + } setAndConstrainColumnHeight(newColumnHeight); - // After having calculated an initial column height, the multicol container typically needs at - // least one more layout pass with a new column height, but if a height was specified, we only - // need to do this if we think that we need less space than specified. Conversely, if we - // determined that the columns need to be as tall as the specified height of the container, we - // have already laid it out correctly, and there's no need for another pass. } else { // The position of the column set may have changed, in which case height available for // columns may have changed as well. @@ -331,16 +343,8 @@ m_columnHeight = m_maxColumnHeight; } -LayoutUnit MultiColumnFragmentainerGroup::calculateColumnHeight(BalancedColumnHeightCalculation calculationMode) const +LayoutUnit MultiColumnFragmentainerGroup::rebalanceColumnHeightIfNeeded() const { - if (calculationMode == GuessFromFlowThreadPortion) { - // Initial balancing. Start with the lowest imaginable column height. We use the tallest - // content run (after having "inserted" implicit breaks), and find its start offset (by - // looking at the previous run's end offset, or, if there's no previous run, the set's start - // offset in the flow thread). - return InitialColumnHeightFinder::initialMinimalBalancedHeight(*this); - } - if (actualColumnCount() <= m_columnSet.usedColumnCount()) { // With the current column height, the content fits without creating overflowing columns. We're done. return m_columnHeight;
diff --git a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h index 4f53c50e..e0e1f49 100644 --- a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h +++ b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h
@@ -84,7 +84,7 @@ LayoutUnit calculateMaxColumnHeight() const; void setAndConstrainColumnHeight(LayoutUnit); - LayoutUnit calculateColumnHeight(BalancedColumnHeightCalculation) const; + LayoutUnit rebalanceColumnHeightIfNeeded() const; LayoutRect columnRectAt(unsigned columnIndex) const; LayoutUnit logicalTopInFlowThreadAt(unsigned columnIndex) const { return m_logicalTopInFlowThread + columnIndex * m_columnHeight; }
diff --git a/third_party/WebKit/Source/modules/mediastream/RTCIceCandidate.idl b/third_party/WebKit/Source/modules/mediastream/RTCIceCandidate.idl index d6ce94d..d3bce54a 100644 --- a/third_party/WebKit/Source/modules/mediastream/RTCIceCandidate.idl +++ b/third_party/WebKit/Source/modules/mediastream/RTCIceCandidate.idl
@@ -33,8 +33,8 @@ Constructor(RTCIceCandidateInit candidateInitDict), RaisesException=Constructor ] interface RTCIceCandidate { - [TreatNullAs=NullString] attribute DOMString candidate; - [TreatNullAs=NullString] attribute DOMString sdpMid; + attribute DOMString candidate; + attribute DOMString sdpMid; attribute unsigned short sdpMLineIndex; serializer = {attribute}; };
diff --git a/third_party/WebKit/Source/modules/modules.gypi b/third_party/WebKit/Source/modules/modules.gypi index f80fbaa..fe95788 100644 --- a/third_party/WebKit/Source/modules/modules.gypi +++ b/third_party/WebKit/Source/modules/modules.gypi
@@ -144,6 +144,7 @@ 'navigatorconnect/ServicePortConnectEvent.idl', 'navigatorconnect/ServicePortCollection.idl', 'netinfo/NetworkInformation.idl', + 'nfc/MessageCallback.idl', 'nfc/NFC.idl', 'notifications/Notification.idl', 'notifications/NotificationEvent.idl', @@ -471,6 +472,7 @@ 'navigatorconnect/ServicePortConnectOptions.idl', 'navigatorconnect/ServicePortConnectResponse.idl', 'navigatorconnect/ServicePortMatchOptions.idl', + 'nfc/NFCMessage.idl', 'nfc/NFCPushOptions.idl', 'nfc/NFCRecord.idl', 'nfc/NFCWatchOptions.idl', @@ -608,6 +610,8 @@ '<(blink_modules_output_dir)/navigatorconnect/ServicePortConnectResponse.h', '<(blink_modules_output_dir)/navigatorconnect/ServicePortMatchOptions.cpp', '<(blink_modules_output_dir)/navigatorconnect/ServicePortMatchOptions.h', + '<(blink_modules_output_dir)/nfc/NFCMessage.cpp', + '<(blink_modules_output_dir)/nfc/NFCMessage.h', '<(blink_modules_output_dir)/nfc/NFCPushOptions.cpp', '<(blink_modules_output_dir)/nfc/NFCPushOptions.h', '<(blink_modules_output_dir)/nfc/NFCRecord.cpp',
diff --git a/third_party/WebKit/Source/modules/nfc/MessageCallback.h b/third_party/WebKit/Source/modules/nfc/MessageCallback.h new file mode 100644 index 0000000..84d4279 --- /dev/null +++ b/third_party/WebKit/Source/modules/nfc/MessageCallback.h
@@ -0,0 +1,23 @@ +// Copyright 2015 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 MessageCallback_h +#define MessageCallback_h + +#include "platform/heap/Handle.h" + +namespace blink { + +class NFCMessage; + +class MessageCallback : public GarbageCollectedFinalized<MessageCallback> { +public: + virtual ~MessageCallback() { } + DEFINE_INLINE_VIRTUAL_TRACE() { } + virtual void handleMessage(const NFCMessage&) = 0; +}; + +} // namespace blink + +#endif // MessageCallback_h
diff --git a/third_party/WebKit/Source/modules/nfc/MessageCallback.idl b/third_party/WebKit/Source/modules/nfc/MessageCallback.idl new file mode 100644 index 0000000..edbffe5 --- /dev/null +++ b/third_party/WebKit/Source/modules/nfc/MessageCallback.idl
@@ -0,0 +1,9 @@ +// Copyright 2015 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. + +// https://w3c.github.io/web-nfc/#idl-def-messagecallback + +callback interface MessageCallback { + void handleMessage(NFCMessage message); +};
diff --git a/third_party/WebKit/Source/modules/nfc/NFC.cpp b/third_party/WebKit/Source/modules/nfc/NFC.cpp index ffd1cf7..1f935e5 100644 --- a/third_party/WebKit/Source/modules/nfc/NFC.cpp +++ b/third_party/WebKit/Source/modules/nfc/NFC.cpp
@@ -8,6 +8,8 @@ #include "bindings/core/v8/ScriptPromiseResolver.h" #include "core/dom/DOMException.h" #include "core/dom/ExceptionCode.h" +#include "modules/nfc/NFCMessage.h" +#include "modules/nfc/NFCPushOptions.h" namespace blink { @@ -23,13 +25,33 @@ return nfc; } -NFC::~NFC() +ScriptPromise NFC::push(ScriptState* scriptState, const NFCPushMessage& records, const NFCPushOptions& options) { + // TODO(shalamov): To be implemented. + return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError)); } -ScriptPromise NFC::requestAdapter(ScriptState* scriptState) +ScriptPromise NFC::cancelPush(ScriptState* scriptState, const String& target) { - // TODO(riju): To be implemented. + // TODO(shalamov): To be implemented. + return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError)); +} + +ScriptPromise NFC::watch(ScriptState* scriptState, MessageCallback* callback, const NFCWatchOptions& options) +{ + // TODO(shalamov): To be implemented. + return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError)); +} + +ScriptPromise NFC::cancelWatch(ScriptState* scriptState, long id) +{ + // TODO(shalamov): To be implemented. + return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError)); +} + +ScriptPromise NFC::cancelWatch(ScriptState* scriptState) +{ + // TODO(shalamov): To be implemented. return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError)); }
diff --git a/third_party/WebKit/Source/modules/nfc/NFC.h b/third_party/WebKit/Source/modules/nfc/NFC.h index ffb5845f..50b9b47e 100644 --- a/third_party/WebKit/Source/modules/nfc/NFC.h +++ b/third_party/WebKit/Source/modules/nfc/NFC.h
@@ -7,11 +7,17 @@ #include "bindings/core/v8/ScriptPromise.h" #include "bindings/core/v8/ScriptWrappable.h" +#include "bindings/modules/v8/UnionTypesModules.h" #include "core/frame/LocalFrameLifecycleObserver.h" #include "core/page/PageLifecycleObserver.h" namespace blink { +class MessageCallback; +class NFCPushOptions; +using NFCPushMessage = StringOrArrayBufferOrNFCMessage; +class NFCWatchOptions; + class NFC final : public GarbageCollectedFinalized<NFC> , public ScriptWrappable @@ -22,19 +28,29 @@ public: static NFC* create(LocalFrame*); -#if ENABLE(OILPAN) - ~NFC(); -#else - ~NFC() override; +#if !ENABLE(OILPAN) + ~NFC() override = default; #endif - // Get an adapter object providing NFC functionality. - ScriptPromise requestAdapter(ScriptState*); + // Pushes NFCPushMessage asynchronously to NFC tag / peer. + ScriptPromise push(ScriptState*, const NFCPushMessage&, const NFCPushOptions&); + + // Cancels ongoing push operation. + ScriptPromise cancelPush(ScriptState*, const String&); + + // Starts watching for NFC messages that match NFCWatchOptions criteria. + ScriptPromise watch(ScriptState*, MessageCallback*, const NFCWatchOptions&); + + // Cancels watch operation with id. + ScriptPromise cancelWatch(ScriptState*, long id); + + // Cancels all watch operations. + ScriptPromise cancelWatch(ScriptState*); // Implementation of LocalFrameLifecycleObserver. void willDetachFrameHost() override; - // Implementation of PageLifecycleObserver + // Implementation of PageLifecycleObserver. void pageVisibilityChanged() override; // Interface required by garbage collection.
diff --git a/third_party/WebKit/Source/modules/nfc/NFC.idl b/third_party/WebKit/Source/modules/nfc/NFC.idl index cc38e16f..bb0f5209 100644 --- a/third_party/WebKit/Source/modules/nfc/NFC.idl +++ b/third_party/WebKit/Source/modules/nfc/NFC.idl
@@ -2,11 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/web-nfc/#idl-def-NFC +// https://w3c.github.io/web-nfc/#the-nfc-interface + +typedef (DOMString or ArrayBuffer or NFCMessage) NFCPushMessage; [ GarbageCollected, RuntimeEnabled=WebNFC, ] interface NFC { - [CallWith=ScriptState] Promise<NFCAdapter> requestAdapter (); + [CallWith=ScriptState] Promise<void> push (NFCPushMessage message, optional NFCPushOptions options); + [CallWith=ScriptState] Promise<void> cancelPush (optional NFCPushTarget target = "any"); + [CallWith=ScriptState] Promise<long> watch (MessageCallback callback, optional NFCWatchOptions options); + [CallWith=ScriptState] Promise<void> cancelWatch (optional long id); };
diff --git a/third_party/WebKit/Source/modules/nfc/NFCMessage.idl b/third_party/WebKit/Source/modules/nfc/NFCMessage.idl new file mode 100644 index 0000000..5cea9c70 --- /dev/null +++ b/third_party/WebKit/Source/modules/nfc/NFCMessage.idl
@@ -0,0 +1,10 @@ +// Copyright 2015 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. + +// https://w3c.github.io/web-nfc/#the-nfcmessage-dictionary + +dictionary NFCMessage { + sequence<NFCRecord> data; + USVString url; +};
diff --git a/third_party/WebKit/Source/modules/nfc/NFCPushOptions.idl b/third_party/WebKit/Source/modules/nfc/NFCPushOptions.idl index 2fe24e81..c7c78fb5 100644 --- a/third_party/WebKit/Source/modules/nfc/NFCPushOptions.idl +++ b/third_party/WebKit/Source/modules/nfc/NFCPushOptions.idl
@@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/web-nfc/index.html#the-nfcpushoptions-dictionary +// https://w3c.github.io/web-nfc/#the-nfcpushoptions-dictionary -enum NFCPushTarget { "tag", "peer" }; +enum NFCPushTarget { "tag", "peer", "any" }; dictionary NFCPushOptions { - NFCPushTarget target; - unsigned long timeout; + NFCPushTarget target = "any"; + unrestricted double timeout; // in ms + boolean ignoreRead = true; };
diff --git a/third_party/WebKit/Source/modules/nfc/NFCRecord.idl b/third_party/WebKit/Source/modules/nfc/NFCRecord.idl index a20ccbb..48bfd24 100644 --- a/third_party/WebKit/Source/modules/nfc/NFCRecord.idl +++ b/third_party/WebKit/Source/modules/nfc/NFCRecord.idl
@@ -2,17 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/web-nfc/index.html#the-nfcrecord-dictionary +// https://w3c.github.io/web-nfc/#the-nfcrecord-dictionary enum NFCRecordType { "empty", "text", "url", "json", "opaque" }; -// typedef (DOMString or unrestricted double or object or ArrayBuffer) NFCRecordData; +// TODO(shalamov): This is blocked by https://crbug.com/524424 +// typedef (DOMString or unrestricted double or ArrayBuffer or Dictionary) NFCRecordData; +typedef any NFCRecordData; dictionary NFCRecord { - NFCRecordType kind; - USVString type; - // NFCRecordData data; - // Use ´any´ as Blink IDL compiler complains that Object is not supported as - // union member. Tracked in https://crbug.com/537133 . - any data; + NFCRecordType recordType; + USVString mediaType; + NFCRecordData data; };
diff --git a/third_party/WebKit/Source/modules/nfc/NFCWatchOptions.idl b/third_party/WebKit/Source/modules/nfc/NFCWatchOptions.idl index 971497a..8a4722de 100644 --- a/third_party/WebKit/Source/modules/nfc/NFCWatchOptions.idl +++ b/third_party/WebKit/Source/modules/nfc/NFCWatchOptions.idl
@@ -2,15 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/web-nfc/#idl-def-nfcwatchoptions +// https://w3c.github.io/web-nfc/#the-nfcwatchoptions-dictionary enum NFCWatchMode { "web-nfc-only", "any" }; -[ - RuntimeEnabled=WebNFC, -] dictionary NFCWatchOptions { - USVString url = ""; - USVString kind = ""; - USVString type = ""; +dictionary NFCWatchOptions { + USVString url = ""; + NFCRecordType? recordType; + USVString mediaType = ""; NFCWatchMode mode = "web-nfc-only"; };
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp index e8d9ee84..daff13f 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
@@ -393,20 +393,93 @@ } } -void WebGL2RenderingContextBase::invalidateFramebuffer(GLenum target, Vector<GLenum>& attachments) +bool WebGL2RenderingContextBase::checkAndTranslateAttachments(const char* functionName, GLenum target, const Vector<GLenum>& attachments, Vector<GLenum>& translatedAttachments) { - if (isContextLost()) - return; + GLsizei size = attachments.size(); + translatedAttachments.resize(size); - webContext()->invalidateFramebuffer(target, attachments.size(), attachments.data()); + WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target); + ASSERT(framebufferBinding || drawingBuffer()); + if (!framebufferBinding) { + // For the default framebuffer + // Translate GL_COLOR/GL_DEPTH/GL_STENCIL, because the default framebuffer of WebGL is not fb 0, it is an internal fbo + for (GLsizei i = 0; i < size; ++i) { + switch (attachments[i]) { + case GL_COLOR: + translatedAttachments[i] = GL_COLOR_ATTACHMENT0; + break; + case GL_DEPTH: + translatedAttachments[i] = GL_DEPTH_ATTACHMENT; + break; + case GL_STENCIL: + translatedAttachments[i] = GL_STENCIL_ATTACHMENT; + break; + default: + synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid attachment"); + return false; + } + } + } else { + // For the FBO + for (GLsizei i = 0; i < size; ++i) { + switch (attachments[i]) { + case GL_COLOR_ATTACHMENT0: + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + case GL_DEPTH_STENCIL_ATTACHMENT: + translatedAttachments[i] = attachments[i]; + break; + default: + if (attachments[i] > GL_COLOR_ATTACHMENT0 + && attachments[i] < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + maxColorAttachments())) { + translatedAttachments[i] = attachments[i]; + break; + } + synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid attachment"); + return false; + } + } + } + return true; } -void WebGL2RenderingContextBase::invalidateSubFramebuffer(GLenum target, Vector<GLenum>& attachments, GLint x, GLint y, GLsizei width, GLsizei height) +void WebGL2RenderingContextBase::invalidateFramebuffer(GLenum target, const Vector<GLenum>& attachments) { if (isContextLost()) return; - webContext()->invalidateSubFramebuffer(target, attachments.size(), attachments.data(), x, y, width, height); + if (!validateFramebufferTarget(target)) { + synthesizeGLError(GL_INVALID_ENUM, "invalidateFramebuffer", "invalid target"); + return; + } + + Vector<GLenum> translatedAttachments; + if (!checkAndTranslateAttachments("invalidateFramebuffer", target, attachments, translatedAttachments)) + return; + + webContext()->invalidateFramebuffer(target, translatedAttachments.size(), translatedAttachments.data()); +} + +void WebGL2RenderingContextBase::invalidateSubFramebuffer(GLenum target, const Vector<GLenum>& attachments, GLint x, GLint y, GLsizei width, GLsizei height) +{ + if (isContextLost()) + return; + + if (!validateFramebufferTarget(target)) { + synthesizeGLError(GL_INVALID_ENUM, "invalidateFramebuffer", "invalid target"); + return; + } + + if (width < 0 || height < 0) { + synthesizeGLError(GL_INVALID_VALUE, "invalidateSubFramebuffer", "invalid width or height"); + return; + } + + Vector<GLenum> translatedAttachments; + if (!checkAndTranslateAttachments("invalidateSubFramebuffer", target, attachments, translatedAttachments)) + return; + + webContext()->invalidateSubFramebuffer(target, translatedAttachments.size(), translatedAttachments.data(), x, y, width, height); } void WebGL2RenderingContextBase::readBuffer(GLenum mode)
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h index 3ab1aad..726ceb2 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h +++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h
@@ -36,8 +36,8 @@ void blitFramebuffer(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); void framebufferTextureLayer(ScriptState*, GLenum, GLenum, WebGLTexture*, GLint, GLint); ScriptValue getInternalformatParameter(ScriptState*, GLenum, GLenum, GLenum); - void invalidateFramebuffer(GLenum, Vector<GLenum>&); - void invalidateSubFramebuffer(GLenum, Vector<GLenum>&, GLint, GLint, GLsizei, GLsizei); + void invalidateFramebuffer(GLenum, const Vector<GLenum>&); + void invalidateSubFramebuffer(GLenum, const Vector<GLenum>&, GLint, GLint, GLsizei, GLsizei); void readBuffer(GLenum); /* Renderbuffer objects */ @@ -213,6 +213,8 @@ void vertexAttribIivImpl(const char*, GLuint, const GLint*, GLsizei); void vertexAttribIuivImpl(const char*, GLuint, const GLuint*, GLsizei); + bool checkAndTranslateAttachments(const char* functionName, GLenum, const Vector<GLenum>&, Vector<GLenum>&); + /* WebGLRenderingContextBase overrides */ unsigned getMaxWebGLLocationLength() const override { return 1024; }; bool validateCapability(const char* functionName, GLenum) override;
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp index 071b252..d75c36d 100644 --- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp +++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -4596,6 +4596,25 @@ Member<IntWrapper> m_obj; }; +class DerivedMultipleMixins : public MultipleMixins { +public: + DerivedMultipleMixins() : m_obj(IntWrapper::create(103)) { } + + DEFINE_INLINE_VIRTUAL_TRACE() + { + s_traceCalled++; + visitor->trace(m_obj); + MultipleMixins::trace(visitor); + } + + static int s_traceCalled; + +private: + Member<IntWrapper> m_obj; +}; + +int DerivedMultipleMixins::s_traceCalled = 0; + static const bool s_isMixinTrue = IsGarbageCollectedMixin<MultipleMixins>::value; static const bool s_isMixinFalse = IsGarbageCollectedMixin<IntWrapper>::value; @@ -4621,6 +4640,29 @@ EXPECT_EQ(3, IntWrapper::s_destructorCalls); } +TEST(HeapTest, DerivedMultipleMixins) +{ + clearOutOldGarbage(); + IntWrapper::s_destructorCalls = 0; + DerivedMultipleMixins::s_traceCalled = 0; + + DerivedMultipleMixins* obj = new DerivedMultipleMixins(); + { + Persistent<MixinA> a = obj; + preciselyCollectGarbage(); + EXPECT_EQ(0, IntWrapper::s_destructorCalls); + EXPECT_EQ(1, DerivedMultipleMixins::s_traceCalled); + } + { + Persistent<MixinB> b = obj; + preciselyCollectGarbage(); + EXPECT_EQ(0, IntWrapper::s_destructorCalls); + EXPECT_EQ(2, DerivedMultipleMixins::s_traceCalled); + } + preciselyCollectGarbage(); + EXPECT_EQ(4, IntWrapper::s_destructorCalls); +} + class GCParkingThreadTester { public: static void test()
diff --git a/third_party/WebKit/Source/web/DateTimeChooserImpl.cpp b/third_party/WebKit/Source/web/DateTimeChooserImpl.cpp index 0d93ced..7bb8523 100644 --- a/third_party/WebKit/Source/web/DateTimeChooserImpl.cpp +++ b/third_party/WebKit/Source/web/DateTimeChooserImpl.cpp
@@ -70,6 +70,7 @@ DEFINE_TRACE(DateTimeChooserImpl) { visitor->trace(m_chromeClient); + visitor->trace(m_client); DateTimeChooser::trace(visitor); } @@ -204,7 +205,7 @@ void DateTimeChooserImpl::didClosePopup() { ASSERT(m_client); - m_popup = 0; + m_popup = nullptr; m_client->didEndChooser(); }
diff --git a/third_party/WebKit/Source/web/DateTimeChooserImpl.h b/third_party/WebKit/Source/web/DateTimeChooserImpl.h index 368afa6..d7b9d9b 100644 --- a/third_party/WebKit/Source/web/DateTimeChooserImpl.h +++ b/third_party/WebKit/Source/web/DateTimeChooserImpl.h
@@ -65,7 +65,7 @@ void didClosePopup() override; RawPtrWillBeMember<ChromeClientImpl> m_chromeClient; - DateTimeChooserClient* m_client; + RawPtrWillBeMember<DateTimeChooserClient> m_client; PagePopup* m_popup; DateTimeChooserParameters m_parameters; OwnPtr<Locale> m_locale;
diff --git a/third_party/WebKit/Source/web/ExternalDateTimeChooser.cpp b/third_party/WebKit/Source/web/ExternalDateTimeChooser.cpp index b609d71b..bb72787 100644 --- a/third_party/WebKit/Source/web/ExternalDateTimeChooser.cpp +++ b/third_party/WebKit/Source/web/ExternalDateTimeChooser.cpp
@@ -63,23 +63,29 @@ delete this; } - RefPtr<ExternalDateTimeChooser> m_chooser; + RefPtrWillBePersistent<ExternalDateTimeChooser> m_chooser; }; ExternalDateTimeChooser::~ExternalDateTimeChooser() { } +DEFINE_TRACE(ExternalDateTimeChooser) +{ + visitor->trace(m_client); + DateTimeChooser::trace(visitor); +} + ExternalDateTimeChooser::ExternalDateTimeChooser(DateTimeChooserClient* client) : m_client(client) { ASSERT(client); } -PassRefPtr<ExternalDateTimeChooser> ExternalDateTimeChooser::create(ChromeClientImpl* chromeClient, WebViewClient* webViewClient, DateTimeChooserClient* client, const DateTimeChooserParameters& parameters) +PassRefPtrWillBeRawPtr<ExternalDateTimeChooser> ExternalDateTimeChooser::create(ChromeClientImpl* chromeClient, WebViewClient* webViewClient, DateTimeChooserClient* client, const DateTimeChooserParameters& parameters) { ASSERT(chromeClient); - RefPtr<ExternalDateTimeChooser> chooser = adoptRef(new ExternalDateTimeChooser(client)); + RefPtrWillBeRawPtr<ExternalDateTimeChooser> chooser = adoptRefWillBeNoop(new ExternalDateTimeChooser(client)); if (!chooser->openDateTimeChooser(chromeClient, webViewClient, parameters)) chooser.clear(); return chooser.release(); @@ -162,13 +168,13 @@ void ExternalDateTimeChooser::endChooser() { DateTimeChooserClient* client = m_client; - m_client = 0; + m_client = nullptr; client->didEndChooser(); } AXObject* ExternalDateTimeChooser::rootAXObject() { - return 0; + return nullptr; } } // namespace blink
diff --git a/third_party/WebKit/Source/web/ExternalDateTimeChooser.h b/third_party/WebKit/Source/web/ExternalDateTimeChooser.h index faa89f73..fcaaf1d 100644 --- a/third_party/WebKit/Source/web/ExternalDateTimeChooser.h +++ b/third_party/WebKit/Source/web/ExternalDateTimeChooser.h
@@ -40,6 +40,7 @@ public: static PassRefPtrWillBeRawPtr<ExternalDateTimeChooser> create(ChromeClientImpl*, WebViewClient*, DateTimeChooserClient*, const DateTimeChooserParameters&); ~ExternalDateTimeChooser() override; + DECLARE_VIRTUAL_TRACE(); // The following functions are for DateTimeChooserCompletion. void didChooseValue(const WebString&); @@ -54,7 +55,7 @@ void endChooser() override; AXObject* rootAXObject() override; - DateTimeChooserClient* m_client; + RawPtrWillBeMember<DateTimeChooserClient> m_client; }; }
diff --git a/ui/gfx/image/image_skia.h b/ui/gfx/image/image_skia.h index 941ebc9f..7bf5e58f 100644 --- a/ui/gfx/image/image_skia.h +++ b/ui/gfx/image/image_skia.h
@@ -33,6 +33,11 @@ // Functions that mutate the image should operate on the gfx::ImageSkiaRep // returned from ImageSkia::GetRepresentation, not on ImageSkia. // +// NOTE: This class should *not* be used to store multiple logical sizes of an +// image (e.g., small, medium and large versions of an icon); use an ImageFamily +// for that. An ImageSkia represents an image of a single logical size, with +// potentially many different densities for high-DPI displays. +// // ImageSkia is cheap to copy and intentionally supports copy semantics. class GFX_EXPORT ImageSkia { public: