Adlai Holler e5614964f4 Use the GrDirectContext factories instead of deprecated GrContext ones (flutter/engine#19962)
This is part of a larger effort to expose the difference between GrDirectContext,
which runs on the GPU thread and can directly perform operations like uploading
textures, and GrRecordingContext, which can only queue up work to be delivered
to the GrDirectContext later.
2020-07-28 13:32:09 -07:00

133 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/shell_io_manager.h"
#include "flutter/fml/build_config.h"
#include "flutter/fml/message_loop.h"
#include "flutter/shell/common/persistent_cache.h"
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
namespace flutter {
sk_sp<GrDirectContext> ShellIOManager::CreateCompatibleResourceLoadingContext(
GrBackend backend,
sk_sp<const GrGLInterface> gl_interface) {
if (backend != GrBackend::kOpenGL_GrBackend) {
return nullptr;
}
GrContextOptions options = {};
if (PersistentCache::cache_sksl()) {
FML_LOG(INFO) << "Cache SkSL";
options.fShaderCacheStrategy = GrContextOptions::ShaderCacheStrategy::kSkSL;
}
PersistentCache::MarkStrategySet();
options.fPersistentCache = PersistentCache::GetCacheForProcess();
// There is currently a bug with doing GPU YUV to RGB conversions on the IO
// thread. The necessary work isn't being flushed or synchronized with the
// other threads correctly, so the textures end up blank. For now, suppress
// that feature, which will cause texture uploads to do CPU YUV conversion.
// A similar work-around is also used in shell/gpu/gpu_surface_gl.cc.
options.fDisableGpuYUVConversion = true;
// To get video playback on the widest range of devices, we limit Skia to
// ES2 shading language when the ES3 external image extension is missing.
options.fPreferExternalImagesOverES3 = true;
#if !OS_FUCHSIA
if (auto context = GrDirectContext::MakeGL(gl_interface, options)) {
// Do not cache textures created by the image decoder. These textures
// should be deleted when they are no longer referenced by an SkImage.
context->setResourceCacheLimits(0, 0);
return context;
}
#endif
return nullptr;
}
ShellIOManager::ShellIOManager(
sk_sp<GrDirectContext> resource_context,
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch,
fml::RefPtr<fml::TaskRunner> unref_queue_task_runner)
: resource_context_(std::move(resource_context)),
resource_context_weak_factory_(
resource_context_
? std::make_unique<fml::WeakPtrFactory<GrDirectContext>>(
resource_context_.get())
: nullptr),
unref_queue_(fml::MakeRefCounted<flutter::SkiaUnrefQueue>(
std::move(unref_queue_task_runner),
fml::TimeDelta::FromMilliseconds(8),
GetResourceContext())),
weak_factory_(this),
is_gpu_disabled_sync_switch_(is_gpu_disabled_sync_switch) {
if (!resource_context_) {
#ifndef OS_FUCHSIA
FML_DLOG(WARNING) << "The IO manager was initialized without a resource "
"context. Async texture uploads will be disabled. "
"Expect performance degradation.";
#endif // OS_FUCHSIA
}
}
ShellIOManager::~ShellIOManager() {
// Last chance to drain the IO queue as the platform side reference to the
// underlying OpenGL context may be going away.
is_gpu_disabled_sync_switch_->Execute(
fml::SyncSwitch::Handlers().SetIfFalse([&] { unref_queue_->Drain(); }));
}
void ShellIOManager::NotifyResourceContextAvailable(
sk_sp<GrDirectContext> resource_context) {
// The resource context needs to survive as long as we have Dart objects
// referencing. We shouldn't ever need to replace it if we have one - unless
// we've somehow shut down the Dart VM and started a new one fresh.
if (!resource_context_) {
UpdateResourceContext(std::move(resource_context));
}
}
void ShellIOManager::UpdateResourceContext(
sk_sp<GrDirectContext> resource_context) {
resource_context_ = std::move(resource_context);
resource_context_weak_factory_ =
resource_context_
? std::make_unique<fml::WeakPtrFactory<GrDirectContext>>(
resource_context_.get())
: nullptr;
}
fml::WeakPtr<ShellIOManager> ShellIOManager::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
// |IOManager|
fml::WeakPtr<GrDirectContext> ShellIOManager::GetResourceContext() const {
return resource_context_weak_factory_
? resource_context_weak_factory_->GetWeakPtr()
: fml::WeakPtr<GrDirectContext>();
}
// |IOManager|
fml::RefPtr<flutter::SkiaUnrefQueue> ShellIOManager::GetSkiaUnrefQueue() const {
return unref_queue_;
}
// |IOManager|
fml::WeakPtr<IOManager> ShellIOManager::GetWeakIOManager() const {
return weak_factory_.GetWeakPtr();
}
// |IOManager|
std::shared_ptr<fml::SyncSwitch> ShellIOManager::GetIsGpuDisabledSyncSwitch() {
return is_gpu_disabled_sync_switch_;
}
} // namespace flutter