[go: nahoru, domu]

blob: d6410b8ac5e3017934f5e56c1ccc34abeabbd59f [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"
Mingjing Zhang65eedcc2023-10-24 15:12:4228#include "gpu/command_buffer/client/client_shared_image.h"
Bo Liue0e51f22023-02-02 19:33:0029#include "gpu/command_buffer/client/shared_image_interface.h"
30#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
31#include "gpu/command_buffer/common/shared_image_usage.h"
32#include "third_party/skia/include/core/SkAlphaType.h"
33#include "third_party/skia/include/gpu/GrTypes.h"
34#include "ui/gfx/buffer_types.h"
35#include "ui/gfx/color_space.h"
36
37namespace cc::slim {
38
39FrameSinkImpl::UploadedUIResource::UploadedUIResource() = default;
40FrameSinkImpl::UploadedUIResource::~UploadedUIResource() = default;
41FrameSinkImpl::UploadedUIResource::UploadedUIResource(
42 const UploadedUIResource&) = default;
43FrameSinkImpl::UploadedUIResource& FrameSinkImpl::UploadedUIResource::operator=(
44 const UploadedUIResource&) = default;
45
46FrameSinkImpl::FrameSinkImpl(
47 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
48 mojo::PendingAssociatedRemote<viz::mojom::CompositorFrameSink>
49 compositor_frame_sink_associated_remote,
50 mojo::PendingReceiver<viz::mojom::CompositorFrameSinkClient>
51 client_receiver,
kylecharffcf0912023-06-09 18:57:2252 scoped_refptr<viz::RasterContextProvider> context_provider,
Bo Liu3380083a2023-03-22 16:11:0453 base::PlatformThreadId io_thread_id,
54 std::unique_ptr<Scheduler> scheduler)
Bo Liue0e51f22023-02-02 19:33:0055 : task_runner_(std::move(task_runner)),
Bo Liu3380083a2023-03-22 16:11:0456 scheduler_(std::move(scheduler)),
Bo Liue0e51f22023-02-02 19:33:0057 pending_compositor_frame_sink_associated_remote_(
58 std::move(compositor_frame_sink_associated_remote)),
59 pending_client_receiver_(std::move(client_receiver)),
Michael Thiessenc8842d02023-02-16 17:06:0260 context_provider_(std::move(context_provider)),
Bo Liu3380083a2023-03-22 16:11:0461 io_thread_id_(io_thread_id) {
62 scheduler_->Initialize(this);
63}
Bo Liue0e51f22023-02-02 19:33:0064
65FrameSinkImpl::~FrameSinkImpl() {
Bo Liu9d07e212023-02-27 17:13:3766 // Iterate a copy of `uploaded_resources_` since it might be modified
67 // when `UIResourceReleased()` is called.
68 for (const auto& uploaded_resource_pair :
69 UploadedResourceMap(uploaded_resources_)) {
Bo Liu84fe45d2023-02-21 16:33:3770 resource_provider_.RemoveImportedResource(
71 uploaded_resource_pair.second.viz_resource_id);
72 }
Bo Liue0e51f22023-02-02 19:33:0073 resource_provider_.ShutdownAndReleaseAllResources();
74}
75
76void FrameSinkImpl::SetLocalSurfaceId(
77 const viz::LocalSurfaceId& local_surface_id) {
78 if (local_surface_id_ == local_surface_id) {
79 return;
80 }
81 local_surface_id_ = local_surface_id;
82 hit_test_region_list_.reset();
83}
84
85bool FrameSinkImpl::BindToClient(FrameSinkImplClient* client) {
86 DCHECK(client);
87 if (context_provider_) {
88 context_provider_->AddObserver(this);
89 auto result = context_provider_->BindToCurrentSequence();
90 if (result != gpu::ContextResult::kSuccess) {
91 context_provider_->RemoveObserver(this);
92 context_provider_ = nullptr;
93 return false;
94 }
95 }
96
97 client_ = client;
98
99 frame_sink_remote_.Bind(
100 std::move(pending_compositor_frame_sink_associated_remote_));
101 frame_sink_remote_.set_disconnect_handler(
102 base::BindOnce(&FrameSinkImpl::OnContextLost, base::Unretained(this)));
103 client_receiver_.Bind(std::move(pending_client_receiver_), task_runner_);
104
Bo Liubfe80a072023-02-17 20:09:15105 frame_sink_ = frame_sink_remote_.get();
106 frame_sink_->InitializeCompositorFrameSinkType(
Bo Liue0e51f22023-02-02 19:33:00107 viz::mojom::CompositorFrameSinkType::kLayerTree);
108
109#if BUILDFLAG(IS_ANDROID)
110 std::vector<int32_t> thread_ids;
111 thread_ids.push_back(base::PlatformThread::CurrentId());
Michael Thiessenc8842d02023-02-16 17:06:02112 if (io_thread_id_ != base::kInvalidThreadId) {
113 thread_ids.push_back(io_thread_id_);
114 }
Bo Liubfe80a072023-02-17 20:09:15115 frame_sink_->SetThreadIds(thread_ids);
Bo Liue0e51f22023-02-02 19:33:00116#endif
117 return true;
118}
119
120void FrameSinkImpl::OnContextLost() {
121 client_->DidLoseLayerTreeFrameSink();
122}
123
124void FrameSinkImpl::SetNeedsBeginFrame(bool needs_begin_frame) {
125 if (needs_begin_frame_ == needs_begin_frame) {
126 return;
127 }
128 needs_begin_frame_ = needs_begin_frame;
Bo Liu11af9412023-04-05 19:49:39129 scheduler_->SetNeedsBeginFrame(needs_begin_frame);
Bo Liubfe80a072023-02-17 20:09:15130 frame_sink_->SetNeedsBeginFrame(needs_begin_frame);
Bo Liue0e51f22023-02-02 19:33:00131}
132
Bo Liu11af9412023-04-05 19:49:39133void FrameSinkImpl::MaybeCompositeNow() {
134 scheduler_->MaybeCompositeNow();
135}
136
Bo Liue0e51f22023-02-02 19:33:00137void FrameSinkImpl::UploadUIResource(cc::UIResourceId resource_id,
138 cc::UIResourceBitmap resource_bitmap) {
Bo Liue0e51f22023-02-02 19:33:00139 gfx::Size size = resource_bitmap.GetSize();
Bo Liue54865a2023-05-01 17:52:48140 TRACE_EVENT1("cc", "slim::FrameSinkImpl::UploadUIResource", "size",
141 size.ToString());
142 const gpu::Capabilities& caps = context_provider_->ContextCapabilities();
Bo Liue0e51f22023-02-02 19:33:00143 if (size.width() > caps.max_texture_size ||
144 size.height() > caps.max_texture_size) {
145 LOG(ERROR) << "Size exceeds max texture size";
146 return;
147 }
Colin Blundell836bf252023-02-15 08:33:58148 viz::SharedImageFormat format = viz::SinglePlaneFormat::kRGBA_8888;
Bo Liue0e51f22023-02-02 19:33:00149 switch (resource_bitmap.GetFormat()) {
150 case cc::UIResourceBitmap::RGBA8:
Colin Blundell836bf252023-02-15 08:33:58151 format = viz::PlatformColor::BestSupportedTextureFormat(caps);
Bo Liue0e51f22023-02-02 19:33:00152 break;
153 case cc::UIResourceBitmap::ALPHA_8:
Colin Blundell836bf252023-02-15 08:33:58154 format = viz::SinglePlaneFormat::kALPHA_8;
Bo Liue0e51f22023-02-02 19:33:00155 break;
156 case cc::UIResourceBitmap::ETC1:
Colin Blundell836bf252023-02-15 08:33:58157 format = viz::SinglePlaneFormat::kETC1;
Bo Liue0e51f22023-02-02 19:33:00158 break;
159 }
160
161 UploadedUIResource uploaded_resource;
162 auto* sii = context_provider_->SharedImageInterface();
163 constexpr gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB();
164 uint32_t shared_image_usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;
Mingjing Zhang65eedcc2023-10-24 15:12:42165 auto client_shared_image = sii->CreateSharedImage(
Colin Blundell836bf252023-02-15 08:33:58166 format, resource_bitmap.GetSize(), color_space, kTopLeft_GrSurfaceOrigin,
Rafael Cintronde3d9b82023-04-19 20:19:28167 kPremul_SkAlphaType, shared_image_usage, "SlimCompositorUIResource",
Bo Liue0e51f22023-02-02 19:33:00168 base::span<const uint8_t>(resource_bitmap.GetPixels(),
169 resource_bitmap.SizeInBytes()));
Mingjing Zhang65eedcc2023-10-24 15:12:42170 CHECK(client_shared_image);
171 uploaded_resource.mailbox = client_shared_image->mailbox();
Bo Liue0e51f22023-02-02 19:33:00172 gpu::SyncToken sync_token = sii->GenUnverifiedSyncToken();
173
174 GLenum texture_target = gpu::GetBufferTextureTarget(
Colin Blundell81fb20ca2023-05-30 09:37:54175 gfx::BufferUsage::SCANOUT,
176 viz::SinglePlaneSharedImageFormatToBufferFormat(format), caps);
Bo Liue0e51f22023-02-02 19:33:00177 uploaded_resource.viz_resource_id = resource_provider_.ImportResource(
178 viz::TransferableResource::MakeGpu(
kylechar35a372d2023-04-25 16:05:17179 uploaded_resource.mailbox, texture_target, sync_token,
Jonathan Ross5914b992023-09-28 15:30:53180 resource_bitmap.GetSize(), format, /*is_overlay_candidate=*/false,
181 viz::TransferableResource::ResourceSource::kUI),
Bo Liue0e51f22023-02-02 19:33:00182 base::BindOnce(&FrameSinkImpl::UIResourceReleased, base::Unretained(this),
183 resource_id));
184 uploaded_resource.size = resource_bitmap.GetSize();
185 uploaded_resource.is_opaque = resource_bitmap.GetOpaque();
186
Bo Liu9d07e212023-02-27 17:13:37187 DCHECK(!uploaded_resources_.contains(resource_id));
Bo Liue0e51f22023-02-02 19:33:00188 uploaded_resources_.emplace(resource_id, uploaded_resource);
189}
190
191void FrameSinkImpl::UIResourceReleased(cc::UIResourceId ui_resource_id,
192 const gpu::SyncToken& sync_token,
193 bool is_lost) {
194 auto itr = uploaded_resources_.find(ui_resource_id);
195 DCHECK(itr != uploaded_resources_.end());
196 auto* sii = context_provider_->SharedImageInterface();
197 sii->DestroySharedImage(sync_token, itr->second.mailbox);
198 uploaded_resources_.erase(itr);
199}
200
201void FrameSinkImpl::MarkUIResourceForDeletion(cc::UIResourceId resource_id) {
202 auto itr = uploaded_resources_.find(resource_id);
203 if (itr == uploaded_resources_.end()) {
204 return;
205 }
206 resource_provider_.RemoveImportedResource(itr->second.viz_resource_id);
207}
208
Bo Liu873d13e32023-02-08 15:58:42209viz::ResourceId FrameSinkImpl::GetVizResourceId(cc::UIResourceId resource_id) {
210 auto itr = uploaded_resources_.find(resource_id);
211 if (itr == uploaded_resources_.end()) {
212 return viz::kInvalidResourceId;
213 }
214 return itr->second.viz_resource_id;
Bo Liue0e51f22023-02-02 19:33:00215}
216
217bool FrameSinkImpl::IsUIResourceOpaque(cc::UIResourceId resource_id) {
218 auto it = uploaded_resources_.find(resource_id);
219 if (it == uploaded_resources_.end()) {
220 return true;
221 }
222 return it->second.is_opaque;
223}
224
225gfx::Size FrameSinkImpl::GetUIResourceSize(cc::UIResourceId resource_id) {
226 auto it = uploaded_resources_.find(resource_id);
227 if (it == uploaded_resources_.end()) {
228 return gfx::Size();
229 }
230
231 return it->second.size;
232}
233
Bo Liuf5bd17342023-03-10 17:55:45234int FrameSinkImpl::GetMaxTextureSize() const {
235 if (context_provider_) {
236 return context_provider_->ContextCapabilities().max_texture_size;
237 }
238 return kSoftwareMaxTextureSize;
239}
240
Bo Liue0e51f22023-02-02 19:33:00241void FrameSinkImpl::DidReceiveCompositorFrameAck(
242 std::vector<viz::ReturnedResource> resources) {
243 ReclaimResources(std::move(resources));
Bo Liu3380083a2023-03-22 16:11:04244 DCHECK_GT(num_unacked_frames_, 0u);
245 num_unacked_frames_--;
Bo Liu11af9412023-04-05 19:49:39246 if (!num_unacked_frames_) {
247 scheduler_->SetIsSwapThrottled(false);
248 }
Bo Liue0e51f22023-02-02 19:33:00249 client_->DidReceiveCompositorFrameAck();
250}
251
Bo Liu3380083a2023-03-22 16:11:04252void FrameSinkImpl::ReclaimResources(
253 std::vector<viz::ReturnedResource> resources) {
254 resource_provider_.ReceiveReturnsFromParent(std::move(resources));
255}
256
Bo Liue0e51f22023-02-02 19:33:00257void FrameSinkImpl::OnBeginFrame(
258 const viz::BeginFrameArgs& begin_frame_args,
Jonathan Rossd3117112023-02-17 16:42:09259 const viz::FrameTimingDetailsMap& timing_details,
260 bool frame_ack,
261 std::vector<viz::ReturnedResource> resources) {
262 if (features::IsOnBeginFrameAcksEnabled()) {
263 if (frame_ack) {
264 DidReceiveCompositorFrameAck(std::move(resources));
265 } else if (!resources.empty()) {
266 ReclaimResources(std::move(resources));
267 }
268 }
269
Bo Liuc078148b2023-02-22 18:29:22270 // Note order here is expected to be in order w.r.t viz::FrameTokenGT. This
271 // mostly holds because `FrameTimingDetailsMap` is a flat_map which is sorted.
272 // However this doesn't hold when frame token wraps.
Bo Liue0e51f22023-02-02 19:33:00273 for (const auto& pair : timing_details) {
274 client_->DidPresentCompositorFrame(pair.first, pair.second);
275 }
276
Bo Liu3380083a2023-03-22 16:11:04277 scheduler_->OnBeginFrameFromViz(begin_frame_args);
278}
279
280bool FrameSinkImpl::DoBeginFrame(const viz::BeginFrameArgs& begin_frame_args) {
281 if (num_unacked_frames_) {
282 return false;
283 }
284
Bo Liue0e51f22023-02-02 19:33:00285 if (!local_surface_id_.is_valid()) {
Bo Liu3380083a2023-03-22 16:11:04286 return false;
Bo Liue0e51f22023-02-02 19:33:00287 }
288
Bo Liufe5b6212023-04-06 16:56:28289 TRACE_EVENT0("cc", "slim::FrameSinkImpl::DoBeginFrame");
Bo Liue0e51f22023-02-02 19:33:00290 viz::CompositorFrame frame;
Bo Liu873d13e32023-02-08 15:58:42291 base::flat_set<viz::ResourceId> viz_resource_ids;
Bo Liue0e51f22023-02-02 19:33:00292 viz::HitTestRegionList hit_test_region_list;
Bo Liu873d13e32023-02-08 15:58:42293 if (!client_->BeginFrame(begin_frame_args, frame, viz_resource_ids,
Bo Liue0e51f22023-02-02 19:33:00294 hit_test_region_list)) {
Bo Liu3380083a2023-03-22 16:11:04295 return false;
Bo Liue0e51f22023-02-02 19:33:00296 }
297
Bo Liubfe80a072023-02-17 20:09:15298 if (local_surface_id_ == last_submitted_local_surface_id_) {
299 DCHECK_EQ(last_submitted_device_scale_factor_, frame.device_scale_factor());
300 DCHECK_EQ(last_submitted_size_in_pixels_.height(),
301 frame.size_in_pixels().height());
302 DCHECK_EQ(last_submitted_size_in_pixels_.width(),
303 frame.size_in_pixels().width());
304 }
305
Bo Liu873d13e32023-02-08 15:58:42306 resource_provider_.PrepareSendToParent(std::move(viz_resource_ids).extract(),
307 &frame.resource_list,
Bo Liue0e51f22023-02-02 19:33:00308 context_provider_.get());
309
310 bool send_new_hit_test_region_list = false;
311 if (!hit_test_region_list_ ||
312 !viz::HitTestRegionList::IsEqual(*hit_test_region_list_,
313 hit_test_region_list)) {
314 send_new_hit_test_region_list = true;
315 hit_test_region_list_ = std::move(hit_test_region_list);
316 }
317
318 {
Aman Vermab5f203c2023-07-31 18:32:41319 TRACE_EVENT(
Aman Vermae40f10842023-08-09 15:30:19320 "viz,benchmark,graphics.pipeline", "Graphics.Pipeline",
Aman Vermab5f203c2023-07-31 18:32:41321 perfetto::Flow::Global(begin_frame_args.trace_id),
322 [&](perfetto::EventContext ctx) {
323 auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
324 auto* data = event->set_chrome_graphics_pipeline();
325 data->set_step(perfetto::protos::pbzero::ChromeGraphicsPipeline::
326 StepName::STEP_SUBMIT_COMPOSITOR_FRAME);
327 });
Bo Liubfe80a072023-02-17 20:09:15328 frame_sink_->SubmitCompositorFrame(
Bo Liue0e51f22023-02-02 19:33:00329 local_surface_id_, std::move(frame),
Arthur Sonzognica067f262023-11-10 14:18:10330 send_new_hit_test_region_list ? hit_test_region_list_ : std::nullopt,
Bo Liue0e51f22023-02-02 19:33:00331 0);
332 }
Bo Liu3380083a2023-03-22 16:11:04333 num_unacked_frames_++;
Bo Liu11af9412023-04-05 19:49:39334 if (num_unacked_frames_ == 1) {
335 scheduler_->SetIsSwapThrottled(true);
336 }
Bo Liue0e51f22023-02-02 19:33:00337 client_->DidSubmitCompositorFrame();
Bo Liu3380083a2023-03-22 16:11:04338 return true;
Bo Liue0e51f22023-02-02 19:33:00339}
340
Bo Liu3380083a2023-03-22 16:11:04341void FrameSinkImpl::SendDidNotProduceFrame(
342 const viz::BeginFrameArgs& begin_frame_args) {
Aman Vermab5f203c2023-07-31 18:32:41343 TRACE_EVENT(
Aman Vermae40f10842023-08-09 15:30:19344 "viz,benchmark,graphics.pipeline", "Graphics.Pipeline",
Aman Vermab5f203c2023-07-31 18:32:41345 perfetto::Flow::Global(begin_frame_args.trace_id),
346 [&](perfetto::EventContext ctx) {
347 auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
348 auto* data = event->set_chrome_graphics_pipeline();
349 data->set_step(perfetto::protos::pbzero::ChromeGraphicsPipeline::
350 StepName::STEP_DID_NOT_PRODUCE_FRAME);
351 });
Bo Liu3380083a2023-03-22 16:11:04352 frame_sink_->DidNotProduceFrame(viz::BeginFrameAck(begin_frame_args, false));
Bo Liue0e51f22023-02-02 19:33:00353}
354
355} // namespace cc::slim