1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "flutter/shell/common/shell_io_manager.h"
6
7 #include "flutter/fml/message_loop.h"
8 #include "flutter/shell/common/persistent_cache.h"
9 #include "third_party/skia/include/gpu/gl/GrGLInterface.h"
10
11 namespace flutter {
12
CreateCompatibleResourceLoadingContext(GrBackend backend,sk_sp<const GrGLInterface> gl_interface)13 sk_sp<GrContext> ShellIOManager::CreateCompatibleResourceLoadingContext(
14 GrBackend backend,
15 sk_sp<const GrGLInterface> gl_interface) {
16 if (backend != GrBackend::kOpenGL_GrBackend) {
17 return nullptr;
18 }
19
20 GrContextOptions options = {};
21
22 options.fPersistentCache = PersistentCache::GetCacheForProcess();
23
24 // There is currently a bug with doing GPU YUV to RGB conversions on the IO
25 // thread. The necessary work isn't being flushed or synchronized with the
26 // other threads correctly, so the textures end up blank. For now, suppress
27 // that feature, which will cause texture uploads to do CPU YUV conversion.
28 // A similar work-around is also used in shell/gpu/gpu_surface_gl.cc.
29 options.fDisableGpuYUVConversion = true;
30
31 // To get video playback on the widest range of devices, we limit Skia to
32 // ES2 shading language when the ES3 external image extension is missing.
33 options.fPreferExternalImagesOverES3 = true;
34
35 if (auto context = GrContext::MakeGL(gl_interface, options)) {
36 // Do not cache textures created by the image decoder. These textures
37 // should be deleted when they are no longer referenced by an SkImage.
38 context->setResourceCacheLimits(0, 0);
39 return context;
40 }
41
42 return nullptr;
43 }
44
ShellIOManager(sk_sp<GrContext> resource_context,fml::RefPtr<fml::TaskRunner> unref_queue_task_runner)45 ShellIOManager::ShellIOManager(
46 sk_sp<GrContext> resource_context,
47 fml::RefPtr<fml::TaskRunner> unref_queue_task_runner)
48 : resource_context_(std::move(resource_context)),
49 resource_context_weak_factory_(
50 resource_context_ ? std::make_unique<fml::WeakPtrFactory<GrContext>>(
51 resource_context_.get())
52 : nullptr),
53 unref_queue_(fml::MakeRefCounted<flutter::SkiaUnrefQueue>(
54 std::move(unref_queue_task_runner),
55 fml::TimeDelta::FromMilliseconds(50))),
56 weak_factory_(this) {
57 if (!resource_context_) {
58 #ifndef OS_FUCHSIA
59 FML_DLOG(WARNING) << "The IO manager was initialized without a resource "
60 "context. Async texture uploads will be disabled. "
61 "Expect performance degradation.";
62 #endif // OS_FUCHSIA
63 }
64 }
65
~ShellIOManager()66 ShellIOManager::~ShellIOManager() {
67 // Last chance to drain the IO queue as the platform side reference to the
68 // underlying OpenGL context may be going away.
69 unref_queue_->Drain(true);
70 }
71
NotifyResourceContextAvailable(sk_sp<GrContext> resource_context)72 void ShellIOManager::NotifyResourceContextAvailable(
73 sk_sp<GrContext> resource_context) {
74 // The resource context needs to survive as long as we have Dart objects
75 // referencing. We shouldn't ever need to replace it if we have one - unless
76 // we've somehow shut down the Dart VM and started a new one fresh.
77 if (!resource_context_) {
78 UpdateResourceContext(std::move(resource_context));
79 }
80 }
81
UpdateResourceContext(sk_sp<GrContext> resource_context)82 void ShellIOManager::UpdateResourceContext(sk_sp<GrContext> resource_context) {
83 resource_context_ = std::move(resource_context);
84 resource_context_weak_factory_ =
85 resource_context_ ? std::make_unique<fml::WeakPtrFactory<GrContext>>(
86 resource_context_.get())
87 : nullptr;
88 }
89
GetWeakPtr()90 fml::WeakPtr<ShellIOManager> ShellIOManager::GetWeakPtr() {
91 return weak_factory_.GetWeakPtr();
92 }
93
94 // |IOManager|
GetResourceContext() const95 fml::WeakPtr<GrContext> ShellIOManager::GetResourceContext() const {
96 return resource_context_weak_factory_
97 ? resource_context_weak_factory_->GetWeakPtr()
98 : fml::WeakPtr<GrContext>();
99 }
100
101 // |IOManager|
GetSkiaUnrefQueue() const102 fml::RefPtr<flutter::SkiaUnrefQueue> ShellIOManager::GetSkiaUnrefQueue() const {
103 return unref_queue_;
104 }
105
106 // |IOManager|
GetWeakIOManager() const107 fml::WeakPtr<IOManager> ShellIOManager::GetWeakIOManager() const {
108 return weak_factory_.GetWeakPtr();
109 }
110
111 } // namespace flutter
112