[go: nahoru, domu]

blob: da9ab77796765c0992fb75b68dde82c07cc44a28 [file] [log] [blame]
Bo Liue0e51f22023-02-02 19:33:001// Copyright 2023 The Chromium Authors
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 "cc/slim/frame_sink_impl.h"
6
7#include <string>
8#include <utility>
9#include <vector>
10
11#include "base/check.h"
12#include "base/containers/flat_set.h"
13#include "base/functional/bind.h"
14#include "base/threading/platform_thread.h"
15#include "base/trace_event/trace_event.h"
Aman Vermab5f203c2023-07-31 18:32:4116#include "base/trace_event/typed_macros.h"
Bo Liue0e51f22023-02-02 19:33:0017#include "build/build_config.h"
Bo Liuf5bd17342023-03-10 17:55:4518#include "cc/slim/constants.h"
Bo Liu11af9412023-04-05 19:49:3919#include "cc/slim/delayed_scheduler.h"
Bo Liue0e51f22023-02-02 19:33:0020#include "cc/slim/frame_sink_impl_client.h"
Jonathan Rossd3117112023-02-17 16:42:0921#include "components/viz/common/features.h"
Bo Liu677cece2023-03-07 17:44:1322#include "components/viz/common/quads/compositor_frame.h"
Bo Liue0e51f22023-02-02 19:33:0023#include "components/viz/common/resources/platform_color.h"
Bo Liu873d13e32023-02-08 15:58:4224#include "components/viz/common/resources/resource_id.h"
Colin Blundell6828da72023-02-13 18:07:3325#include "components/viz/common/resources/shared_image_format.h"
Colin Blundell81fb20ca2023-05-30 09:37:5426#include "components/viz/common/resources/shared_image_format_utils.h"
Bo Liu677cece2023-03-07 17:44:1327#include "components/viz/common/resources/transferable_resource.h"
Bo Liue0e51f22023-02-02 19:33:0028#include "gpu/command_buffer/client/shared_image_interface.h"
29#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
30#include "gpu/command_buffer/common/shared_image_usage.h"
31#include "third_party/skia/include/core/SkAlphaType.h"
32#include "third_party/skia/include/gpu/GrTypes.h"
33#include "ui/gfx/buffer_types.h"
34#include "ui/gfx/color_space.h"
35
36namespace cc::slim {
37
38FrameSinkImpl::UploadedUIResource::UploadedUIResource() = default;
39FrameSinkImpl::UploadedUIResource::~UploadedUIResource() = default;
40FrameSinkImpl::UploadedUIResource::UploadedUIResource(
41 const UploadedUIResource&) = default;
42FrameSinkImpl::UploadedUIResource& FrameSinkImpl::UploadedUIResource::operator=(
43 const UploadedUIResource&) = default;
44
45FrameSinkImpl::FrameSinkImpl(
46 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
47 mojo::PendingAssociatedRemote<viz::mojom::CompositorFrameSink>
48 compositor_frame_sink_associated_remote,
49 mojo::PendingReceiver<viz::mojom::CompositorFrameSinkClient>
50 client_receiver,
kylecharffcf0912023-06-09 18:57:2251 scoped_refptr<viz::RasterContextProvider> context_provider,
Bo Liu3380083a2023-03-22 16:11:0452 base::PlatformThreadId io_thread_id,
53 std::unique_ptr<Scheduler> scheduler)
Bo Liue0e51f22023-02-02 19:33:0054 : task_runner_(std::move(task_runner)),
Bo Liu3380083a2023-03-22 16:11:0455 scheduler_(std::move(scheduler)),
Bo Liue0e51f22023-02-02 19:33:0056 pending_compositor_frame_sink_associated_remote_(
57 std::move(compositor_frame_sink_associated_remote)),
58 pending_client_receiver_(std::move(client_receiver)),
Michael Thiessenc8842d02023-02-16 17:06:0259 context_provider_(std::move(context_provider)),
Bo Liu3380083a2023-03-22 16:11:0460 io_thread_id_(io_thread_id) {
61 scheduler_->Initialize(this);
62}
Bo Liue0e51f22023-02-02 19:33:0063
64FrameSinkImpl::~FrameSinkImpl() {
Bo Liu9d07e212023-02-27 17:13:3765 // Iterate a copy of `uploaded_resources_` since it might be modified
66 // when `UIResourceReleased()` is called.
67 for (const auto& uploaded_resource_pair :
68 UploadedResourceMap(uploaded_resources_)) {
Bo Liu84fe45d2023-02-21 16:33:3769 resource_provider_.RemoveImportedResource(
70 uploaded_resource_pair.second.viz_resource_id);
71 }
Bo Liue0e51f22023-02-02 19:33:0072 resource_provider_.ShutdownAndReleaseAllResources();
73}
74
75void FrameSinkImpl::SetLocalSurfaceId(
76 const viz::LocalSurfaceId& local_surface_id) {
77 if (local_surface_id_ == local_surface_id) {
78 return;
79 }
80 local_surface_id_ = local_surface_id;
81 hit_test_region_list_.reset();
82}
83
84bool FrameSinkImpl::BindToClient(FrameSinkImplClient* client) {
85 DCHECK(client);
86 if (context_provider_) {
87 context_provider_->AddObserver(this);
88 auto result = context_provider_->BindToCurrentSequence();
89 if (result != gpu::ContextResult::kSuccess) {
90 context_provider_->RemoveObserver(this);
91 context_provider_ = nullptr;
92 return false;
93 }
94 }
95
96 client_ = client;
97
98 frame_sink_remote_.Bind(
99 std::move(pending_compositor_frame_sink_associated_remote_));
100 frame_sink_remote_.set_disconnect_handler(
101 base::BindOnce(&FrameSinkImpl::OnContextLost, base::Unretained(this)));
102 client_receiver_.Bind(std::move(pending_client_receiver_), task_runner_);
103
Bo Liubfe80a072023-02-17 20:09:15104 frame_sink_ = frame_sink_remote_.get();
105 frame_sink_->InitializeCompositorFrameSinkType(
Bo Liue0e51f22023-02-02 19:33:00106 viz::mojom::CompositorFrameSinkType::kLayerTree);
107
108#if BUILDFLAG(IS_ANDROID)
109 std::vector<int32_t> thread_ids;
110 thread_ids.push_back(base::PlatformThread::CurrentId());
Michael Thiessenc8842d02023-02-16 17:06:02111 if (io_thread_id_ != base::kInvalidThreadId) {
112 thread_ids.push_back(io_thread_id_);
113 }
Bo Liubfe80a072023-02-17 20:09:15114 frame_sink_->SetThreadIds(thread_ids);
Bo Liue0e51f22023-02-02 19:33:00115#endif
116 return true;
117}
118
119void FrameSinkImpl::OnContextLost() {
120 client_->DidLoseLayerTreeFrameSink();
121}
122
123void FrameSinkImpl::SetNeedsBeginFrame(bool needs_begin_frame) {
124 if (needs_begin_frame_ == needs_begin_frame) {
125 return;
126 }
127 needs_begin_frame_ = needs_begin_frame;
Bo Liu11af9412023-04-05 19:49:39128 scheduler_->SetNeedsBeginFrame(needs_begin_frame);
Bo Liubfe80a072023-02-17 20:09:15129 frame_sink_->SetNeedsBeginFrame(needs_begin_frame);
Bo Liue0e51f22023-02-02 19:33:00130}
131
Bo Liu11af9412023-04-05 19:49:39132void FrameSinkImpl::MaybeCompositeNow() {
133 scheduler_->MaybeCompositeNow();
134}
135
Bo Liue0e51f22023-02-02 19:33:00136void FrameSinkImpl::UploadUIResource(cc::UIResourceId resource_id,
137 cc::UIResourceBitmap resource_bitmap) {
Bo Liue0e51f22023-02-02 19:33:00138 gfx::Size size = resource_bitmap.GetSize();
Bo Liue54865a2023-05-01 17:52:48139 TRACE_EVENT1("cc", "slim::FrameSinkImpl::UploadUIResource", "size",
140 size.ToString());
141 const gpu::Capabilities& caps = context_provider_->ContextCapabilities();
Bo Liue0e51f22023-02-02 19:33:00142 if (size.width() > caps.max_texture_size ||
143 size.height() > caps.max_texture_size) {
144 LOG(ERROR) << "Size exceeds max texture size";
145 return;
146 }
Colin Blundell836bf252023-02-15 08:33:58147 viz::SharedImageFormat format = viz::SinglePlaneFormat::kRGBA_8888;
Bo Liue0e51f22023-02-02 19:33:00148 switch (resource_bitmap.GetFormat()) {
149 case cc::UIResourceBitmap::RGBA8:
Colin Blundell836bf252023-02-15 08:33:58150 format = viz::PlatformColor::BestSupportedTextureFormat(caps);
Bo Liue0e51f22023-02-02 19:33:00151 break;
152 case cc::UIResourceBitmap::ALPHA_8:
Colin Blundell836bf252023-02-15 08:33:58153 format = viz::SinglePlaneFormat::kALPHA_8;
Bo Liue0e51f22023-02-02 19:33:00154 break;
155 case cc::UIResourceBitmap::ETC1:
Colin Blundell836bf252023-02-15 08:33:58156 format = viz::SinglePlaneFormat::kETC1;
Bo Liue0e51f22023-02-02 19:33:00157 break;
158 }
159
160 UploadedUIResource uploaded_resource;
161 auto* sii = context_provider_->SharedImageInterface();
162 constexpr gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB();
163 uint32_t shared_image_usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;
164 uploaded_resource.mailbox = sii->CreateSharedImage(
Colin Blundell836bf252023-02-15 08:33:58165 format, resource_bitmap.GetSize(), color_space, kTopLeft_GrSurfaceOrigin,
Rafael Cintronde3d9b82023-04-19 20:19:28166 kPremul_SkAlphaType, shared_image_usage, "SlimCompositorUIResource",
Bo Liue0e51f22023-02-02 19:33:00167 base::span<const uint8_t>(resource_bitmap.GetPixels(),
168 resource_bitmap.SizeInBytes()));
169 gpu::SyncToken sync_token = sii->GenUnverifiedSyncToken();
170
171 GLenum texture_target = gpu::GetBufferTextureTarget(
Colin Blundell81fb20ca2023-05-30 09:37:54172 gfx::BufferUsage::SCANOUT,
173 viz::SinglePlaneSharedImageFormatToBufferFormat(format), caps);
Bo Liue0e51f22023-02-02 19:33:00174 uploaded_resource.viz_resource_id = resource_provider_.ImportResource(
175 viz::TransferableResource::MakeGpu(
kylechar35a372d2023-04-25 16:05:17176 uploaded_resource.mailbox, texture_target, sync_token,
Jonathan Ross5914b992023-09-28 15:30:53177 resource_bitmap.GetSize(), format, /*is_overlay_candidate=*/false,
178 viz::TransferableResource::ResourceSource::kUI),
Bo Liue0e51f22023-02-02 19:33:00179 base::BindOnce(&FrameSinkImpl::UIResourceReleased, base::Unretained(this),
180 resource_id));
181 uploaded_resource.size = resource_bitmap.GetSize();
182 uploaded_resource.is_opaque = resource_bitmap.GetOpaque();
183
Bo Liu9d07e212023-02-27 17:13:37184 DCHECK(!uploaded_resources_.contains(resource_id));
Bo Liue0e51f22023-02-02 19:33:00185 uploaded_resources_.emplace(resource_id, uploaded_resource);
186}
187
188void FrameSinkImpl::UIResourceReleased(cc::UIResourceId ui_resource_id,
189 const gpu::SyncToken& sync_token,
190 bool is_lost) {
191 auto itr = uploaded_resources_.find(ui_resource_id);
192 DCHECK(itr != uploaded_resources_.end());
193 auto* sii = context_provider_->SharedImageInterface();
194 sii->DestroySharedImage(sync_token, itr->second.mailbox);
195 uploaded_resources_.erase(itr);
196}
197
198void FrameSinkImpl::MarkUIResourceForDeletion(cc::UIResourceId resource_id) {
199 auto itr = uploaded_resources_.find(resource_id);
200 if (itr == uploaded_resources_.end()) {
201 return;
202 }
203 resource_provider_.RemoveImportedResource(itr->second.viz_resource_id);
204}
205
Bo Liu873d13e32023-02-08 15:58:42206viz::ResourceId FrameSinkImpl::GetVizResourceId(cc::UIResourceId resource_id) {
207 auto itr = uploaded_resources_.find(resource_id);
208 if (itr == uploaded_resources_.end()) {
209 return viz::kInvalidResourceId;
210 }
211 return itr->second.viz_resource_id;
Bo Liue0e51f22023-02-02 19:33:00212}
213
214bool FrameSinkImpl::IsUIResourceOpaque(cc::UIResourceId resource_id) {
215 auto it = uploaded_resources_.find(resource_id);
216 if (it == uploaded_resources_.end()) {
217 return true;
218 }
219 return it->second.is_opaque;
220}
221
222gfx::Size FrameSinkImpl::GetUIResourceSize(cc::UIResourceId resource_id) {
223 auto it = uploaded_resources_.find(resource_id);
224 if (it == uploaded_resources_.end()) {
225 return gfx::Size();
226 }
227
228 return it->second.size;
229}
230
Bo Liuf5bd17342023-03-10 17:55:45231int FrameSinkImpl::GetMaxTextureSize() const {
232 if (context_provider_) {
233 return context_provider_->ContextCapabilities().max_texture_size;
234 }
235 return kSoftwareMaxTextureSize;
236}
237
Bo Liue0e51f22023-02-02 19:33:00238void FrameSinkImpl::DidReceiveCompositorFrameAck(
239 std::vector<viz::ReturnedResource> resources) {
240 ReclaimResources(std::move(resources));
Bo Liu3380083a2023-03-22 16:11:04241 DCHECK_GT(num_unacked_frames_, 0u);
242 num_unacked_frames_--;
Bo Liu11af9412023-04-05 19:49:39243 if (!num_unacked_frames_) {
244 scheduler_->SetIsSwapThrottled(false);
245 }
Bo Liue0e51f22023-02-02 19:33:00246 client_->DidReceiveCompositorFrameAck();
247}
248
Bo Liu3380083a2023-03-22 16:11:04249void FrameSinkImpl::ReclaimResources(
250 std::vector<viz::ReturnedResource> resources) {
251 resource_provider_.ReceiveReturnsFromParent(std::move(resources));
252}
253
Bo Liue0e51f22023-02-02 19:33:00254void FrameSinkImpl::OnBeginFrame(
255 const viz::BeginFrameArgs& begin_frame_args,
Jonathan Rossd3117112023-02-17 16:42:09256 const viz::FrameTimingDetailsMap& timing_details,
257 bool frame_ack,
258 std::vector<viz::ReturnedResource> resources) {
259 if (features::IsOnBeginFrameAcksEnabled()) {
260 if (frame_ack) {
261 DidReceiveCompositorFrameAck(std::move(resources));
262 } else if (!resources.empty()) {
263 ReclaimResources(std::move(resources));
264 }
265 }
266
Bo Liuc078148b2023-02-22 18:29:22267 // Note order here is expected to be in order w.r.t viz::FrameTokenGT. This
268 // mostly holds because `FrameTimingDetailsMap` is a flat_map which is sorted.
269 // However this doesn't hold when frame token wraps.
Bo Liue0e51f22023-02-02 19:33:00270 for (const auto& pair : timing_details) {
271 client_->DidPresentCompositorFrame(pair.first, pair.second);
272 }
273
Bo Liu3380083a2023-03-22 16:11:04274 scheduler_->OnBeginFrameFromViz(begin_frame_args);
275}
276
277bool FrameSinkImpl::DoBeginFrame(const viz::BeginFrameArgs& begin_frame_args) {
278 if (num_unacked_frames_) {
279 return false;
280 }
281
Bo Liue0e51f22023-02-02 19:33:00282 if (!local_surface_id_.is_valid()) {
Bo Liu3380083a2023-03-22 16:11:04283 return false;
Bo Liue0e51f22023-02-02 19:33:00284 }
285
Bo Liufe5b6212023-04-06 16:56:28286 TRACE_EVENT0("cc", "slim::FrameSinkImpl::DoBeginFrame");
Bo Liue0e51f22023-02-02 19:33:00287 viz::CompositorFrame frame;
Bo Liu873d13e32023-02-08 15:58:42288 base::flat_set<viz::ResourceId> viz_resource_ids;
Bo Liue0e51f22023-02-02 19:33:00289 viz::HitTestRegionList hit_test_region_list;
Bo Liu873d13e32023-02-08 15:58:42290 if (!client_->BeginFrame(begin_frame_args, frame, viz_resource_ids,
Bo Liue0e51f22023-02-02 19:33:00291 hit_test_region_list)) {
Bo Liu3380083a2023-03-22 16:11:04292 return false;
Bo Liue0e51f22023-02-02 19:33:00293 }
294
Bo Liubfe80a072023-02-17 20:09:15295 if (local_surface_id_ == last_submitted_local_surface_id_) {
296 DCHECK_EQ(last_submitted_device_scale_factor_, frame.device_scale_factor());
297 DCHECK_EQ(last_submitted_size_in_pixels_.height(),
298 frame.size_in_pixels().height());
299 DCHECK_EQ(last_submitted_size_in_pixels_.width(),
300 frame.size_in_pixels().width());
301 }
302
Bo Liu873d13e32023-02-08 15:58:42303 resource_provider_.PrepareSendToParent(std::move(viz_resource_ids).extract(),
304 &frame.resource_list,
Bo Liue0e51f22023-02-02 19:33:00305 context_provider_.get());
306
307 bool send_new_hit_test_region_list = false;
308 if (!hit_test_region_list_ ||
309 !viz::HitTestRegionList::IsEqual(*hit_test_region_list_,
310 hit_test_region_list)) {
311 send_new_hit_test_region_list = true;
312 hit_test_region_list_ = std::move(hit_test_region_list);
313 }
314
315 {
Aman Vermab5f203c2023-07-31 18:32:41316 TRACE_EVENT(
Aman Vermae40f10842023-08-09 15:30:19317 "viz,benchmark,graphics.pipeline", "Graphics.Pipeline",
Aman Vermab5f203c2023-07-31 18:32:41318 perfetto::Flow::Global(begin_frame_args.trace_id),
319 [&](perfetto::EventContext ctx) {
320 auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
321 auto* data = event->set_chrome_graphics_pipeline();
322 data->set_step(perfetto::protos::pbzero::ChromeGraphicsPipeline::
323 StepName::STEP_SUBMIT_COMPOSITOR_FRAME);
324 });
Bo Liubfe80a072023-02-17 20:09:15325 frame_sink_->SubmitCompositorFrame(
Bo Liue0e51f22023-02-02 19:33:00326 local_surface_id_, std::move(frame),
327 send_new_hit_test_region_list ? hit_test_region_list_ : absl::nullopt,
328 0);
329 }
Bo Liu3380083a2023-03-22 16:11:04330 num_unacked_frames_++;
Bo Liu11af9412023-04-05 19:49:39331 if (num_unacked_frames_ == 1) {
332 scheduler_->SetIsSwapThrottled(true);
333 }
Bo Liue0e51f22023-02-02 19:33:00334 client_->DidSubmitCompositorFrame();
Bo Liu3380083a2023-03-22 16:11:04335 return true;
Bo Liue0e51f22023-02-02 19:33:00336}
337
Bo Liu3380083a2023-03-22 16:11:04338void FrameSinkImpl::SendDidNotProduceFrame(
339 const viz::BeginFrameArgs& begin_frame_args) {
Aman Vermab5f203c2023-07-31 18:32:41340 TRACE_EVENT(
Aman Vermae40f10842023-08-09 15:30:19341 "viz,benchmark,graphics.pipeline", "Graphics.Pipeline",
Aman Vermab5f203c2023-07-31 18:32:41342 perfetto::Flow::Global(begin_frame_args.trace_id),
343 [&](perfetto::EventContext ctx) {
344 auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
345 auto* data = event->set_chrome_graphics_pipeline();
346 data->set_step(perfetto::protos::pbzero::ChromeGraphicsPipeline::
347 StepName::STEP_DID_NOT_PRODUCE_FRAME);
348 });
Bo Liu3380083a2023-03-22 16:11:04349 frame_sink_->DidNotProduceFrame(viz::BeginFrameAck(begin_frame_args, false));
Bo Liue0e51f22023-02-02 19:33:00350}
351
352} // namespace cc::slim