flutter_flutter/shell/common/platform_view.cc
liyuqian 9675ca2f6b
Reland "Smooth out iOS irregular input events delivery (#12280)" (#12385)
This reverts commit c2879cae2ee3707ad07af1118bf4862dc1d82bb7.

Additionally, we fix https://github.com/flutter/flutter/issues/40863 by adding a secondary VSYNC callback.

Unit tests are updated to provide VSYNC mocking and check the fix of https://github.com/flutter/flutter/issues/40863.

The root cause of having https://github.com/flutter/flutter/issues/40863 is the false assumption that each input event must trigger a new frame. That was true in the framework PR https://github.com/flutter/flutter/pull/36616 because the input events there are all scrolling move events. When the PR was ported to the engine, we can no longer distinguish different types of events, and tap events may no longer trigger a new frame.

Therefore, this PR directly hooks into the `VsyncWaiter` and uses its (newly added) secondary callback to dispatch the pending input event.
2019-09-30 11:25:50 -07:00

140 lines
4.6 KiB
C++

// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/shell/common/platform_view.h"
#include <utility>
#include "flutter/fml/make_copyable.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/common/shell.h"
#include "flutter/shell/common/vsync_waiter_fallback.h"
#include "third_party/skia/include/gpu/GrContextOptions.h"
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
namespace flutter {
PlatformView::PlatformView(Delegate& delegate, TaskRunners task_runners)
: delegate_(delegate),
task_runners_(std::move(task_runners)),
size_(SkISize::Make(0, 0)),
weak_factory_(this) {}
PlatformView::~PlatformView() = default;
std::unique_ptr<VsyncWaiter> PlatformView::CreateVSyncWaiter() {
FML_DLOG(WARNING)
<< "This platform does not provide a Vsync waiter implementation. A "
"simple timer based fallback is being used.";
return std::make_unique<VsyncWaiterFallback>(task_runners_);
}
void PlatformView::DispatchPlatformMessage(
fml::RefPtr<PlatformMessage> message) {
delegate_.OnPlatformViewDispatchPlatformMessage(std::move(message));
}
void PlatformView::DispatchPointerDataPacket(
std::unique_ptr<PointerDataPacket> packet) {
delegate_.OnPlatformViewDispatchPointerDataPacket(std::move(packet));
}
void PlatformView::DispatchSemanticsAction(int32_t id,
SemanticsAction action,
std::vector<uint8_t> args) {
delegate_.OnPlatformViewDispatchSemanticsAction(id, action, std::move(args));
}
void PlatformView::SetSemanticsEnabled(bool enabled) {
delegate_.OnPlatformViewSetSemanticsEnabled(enabled);
}
void PlatformView::SetAccessibilityFeatures(int32_t flags) {
delegate_.OnPlatformViewSetAccessibilityFeatures(flags);
}
void PlatformView::SetViewportMetrics(const ViewportMetrics& metrics) {
delegate_.OnPlatformViewSetViewportMetrics(metrics);
}
void PlatformView::NotifyCreated() {
std::unique_ptr<Surface> surface;
// Threading: We want to use the platform view on the non-platform thread.
// Using the weak pointer is illegal. But, we are going to introduce a latch
// so that the platform view is not collected till the surface is obtained.
auto* platform_view = this;
fml::ManualResetWaitableEvent latch;
fml::TaskRunner::RunNowOrPostTask(
task_runners_.GetGPUTaskRunner(), [platform_view, &surface, &latch]() {
surface = platform_view->CreateRenderingSurface();
latch.Signal();
});
latch.Wait();
delegate_.OnPlatformViewCreated(std::move(surface));
}
void PlatformView::NotifyDestroyed() {
delegate_.OnPlatformViewDestroyed();
}
sk_sp<GrContext> PlatformView::CreateResourceContext() const {
FML_DLOG(WARNING) << "This platform does not setup the resource "
"context on the IO thread for async texture uploads.";
return nullptr;
}
void PlatformView::ReleaseResourceContext() const {}
PointerDataDispatcherMaker PlatformView::GetDispatcherMaker() {
return [](DefaultPointerDataDispatcher::Delegate& delegate) {
return std::make_unique<DefaultPointerDataDispatcher>(delegate);
};
}
fml::WeakPtr<PlatformView> PlatformView::GetWeakPtr() const {
return weak_factory_.GetWeakPtr();
}
void PlatformView::UpdateSemantics(SemanticsNodeUpdates update,
CustomAccessibilityActionUpdates actions) {}
void PlatformView::HandlePlatformMessage(fml::RefPtr<PlatformMessage> message) {
if (auto response = message->response())
response->CompleteEmpty();
}
void PlatformView::OnPreEngineRestart() const {}
void PlatformView::RegisterTexture(std::shared_ptr<flutter::Texture> texture) {
delegate_.OnPlatformViewRegisterTexture(std::move(texture));
}
void PlatformView::UnregisterTexture(int64_t texture_id) {
delegate_.OnPlatformViewUnregisterTexture(texture_id);
}
void PlatformView::MarkTextureFrameAvailable(int64_t texture_id) {
delegate_.OnPlatformViewMarkTextureFrameAvailable(texture_id);
}
std::unique_ptr<Surface> PlatformView::CreateRenderingSurface() {
// We have a default implementation because tests create a platform view but
// never a rendering surface.
FML_DCHECK(false) << "This platform does not provide a rendering surface but "
"it was notified of surface rendering surface creation.";
return nullptr;
}
void PlatformView::SetNextFrameCallback(fml::closure closure) {
if (!closure) {
return;
}
delegate_.OnPlatformViewSetNextFrameCallback(std::move(closure));
}
} // namespace flutter