blob: 97badd40bb25b559704959c28733e5d316c4f913 [file] [log] [blame]
// 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<GrContext> 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 = GrContext::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<GrContext> 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<GrContext>>(
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<GrContext> 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<GrContext> resource_context) {
resource_context_ = std::move(resource_context);
resource_context_weak_factory_ =
resource_context_ ? std::make_unique<fml::WeakPtrFactory<GrContext>>(
resource_context_.get())
: nullptr;
}
fml::WeakPtr<ShellIOManager> ShellIOManager::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
// |IOManager|
fml::WeakPtr<GrContext> ShellIOManager::GetResourceContext() const {
return resource_context_weak_factory_
? resource_context_weak_factory_->GetWeakPtr()
: fml::WeakPtr<GrContext>();
}
// |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