blob: f1bb540131e79c3ba047f405e856cf4d38011d07 [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 <utility>
#include "flutter/fml/message_loop.h"
#include "flutter/shell/common/context_options.h"
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
namespace flutter {
sk_sp<GrDirectContext> ShellIOManager::CreateCompatibleResourceLoadingContext(
GrBackend backend,
const sk_sp<const GrGLInterface>& gl_interface) {
#if SK_GL
if (backend != GrBackend::kOpenGL_GrBackend) {
return nullptr;
}
const auto options = MakeDefaultContextOptions(ContextType::kResource);
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->setResourceCacheLimit(0);
return context;
}
#endif // SK_GL
return nullptr;
}
ShellIOManager::ShellIOManager(
sk_sp<GrDirectContext> resource_context,
std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
fml::RefPtr<fml::TaskRunner> unref_queue_task_runner,
std::shared_ptr<impeller::Context> impeller_context,
fml::TimeDelta unref_queue_drain_delay)
: 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),
unref_queue_drain_delay,
resource_context_)),
is_gpu_disabled_sync_switch_(std::move(is_gpu_disabled_sync_switch)),
impeller_context_(std::move(impeller_context)),
weak_factory_(this) {
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;
unref_queue_->UpdateResourceContext(resource_context_);
}
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<const fml::SyncSwitch>
ShellIOManager::GetIsGpuDisabledSyncSwitch() {
return is_gpu_disabled_sync_switch_;
}
// |IOManager|
std::shared_ptr<impeller::Context> ShellIOManager::GetImpellerContext() const {
return impeller_context_;
}
} // namespace flutter