[go: nahoru, domu]

blob: 931a56ccdb66c31eed64183d9ab54101fea336b2 [file] [log] [blame]
Avi Drissman3f7a9d82022-09-08 20:55:421// Copyright 2013 The Chromium Authors
prashant.nb4d4f492016-04-29 12:51:282// 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/raster/zero_copy_raster_buffer_provider.h"
6
7#include <stdint.h>
8
9#include <algorithm>
Chris Blumed4354332020-11-11 08:40:1610#include <utility>
prashant.nb4d4f492016-04-29 12:51:2811
Colin Blundell42819692023-09-25 15:24:2812#include "base/feature_list.h"
Keishi Hattori0e45c022021-11-27 09:25:5213#include "base/memory/raw_ptr.h"
Antoine Laboure5a2101a2018-11-07 23:36:2714#include "base/trace_event/process_memory_dump.h"
prashant.nb4d4f492016-04-29 12:51:2815#include "base/trace_event/trace_event.h"
David 'Digit' Turner59a87482018-10-29 13:27:1616#include "base/trace_event/traced_value.h"
danakjbd636052018-02-06 18:28:4917#include "cc/resources/resource_pool.h"
danakj57baa772018-05-29 15:59:1418#include "components/viz/client/client_resource_provider.h"
kylecharffcf0912023-06-09 18:57:2219#include "components/viz/common/gpu/raster_context_provider.h"
Fady Samuel555c8d12017-07-07 23:14:0920#include "components/viz/common/resources/platform_color.h"
Colin Blundell81fb20ca2023-05-30 09:37:5421#include "components/viz/common/resources/shared_image_format_utils.h"
Mingjing Zhang3f1265c2023-10-26 02:16:5522#include "gpu/command_buffer/client/client_shared_image.h"
danakjbd636052018-02-06 18:28:4923#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
Antoine Laboure5a2101a2018-11-07 23:36:2724#include "gpu/command_buffer/client/shared_image_interface.h"
danakjbd636052018-02-06 18:28:4925#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
Antoine Laboure5a2101a2018-11-07 23:36:2726#include "gpu/command_buffer/common/shared_image_trace_utils.h"
27#include "gpu/command_buffer/common/shared_image_usage.h"
prashant.nb4d4f492016-04-29 12:51:2828#include "ui/gfx/buffer_format_util.h"
29#include "ui/gfx/gpu_memory_buffer.h"
30
31namespace cc {
32namespace {
33
Colin Blundell42819692023-09-25 15:24:2834BASE_FEATURE(kAlwaysUseMappableSIForZeroCopyRaster,
35 "AlwaysUseMappableSIForZeroCopyRaster",
36 base::FEATURE_ENABLED_BY_DEFAULT);
37
danakjbd636052018-02-06 18:28:4938constexpr static auto kBufferUsage = gfx::BufferUsage::GPU_READ_CPU_READ_WRITE;
39
40// Subclass for InUsePoolResource that holds ownership of a zero-copy backing
41// and does cleanup of the backing when destroyed.
42class ZeroCopyGpuBacking : public ResourcePool::GpuBacking {
43 public:
44 ~ZeroCopyGpuBacking() override {
Antoine Laboure5a2101a2018-11-07 23:36:2745 if (mailbox.IsZero())
46 return;
danakjbd636052018-02-06 18:28:4947 if (returned_sync_token.HasData())
Antoine Laboure5a2101a2018-11-07 23:36:2748 shared_image_interface->DestroySharedImage(returned_sync_token, mailbox);
49 else if (mailbox_sync_token.HasData())
50 shared_image_interface->DestroySharedImage(mailbox_sync_token, mailbox);
danakjbd636052018-02-06 18:28:4951 }
52
Alexandr Ilin0443a8f2018-07-20 20:14:5053 void OnMemoryDump(
54 base::trace_event::ProcessMemoryDump* pmd,
55 const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
56 uint64_t tracing_process_id,
57 int importance) const override {
Colin Blundell42819692023-09-25 15:24:2858 if (base::FeatureList::IsEnabled(kAlwaysUseMappableSIForZeroCopyRaster)) {
59 if (mailbox.IsZero()) {
60 return;
61 }
62 auto mapping = shared_image_interface->MapSharedImage(mailbox);
63 if (!mapping) {
64 return;
65 }
66 mapping->OnMemoryDump(pmd, buffer_dump_guid, tracing_process_id,
67 importance);
68 } else {
69 if (!gpu_memory_buffer) {
70 return;
71 }
72 gpu_memory_buffer->OnMemoryDump(pmd, buffer_dump_guid, tracing_process_id,
73 importance);
74 }
danakjbd636052018-02-06 18:28:4975 }
76
Antoine Laboure5a2101a2018-11-07 23:36:2777 // The SharedImageInterface used to clean up the shared image.
Keishi Hattori0e45c022021-11-27 09:25:5278 raw_ptr<gpu::SharedImageInterface> shared_image_interface = nullptr;
danakjbd636052018-02-06 18:28:4979 // The backing for zero-copy gpu resources. The |texture_id| is bound to
80 // this.
81 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer;
danakjbd636052018-02-06 18:28:4982};
83
84// RasterBuffer for the zero copy upload, which is given to the raster worker
85// threads for raster/upload.
Daniel Bratell1bddcb332017-11-21 11:08:2986class ZeroCopyRasterBufferImpl : public RasterBuffer {
prashant.nb4d4f492016-04-29 12:51:2887 public:
danakj4e871d82018-01-18 21:56:5788 ZeroCopyRasterBufferImpl(
danakjbd636052018-02-06 18:28:4989 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
John Abd-El-Malek61fd3e12021-04-29 19:01:3090 base::WaitableEvent* shutdown_event,
danakjbd636052018-02-06 18:28:4991 const ResourcePool::InUsePoolResource& in_use_resource,
92 ZeroCopyGpuBacking* backing)
93 : backing_(backing),
94 gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
John Abd-El-Malek61fd3e12021-04-29 19:01:3095 shutdown_event_(shutdown_event),
danakj4e871d82018-01-18 21:56:5796 resource_size_(in_use_resource.size()),
Colin Blundell1190bd92023-03-21 11:49:0597 format_(in_use_resource.format()),
danakjbd636052018-02-06 18:28:4998 resource_color_space_(in_use_resource.color_space()),
99 gpu_memory_buffer_(std::move(backing_->gpu_memory_buffer)) {}
Vladimir Levinf06d1cd72019-03-13 18:24:10100 ZeroCopyRasterBufferImpl(const ZeroCopyRasterBufferImpl&) = delete;
danakjbd636052018-02-06 18:28:49101
102 ~ZeroCopyRasterBufferImpl() override {
Colin Blundell42819692023-09-25 15:24:28103 // If MapSharedImage() or GpuMemoryBuffer allocation failed
104 // (https://crbug.com/554541), then we don't have anything to give to the
105 // display compositor, so we report a zero mailbox that will result in
106 // checkerboarding.
107 if (base::FeatureList::IsEnabled(kAlwaysUseMappableSIForZeroCopyRaster)) {
108 CHECK(!gpu_memory_buffer_);
109 if (backing_->mailbox.IsZero()) {
110 return;
111 }
112 } else {
113 if (!gpu_memory_buffer_) {
114 DCHECK(backing_->mailbox.IsZero());
115 return;
116 }
Antoine Labour6363d8202018-10-29 22:36:01117 }
118
danakjbd636052018-02-06 18:28:49119 // This is destroyed on the compositor thread when raster is complete, but
120 // before the backing is prepared for export to the display compositor. So
121 // we can set up the texture and SyncToken here.
122 // TODO(danakj): This could be done with the worker context in Playback. Do
123 // we need to do things in IsResourceReadyToDraw() and OrderingBarrier then?
Antoine Laboure5a2101a2018-11-07 23:36:27124 gpu::SharedImageInterface* sii = backing_->shared_image_interface;
125 if (backing_->mailbox.IsZero()) {
Colin Blundell42819692023-09-25 15:24:28126 CHECK(
127 !base::FeatureList::IsEnabled(kAlwaysUseMappableSIForZeroCopyRaster));
Michael Tang82400382022-10-03 20:22:13128 uint32_t usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ |
129 gpu::SHARED_IMAGE_USAGE_SCANOUT;
Antoine Laboure5a2101a2018-11-07 23:36:27130 // Make a mailbox for export of the GpuMemoryBuffer to the display
131 // compositor.
Nathan Zabriskie659c2742020-07-16 03:49:32132 backing_->mailbox = sii->CreateSharedImage(
Saifuddin Hitawala9ca81a52023-06-06 20:09:23133 format_, resource_size_, resource_color_space_,
134 kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, usage,
135 "ZeroCopyRasterTile", gpu_memory_buffer_->CloneHandle());
danakjbd636052018-02-06 18:28:49136 } else {
Antoine Laboure5a2101a2018-11-07 23:36:27137 sii->UpdateSharedImage(backing_->returned_sync_token, backing_->mailbox);
danakjbd636052018-02-06 18:28:49138 }
139
Antoine Laboure5a2101a2018-11-07 23:36:27140 backing_->mailbox_sync_token = sii->GenUnverifiedSyncToken();
danakjbd636052018-02-06 18:28:49141 backing_->gpu_memory_buffer = std::move(gpu_memory_buffer_);
142 }
prashant.nb4d4f492016-04-29 12:51:28143
Vladimir Levinf06d1cd72019-03-13 18:24:10144 ZeroCopyRasterBufferImpl& operator=(const ZeroCopyRasterBufferImpl&) = delete;
145
prashant.nb4d4f492016-04-29 12:51:28146 // Overridden from RasterBuffer:
Khushal49836ab2018-07-25 02:08:45147 void Playback(const RasterSource* raster_source,
148 const gfx::Rect& raster_full_rect,
149 const gfx::Rect& raster_dirty_rect,
150 uint64_t new_content_id,
151 const gfx::AxisTransform2d& transform,
152 const RasterSource::PlaybackSettings& playback_settings,
153 const GURL& url) override {
prashant.n60e135b02016-06-08 04:12:23154 TRACE_EVENT0("cc", "ZeroCopyRasterBuffer::Playback");
prashant.nb4d4f492016-04-29 12:51:28155
Colin Blundell42819692023-09-25 15:24:28156 std::unique_ptr<gpu::SharedImageInterface::ScopedMapping> mapping;
157 void* memory = nullptr;
158 size_t stride = 0;
danakjbd636052018-02-06 18:28:49159
Colin Blundell42819692023-09-25 15:24:28160 if (base::FeatureList::IsEnabled(kAlwaysUseMappableSIForZeroCopyRaster)) {
161 CHECK(!gpu_memory_buffer_);
162
163 gpu::SharedImageInterface* sii = backing_->shared_image_interface;
164
165 // Create a MappableSI if necessary.
166 if (backing_->mailbox.IsZero()) {
167 uint32_t usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ |
168 gpu::SHARED_IMAGE_USAGE_SCANOUT;
Mingjing Zhang3f1265c2023-10-26 02:16:55169 auto client_shared_image = sii->CreateSharedImage(
Colin Blundell42819692023-09-25 15:24:28170 format_, resource_size_, resource_color_space_,
171 kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, usage,
172 "ZeroCopyRasterTile", gpu::kNullSurfaceHandle, kBufferUsage);
Mingjing Zhang3f1265c2023-10-26 02:16:55173 if (!client_shared_image) {
174 LOG(ERROR) << "Creation of MappableSharedImage failed.";
175 return;
176 }
177 backing_->mailbox = client_shared_image->mailbox();
Colin Blundellbdf8b2c2023-10-03 15:43:04178 }
179
Colin Blundell42819692023-09-25 15:24:28180 mapping = sii->MapSharedImage(backing_->mailbox);
181 if (!mapping) {
182 LOG(ERROR) << "MapSharedImage Failed.";
183 sii->DestroySharedImage(gpu::SyncToken(), backing_->mailbox);
184 backing_->mailbox.SetZero();
185 return;
186 }
187 memory = mapping->Memory(0);
188 stride = mapping->Stride(0);
189 } else {
190 if (!gpu_memory_buffer_) {
191 gpu_memory_buffer_ = gpu_memory_buffer_manager_->CreateGpuMemoryBuffer(
192 resource_size_,
193 viz::SinglePlaneSharedImageFormatToBufferFormat(format_),
194 kBufferUsage, gpu::kNullSurfaceHandle, shutdown_event_);
195 // Note that GpuMemoryBuffer allocation can fail.
196 // https://crbug.com/554541
197 if (!gpu_memory_buffer_) {
198 return;
199 }
200 }
201
202 CHECK_EQ(1u, gfx::NumberOfPlanesForLinearBufferFormat(
203 gpu_memory_buffer_->GetFormat()));
204 bool rv = gpu_memory_buffer_->Map();
205 CHECK(rv);
206 CHECK(gpu_memory_buffer_->memory(0));
207 // RasterBufferProvider::PlaybackToMemory only supports unsigned strides.
208 CHECK_GE(gpu_memory_buffer_->stride(0), 0);
209
210 memory = gpu_memory_buffer_->memory(0);
211 stride = gpu_memory_buffer_->stride(0);
212 }
prashant.nb4d4f492016-04-29 12:51:28213
214 // TODO(danakj): Implement partial raster with raster_dirty_rect.
215 RasterBufferProvider::PlaybackToMemory(
Colin Blundell42819692023-09-25 15:24:28216 memory, format_, resource_size_, stride, raster_source,
217 raster_full_rect, raster_full_rect, transform, resource_color_space_,
danakja32578c2018-04-25 21:18:36218 /*gpu_compositing=*/true, playback_settings);
Colin Blundell42819692023-09-25 15:24:28219
220 base::FeatureList::IsEnabled(kAlwaysUseMappableSIForZeroCopyRaster)
221 ? mapping.reset()
222 : gpu_memory_buffer_->Unmap();
prashant.nb4d4f492016-04-29 12:51:28223 }
224
Francois Dorayaffe0912020-06-30 20:29:21225 bool SupportsBackgroundThreadPriority() const override { return true; }
226
prashant.nb4d4f492016-04-29 12:51:28227 private:
danakjbd636052018-02-06 18:28:49228 // This field may only be used on the compositor thread.
Keishi Hattori0e45c022021-11-27 09:25:52229 raw_ptr<ZeroCopyGpuBacking> backing_;
danakjbd636052018-02-06 18:28:49230
231 // These fields are for use on the worker thread.
Keishi Hattori0e45c022021-11-27 09:25:52232 raw_ptr<gpu::GpuMemoryBufferManager> gpu_memory_buffer_manager_;
233 raw_ptr<base::WaitableEvent> shutdown_event_;
danakj4e871d82018-01-18 21:56:57234 gfx::Size resource_size_;
Colin Blundell04316232023-03-16 08:14:15235 viz::SharedImageFormat format_;
danakjbd636052018-02-06 18:28:49236 gfx::ColorSpace resource_color_space_;
237 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
prashant.nb4d4f492016-04-29 12:51:28238};
239
240} // namespace
241
prashant.nb4d4f492016-04-29 12:51:28242ZeroCopyRasterBufferProvider::ZeroCopyRasterBufferProvider(
danakjbd636052018-02-06 18:28:49243 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
kylecharffcf0912023-06-09 18:57:22244 viz::RasterContextProvider* compositor_context_provider,
kylechar8cce4942023-06-20 18:03:03245 const RasterCapabilities& raster_caps)
danakja32578c2018-04-25 21:18:36246 : gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
danakjbd636052018-02-06 18:28:49247 compositor_context_provider_(compositor_context_provider),
kylechar58c09f72023-07-11 21:27:34248 tile_format_(raster_caps.tile_format),
249 tile_texture_target_(raster_caps.tile_texture_target) {}
prashant.nb4d4f492016-04-29 12:51:28250
Chris Watkinsf6353292017-12-04 02:36:05251ZeroCopyRasterBufferProvider::~ZeroCopyRasterBufferProvider() = default;
prashant.nb4d4f492016-04-29 12:51:28252
253std::unique_ptr<RasterBuffer>
254ZeroCopyRasterBufferProvider::AcquireBufferForRaster(
danakj4e871d82018-01-18 21:56:57255 const ResourcePool::InUsePoolResource& resource,
prashant.nb4d4f492016-04-29 12:51:28256 uint64_t resource_content_id,
Andres Calderon Jaramillob6b26dc2019-11-25 21:24:05257 uint64_t previous_content_id,
Andres Calderon Jaramillo5057f232019-11-29 23:05:48258 bool depends_on_at_raster_decodes,
259 bool depends_on_hardware_accelerated_jpeg_candidates,
260 bool depends_on_hardware_accelerated_webp_candidates) {
danakjbd636052018-02-06 18:28:49261 if (!resource.gpu_backing()) {
262 auto backing = std::make_unique<ZeroCopyGpuBacking>();
Antoine Laboure5a2101a2018-11-07 23:36:27263 backing->overlay_candidate = true;
kylechar58c09f72023-07-11 21:27:34264 backing->texture_target = tile_texture_target_;
Antoine Laboure5a2101a2018-11-07 23:36:27265 // This RasterBufferProvider will modify the resource outside of the
266 // GL command stream. So resources should not become available for reuse
267 // until they are not in use by the gpu anymore, which a fence is used
268 // to determine.
269 backing->wait_on_fence_required = true;
270 backing->shared_image_interface =
271 compositor_context_provider_->SharedImageInterface();
danakjbd636052018-02-06 18:28:49272 resource.set_gpu_backing(std::move(backing));
273 }
274 ZeroCopyGpuBacking* backing =
275 static_cast<ZeroCopyGpuBacking*>(resource.gpu_backing());
276
John Abd-El-Malek61fd3e12021-04-29 19:01:30277 return std::make_unique<ZeroCopyRasterBufferImpl>(
278 gpu_memory_buffer_manager_, shutdown_event_, resource, backing);
prashant.nb4d4f492016-04-29 12:51:28279}
280
Sunny Sachanandani5f5419e22017-05-12 20:35:30281void ZeroCopyRasterBufferProvider::Flush() {}
282
Colin Blundell68d83e72023-03-17 07:49:28283viz::SharedImageFormat ZeroCopyRasterBufferProvider::GetFormat() const {
danakja32578c2018-04-25 21:18:36284 return tile_format_;
prashant.nb4d4f492016-04-29 12:51:28285}
286
danakja32578c2018-04-25 21:18:36287bool ZeroCopyRasterBufferProvider::IsResourcePremultiplied() const {
Eric Karl247f09c2018-03-15 02:06:36288 return true;
289}
290
ericrk5ac42f322016-07-14 01:06:51291bool ZeroCopyRasterBufferProvider::CanPartialRasterIntoProvidedResource()
292 const {
ericrkeeda58992016-07-07 02:34:27293 return false;
294}
295
ericrk7f6a27f2017-01-31 22:34:32296bool ZeroCopyRasterBufferProvider::IsResourceReadyToDraw(
Steve Kobesad278432023-07-05 21:35:41297 const ResourcePool::InUsePoolResource& resource) {
ericrk7f6a27f2017-01-31 22:34:32298 // Zero-copy resources are immediately ready to draw.
299 return true;
300}
301
302uint64_t ZeroCopyRasterBufferProvider::SetReadyToDrawCallback(
danakj4e871d82018-01-18 21:56:57303 const std::vector<const ResourcePool::InUsePoolResource*>& resources,
kylechar4bb144d2019-01-11 20:42:07304 base::OnceClosure callback,
Steve Kobesad278432023-07-05 21:35:41305 uint64_t pending_callback_id) {
ericrk7f6a27f2017-01-31 22:34:32306 // Zero-copy resources are immediately ready to draw.
307 return 0;
308}
309
John Abd-El-Malek61fd3e12021-04-29 19:01:30310void ZeroCopyRasterBufferProvider::SetShutdownEvent(
311 base::WaitableEvent* shutdown_event) {
312 shutdown_event_ = shutdown_event;
313}
314
prashant.nb4d4f492016-04-29 12:51:28315void ZeroCopyRasterBufferProvider::Shutdown() {}
316
prashant.nb4d4f492016-04-29 12:51:28317} // namespace cc