File: skia_output_surface_dependency_impl.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (194 lines) | stat: -rw-r--r-- 7,157 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/viz/service/display_embedder/skia_output_surface_dependency_impl.h"

#include <memory>
#include <utility>

#include "base/functional/callback_helpers.h"
#include "base/task/bind_post_task.h"
#include "base/task/single_thread_task_runner.h"
#include "build/build_config.h"
#include "components/viz/service/gl/gpu_service_impl.h"
#include "gpu/command_buffer/service/command_buffer_task_executor.h"
#include "gpu/command_buffer/service/dawn_context_provider.h"
#include "gpu/command_buffer/service/gpu_task_scheduler_helper.h"
#include "gpu/command_buffer/service/scheduler.h"
#include "gpu/command_buffer/service/scheduler_sequence.h"
#include "gpu/config/gpu_finch_features.h"
#include "gpu/ipc/service/image_transport_surface.h"
#include "ui/gl/init/gl_factory.h"

namespace viz {

SkiaOutputSurfaceDependencyImpl::SkiaOutputSurfaceDependencyImpl(
    GpuServiceImpl* gpu_service_impl,
    gpu::SurfaceHandle surface_handle)
    : gpu_service_impl_(gpu_service_impl),
      surface_handle_(surface_handle),
      client_thread_task_runner_(
          base::SingleThreadTaskRunner::GetCurrentDefault()) {}

SkiaOutputSurfaceDependencyImpl::~SkiaOutputSurfaceDependencyImpl() = default;

std::unique_ptr<gpu::SingleTaskSequence>
SkiaOutputSurfaceDependencyImpl::CreateSequence() {
  return std::make_unique<gpu::SchedulerSequence>(
      gpu_service_impl_->GetGpuScheduler(),
      gpu_service_impl_->compositor_gpu_task_runner());
}

gpu::SharedImageManager*
SkiaOutputSurfaceDependencyImpl::GetSharedImageManager() {
  return gpu_service_impl_->shared_image_manager();
}

gpu::SyncPointManager* SkiaOutputSurfaceDependencyImpl::GetSyncPointManager() {
  return gpu_service_impl_->sync_point_manager();
}

const gpu::GpuDriverBugWorkarounds&
SkiaOutputSurfaceDependencyImpl::GetGpuDriverBugWorkarounds() {
  return gpu_service_impl_->gpu_driver_bug_workarounds();
}

scoped_refptr<gpu::SharedContextState>
SkiaOutputSurfaceDependencyImpl::GetSharedContextState() {
  if (gpu_service_impl_->compositor_gpu_thread()) {
    return gpu_service_impl_->compositor_gpu_thread()->GetSharedContextState();
  }
  return gpu_service_impl_->GetContextState();
}

gpu::raster::GrShaderCache*
SkiaOutputSurfaceDependencyImpl::GetGrShaderCache() {
  return gpu_service_impl_->gr_shader_cache();
}

VulkanContextProvider*
SkiaOutputSurfaceDependencyImpl::GetVulkanContextProvider() {
  if (gpu_service_impl_->compositor_gpu_thread()) {
    return gpu_service_impl_->compositor_gpu_thread()
        ->vulkan_context_provider();
  }
  return gpu_service_impl_->vulkan_context_provider();
}

gpu::DawnContextProvider*
SkiaOutputSurfaceDependencyImpl::GetDawnContextProvider() {
  return gpu_service_impl_->dawn_context_provider();
}

const gpu::GpuPreferences& SkiaOutputSurfaceDependencyImpl::GetGpuPreferences()
    const {
  return gpu_service_impl_->gpu_preferences();
}

const gpu::GpuFeatureInfo&
SkiaOutputSurfaceDependencyImpl::GetGpuFeatureInfo() {
  return gpu_service_impl_->gpu_feature_info();
}

bool SkiaOutputSurfaceDependencyImpl::IsOffscreen() {
  return surface_handle_ == gpu::kNullSurfaceHandle;
}

gpu::SurfaceHandle SkiaOutputSurfaceDependencyImpl::GetSurfaceHandle() {
  return surface_handle_;
}

scoped_refptr<gl::Presenter>
SkiaOutputSurfaceDependencyImpl::CreatePresenter() {
  DCHECK(!IsOffscreen());
  auto presenter = gpu::ImageTransportSurface::CreatePresenter(
      GetSharedContextState(), GetGpuDriverBugWorkarounds(),
      GetGpuFeatureInfo(), surface_handle_);
  if (presenter &&
      base::FeatureList::IsEnabled(features::kHandleOverlaysSwapFailure)) {
    presenter->SetNotifyNonSimpleOverlayFailure();
  }
  return presenter;
}

scoped_refptr<gl::GLSurface> SkiaOutputSurfaceDependencyImpl::CreateGLSurface(
    gl::GLSurfaceFormat format) {
  CHECK(!IsOffscreen());
  return gpu::ImageTransportSurface::CreateNativeGLSurface(
      GetSharedContextState()->display(), surface_handle_, format);
}

#if BUILDFLAG(IS_ANDROID)
base::ScopedClosureRunner SkiaOutputSurfaceDependencyImpl::CachePresenter(
    gl::Presenter* presenter) {
  // We're running on the viz thread here. We want to release ref on the
  // compositor gpu thread because presenters are generally not thread-safe. For
  // the same reason we don't want to mark them as RefCountedThreadSafe to avoid
  // confusion and so have to AddRef() on the compositor gpu thread too. It's
  // safe to just PostTask here because SkiaOutputSurfaceImplOnGpu keeps ref on
  // its Presenter and can be only destroyed by PostTask from viz thread to gpu
  // thread which will run after this one.
  gpu_service_impl_->compositor_gpu_task_runner()->PostTask(
      FROM_HERE,
      base::BindOnce(&gl::Presenter::AddRef, base::Unretained(presenter)));

  auto release_callback = base::BindPostTask(
      gpu_service_impl_->compositor_gpu_task_runner(),
      base::BindOnce(&gl::Presenter::Release, base::Unretained(presenter)));

  return base::ScopedClosureRunner(std::move(release_callback));
}

base::ScopedClosureRunner SkiaOutputSurfaceDependencyImpl::CacheGLSurface(
    gl::GLSurface* surface) {
  // We're running on the viz thread here. We want to release ref on the
  // compositor gpu thread because presenters are generally not thread-safe. For
  // the same reason we don't want to mark them as RefCountedThreadSafe to avoid
  // confusion and so have to AddRef() on the compositor gpu thread too. It's
  // safe to just PostTask here because SkiaOutputSurfaceImplOnGpu keeps ref on
  // its GLSurface and can be only destroyed by PostTask from viz thread to gpu
  // thread which will run after this one.
  gpu_service_impl_->compositor_gpu_task_runner()->PostTask(
      FROM_HERE,
      base::BindOnce(&gl::GLSurface::AddRef, base::Unretained(surface)));

  auto release_callback = base::BindPostTask(
      gpu_service_impl_->compositor_gpu_task_runner(),
      base::BindOnce(&gl::GLSurface::Release, base::Unretained(surface)));

  return base::ScopedClosureRunner(std::move(release_callback));
}
#endif

scoped_refptr<base::SingleThreadTaskRunner>
SkiaOutputSurfaceDependencyImpl::GetClientTaskRunner() {
  return client_thread_task_runner_;
}

void SkiaOutputSurfaceDependencyImpl::ScheduleGrContextCleanup() {
  GetSharedContextState()->ScheduleSkiaCleanup();
}

void SkiaOutputSurfaceDependencyImpl::ScheduleDelayedGPUTaskFromGPUThread(
    base::OnceClosure task) {
  constexpr base::TimeDelta kDelayForDelayedWork = base::Milliseconds(2);
  gpu_service_impl_->compositor_gpu_task_runner()->PostDelayedTask(
      FROM_HERE, std::move(task), kDelayForDelayedWork);
}

void SkiaOutputSurfaceDependencyImpl::DidLoseContext(
    gpu::error::ContextLostReason reason,
    const GURL& active_url) {
  gpu_service_impl_->DidLoseContext(reason, active_url);
}

bool SkiaOutputSurfaceDependencyImpl::NeedsSupportForExternalStencil() {
  return false;
}

bool SkiaOutputSurfaceDependencyImpl::IsUsingCompositorGpuThread() {
  return !!gpu_service_impl_->compositor_gpu_thread();
}

}  // namespace viz