[go: nahoru, domu]

blob: 7b832cb3739edefd46f0420eddc01cb85ebdccc7 [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 {
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:3145 if (!shared_image) {
Antoine Laboure5a2101a2018-11-07 23:36:2746 return;
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:3147 }
danakjbd636052018-02-06 18:28:4948 if (returned_sync_token.HasData())
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:3149 shared_image_interface->DestroySharedImage(returned_sync_token,
50 std::move(shared_image));
Antoine Laboure5a2101a2018-11-07 23:36:2751 else if (mailbox_sync_token.HasData())
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:3152 shared_image_interface->DestroySharedImage(mailbox_sync_token,
53 std::move(shared_image));
danakjbd636052018-02-06 18:28:4954 }
55
Alexandr Ilin0443a8f2018-07-20 20:14:5056 void OnMemoryDump(
57 base::trace_event::ProcessMemoryDump* pmd,
58 const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
59 uint64_t tracing_process_id,
60 int importance) const override {
Colin Blundell42819692023-09-25 15:24:2861 if (base::FeatureList::IsEnabled(kAlwaysUseMappableSIForZeroCopyRaster)) {
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:3162 if (!shared_image) {
Colin Blundell42819692023-09-25 15:24:2863 return;
64 }
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:3165 auto mapping =
66 shared_image_interface->MapSharedImage(shared_image->mailbox());
Colin Blundell42819692023-09-25 15:24:2867 if (!mapping) {
68 return;
69 }
70 mapping->OnMemoryDump(pmd, buffer_dump_guid, tracing_process_id,
71 importance);
72 } else {
73 if (!gpu_memory_buffer) {
74 return;
75 }
76 gpu_memory_buffer->OnMemoryDump(pmd, buffer_dump_guid, tracing_process_id,
77 importance);
78 }
danakjbd636052018-02-06 18:28:4979 }
80
Antoine Laboure5a2101a2018-11-07 23:36:2781 // The SharedImageInterface used to clean up the shared image.
Keishi Hattori0e45c022021-11-27 09:25:5282 raw_ptr<gpu::SharedImageInterface> shared_image_interface = nullptr;
danakjbd636052018-02-06 18:28:4983 // The backing for zero-copy gpu resources. The |texture_id| is bound to
84 // this.
85 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer;
danakjbd636052018-02-06 18:28:4986};
87
88// RasterBuffer for the zero copy upload, which is given to the raster worker
89// threads for raster/upload.
Daniel Bratell1bddcb332017-11-21 11:08:2990class ZeroCopyRasterBufferImpl : public RasterBuffer {
prashant.nb4d4f492016-04-29 12:51:2891 public:
danakj4e871d82018-01-18 21:56:5792 ZeroCopyRasterBufferImpl(
danakjbd636052018-02-06 18:28:4993 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
John Abd-El-Malek61fd3e12021-04-29 19:01:3094 base::WaitableEvent* shutdown_event,
danakjbd636052018-02-06 18:28:4995 const ResourcePool::InUsePoolResource& in_use_resource,
96 ZeroCopyGpuBacking* backing)
97 : backing_(backing),
98 gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
John Abd-El-Malek61fd3e12021-04-29 19:01:3099 shutdown_event_(shutdown_event),
danakj4e871d82018-01-18 21:56:57100 resource_size_(in_use_resource.size()),
Colin Blundell1190bd92023-03-21 11:49:05101 format_(in_use_resource.format()),
danakjbd636052018-02-06 18:28:49102 resource_color_space_(in_use_resource.color_space()),
103 gpu_memory_buffer_(std::move(backing_->gpu_memory_buffer)) {}
Vladimir Levinf06d1cd72019-03-13 18:24:10104 ZeroCopyRasterBufferImpl(const ZeroCopyRasterBufferImpl&) = delete;
danakjbd636052018-02-06 18:28:49105
106 ~ZeroCopyRasterBufferImpl() override {
Colin Blundell42819692023-09-25 15:24:28107 // If MapSharedImage() or GpuMemoryBuffer allocation failed
108 // (https://crbug.com/554541), then we don't have anything to give to the
109 // display compositor, so we report a zero mailbox that will result in
110 // checkerboarding.
111 if (base::FeatureList::IsEnabled(kAlwaysUseMappableSIForZeroCopyRaster)) {
112 CHECK(!gpu_memory_buffer_);
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:31113 if (!backing_->shared_image) {
Colin Blundell42819692023-09-25 15:24:28114 return;
115 }
116 } else {
117 if (!gpu_memory_buffer_) {
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:31118 DCHECK(!backing_->shared_image);
Colin Blundell42819692023-09-25 15:24:28119 return;
120 }
Antoine Labour6363d8202018-10-29 22:36:01121 }
122
danakjbd636052018-02-06 18:28:49123 // This is destroyed on the compositor thread when raster is complete, but
124 // before the backing is prepared for export to the display compositor. So
125 // we can set up the texture and SyncToken here.
126 // TODO(danakj): This could be done with the worker context in Playback. Do
127 // we need to do things in IsResourceReadyToDraw() and OrderingBarrier then?
Antoine Laboure5a2101a2018-11-07 23:36:27128 gpu::SharedImageInterface* sii = backing_->shared_image_interface;
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:31129 if (!backing_->shared_image) {
Colin Blundell42819692023-09-25 15:24:28130 CHECK(
131 !base::FeatureList::IsEnabled(kAlwaysUseMappableSIForZeroCopyRaster));
Michael Tang82400382022-10-03 20:22:13132 uint32_t usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ |
133 gpu::SHARED_IMAGE_USAGE_SCANOUT;
Antoine Laboure5a2101a2018-11-07 23:36:27134 // Make a mailbox for export of the GpuMemoryBuffer to the display
135 // compositor.
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:31136 backing_->shared_image = sii->CreateSharedImage(
Saifuddin Hitawala9ca81a52023-06-06 20:09:23137 format_, resource_size_, resource_color_space_,
138 kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, usage,
139 "ZeroCopyRasterTile", gpu_memory_buffer_->CloneHandle());
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:31140 CHECK(backing_->shared_image);
danakjbd636052018-02-06 18:28:49141 } else {
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:31142 sii->UpdateSharedImage(backing_->returned_sync_token,
143 backing_->shared_image->mailbox());
danakjbd636052018-02-06 18:28:49144 }
145
Antoine Laboure5a2101a2018-11-07 23:36:27146 backing_->mailbox_sync_token = sii->GenUnverifiedSyncToken();
danakjbd636052018-02-06 18:28:49147 backing_->gpu_memory_buffer = std::move(gpu_memory_buffer_);
148 }
prashant.nb4d4f492016-04-29 12:51:28149
Vladimir Levinf06d1cd72019-03-13 18:24:10150 ZeroCopyRasterBufferImpl& operator=(const ZeroCopyRasterBufferImpl&) = delete;
151
prashant.nb4d4f492016-04-29 12:51:28152 // Overridden from RasterBuffer:
Khushal49836ab2018-07-25 02:08:45153 void Playback(const RasterSource* raster_source,
154 const gfx::Rect& raster_full_rect,
155 const gfx::Rect& raster_dirty_rect,
156 uint64_t new_content_id,
157 const gfx::AxisTransform2d& transform,
158 const RasterSource::PlaybackSettings& playback_settings,
159 const GURL& url) override {
prashant.n60e135b02016-06-08 04:12:23160 TRACE_EVENT0("cc", "ZeroCopyRasterBuffer::Playback");
prashant.nb4d4f492016-04-29 12:51:28161
Colin Blundell42819692023-09-25 15:24:28162 std::unique_ptr<gpu::SharedImageInterface::ScopedMapping> mapping;
163 void* memory = nullptr;
164 size_t stride = 0;
danakjbd636052018-02-06 18:28:49165
Colin Blundell42819692023-09-25 15:24:28166 if (base::FeatureList::IsEnabled(kAlwaysUseMappableSIForZeroCopyRaster)) {
167 CHECK(!gpu_memory_buffer_);
168
169 gpu::SharedImageInterface* sii = backing_->shared_image_interface;
170
171 // Create a MappableSI if necessary.
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:31172 if (!backing_->shared_image) {
Colin Blundell42819692023-09-25 15:24:28173 uint32_t usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ |
174 gpu::SHARED_IMAGE_USAGE_SCANOUT;
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:31175 backing_->shared_image = sii->CreateSharedImage(
Colin Blundell42819692023-09-25 15:24:28176 format_, resource_size_, resource_color_space_,
177 kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, usage,
178 "ZeroCopyRasterTile", gpu::kNullSurfaceHandle, kBufferUsage);
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:31179 if (!backing_->shared_image) {
Mingjing Zhang3f1265c2023-10-26 02:16:55180 LOG(ERROR) << "Creation of MappableSharedImage failed.";
181 return;
182 }
Colin Blundellbdf8b2c2023-10-03 15:43:04183 }
184
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:31185 mapping = sii->MapSharedImage(backing_->shared_image->mailbox());
Colin Blundell42819692023-09-25 15:24:28186 if (!mapping) {
187 LOG(ERROR) << "MapSharedImage Failed.";
luci-bisection@appspot.gserviceaccount.come9ab19e2023-11-10 17:28:31188 sii->DestroySharedImage(gpu::SyncToken(),
189 std::move(backing_->shared_image));
Colin Blundell42819692023-09-25 15:24:28190 return;
191 }
192 memory = mapping->Memory(0);
193 stride = mapping->Stride(0);
194 } else {
195 if (!gpu_memory_buffer_) {
196 gpu_memory_buffer_ = gpu_memory_buffer_manager_->CreateGpuMemoryBuffer(
197 resource_size_,
198 viz::SinglePlaneSharedImageFormatToBufferFormat(format_),
199 kBufferUsage, gpu::kNullSurfaceHandle, shutdown_event_);
200 // Note that GpuMemoryBuffer allocation can fail.
201 // https://crbug.com/554541
202 if (!gpu_memory_buffer_) {
203 return;
204 }
205 }
206
207 CHECK_EQ(1u, gfx::NumberOfPlanesForLinearBufferFormat(
208 gpu_memory_buffer_->GetFormat()));
209 bool rv = gpu_memory_buffer_->Map();
210 CHECK(rv);
211 CHECK(gpu_memory_buffer_->memory(0));
212 // RasterBufferProvider::PlaybackToMemory only supports unsigned strides.
213 CHECK_GE(gpu_memory_buffer_->stride(0), 0);
214
215 memory = gpu_memory_buffer_->memory(0);
216 stride = gpu_memory_buffer_->stride(0);
217 }
prashant.nb4d4f492016-04-29 12:51:28218
219 // TODO(danakj): Implement partial raster with raster_dirty_rect.
220 RasterBufferProvider::PlaybackToMemory(
Colin Blundell42819692023-09-25 15:24:28221 memory, format_, resource_size_, stride, raster_source,
222 raster_full_rect, raster_full_rect, transform, resource_color_space_,
danakja32578c2018-04-25 21:18:36223 /*gpu_compositing=*/true, playback_settings);
Colin Blundell42819692023-09-25 15:24:28224
225 base::FeatureList::IsEnabled(kAlwaysUseMappableSIForZeroCopyRaster)
226 ? mapping.reset()
227 : gpu_memory_buffer_->Unmap();
prashant.nb4d4f492016-04-29 12:51:28228 }
229
Francois Dorayaffe0912020-06-30 20:29:21230 bool SupportsBackgroundThreadPriority() const override { return true; }
231
prashant.nb4d4f492016-04-29 12:51:28232 private:
danakjbd636052018-02-06 18:28:49233 // This field may only be used on the compositor thread.
Keishi Hattori0e45c022021-11-27 09:25:52234 raw_ptr<ZeroCopyGpuBacking> backing_;
danakjbd636052018-02-06 18:28:49235
236 // These fields are for use on the worker thread.
Keishi Hattori0e45c022021-11-27 09:25:52237 raw_ptr<gpu::GpuMemoryBufferManager> gpu_memory_buffer_manager_;
238 raw_ptr<base::WaitableEvent> shutdown_event_;
danakj4e871d82018-01-18 21:56:57239 gfx::Size resource_size_;
Colin Blundell04316232023-03-16 08:14:15240 viz::SharedImageFormat format_;
danakjbd636052018-02-06 18:28:49241 gfx::ColorSpace resource_color_space_;
242 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
prashant.nb4d4f492016-04-29 12:51:28243};
244
245} // namespace
246
prashant.nb4d4f492016-04-29 12:51:28247ZeroCopyRasterBufferProvider::ZeroCopyRasterBufferProvider(
danakjbd636052018-02-06 18:28:49248 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
kylecharffcf0912023-06-09 18:57:22249 viz::RasterContextProvider* compositor_context_provider,
kylechar8cce4942023-06-20 18:03:03250 const RasterCapabilities& raster_caps)
danakja32578c2018-04-25 21:18:36251 : gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
danakjbd636052018-02-06 18:28:49252 compositor_context_provider_(compositor_context_provider),
kylechar58c09f72023-07-11 21:27:34253 tile_format_(raster_caps.tile_format),
254 tile_texture_target_(raster_caps.tile_texture_target) {}
prashant.nb4d4f492016-04-29 12:51:28255
Chris Watkinsf6353292017-12-04 02:36:05256ZeroCopyRasterBufferProvider::~ZeroCopyRasterBufferProvider() = default;
prashant.nb4d4f492016-04-29 12:51:28257
258std::unique_ptr<RasterBuffer>
259ZeroCopyRasterBufferProvider::AcquireBufferForRaster(
danakj4e871d82018-01-18 21:56:57260 const ResourcePool::InUsePoolResource& resource,
prashant.nb4d4f492016-04-29 12:51:28261 uint64_t resource_content_id,
Andres Calderon Jaramillob6b26dc2019-11-25 21:24:05262 uint64_t previous_content_id,
Andres Calderon Jaramillo5057f232019-11-29 23:05:48263 bool depends_on_at_raster_decodes,
264 bool depends_on_hardware_accelerated_jpeg_candidates,
265 bool depends_on_hardware_accelerated_webp_candidates) {
danakjbd636052018-02-06 18:28:49266 if (!resource.gpu_backing()) {
267 auto backing = std::make_unique<ZeroCopyGpuBacking>();
Antoine Laboure5a2101a2018-11-07 23:36:27268 backing->overlay_candidate = true;
kylechar58c09f72023-07-11 21:27:34269 backing->texture_target = tile_texture_target_;
Antoine Laboure5a2101a2018-11-07 23:36:27270 // This RasterBufferProvider will modify the resource outside of the
271 // GL command stream. So resources should not become available for reuse
272 // until they are not in use by the gpu anymore, which a fence is used
273 // to determine.
274 backing->wait_on_fence_required = true;
275 backing->shared_image_interface =
276 compositor_context_provider_->SharedImageInterface();
danakjbd636052018-02-06 18:28:49277 resource.set_gpu_backing(std::move(backing));
278 }
279 ZeroCopyGpuBacking* backing =
280 static_cast<ZeroCopyGpuBacking*>(resource.gpu_backing());
281
John Abd-El-Malek61fd3e12021-04-29 19:01:30282 return std::make_unique<ZeroCopyRasterBufferImpl>(
283 gpu_memory_buffer_manager_, shutdown_event_, resource, backing);
prashant.nb4d4f492016-04-29 12:51:28284}
285
Sunny Sachanandani5f5419e22017-05-12 20:35:30286void ZeroCopyRasterBufferProvider::Flush() {}
287
Colin Blundell68d83e72023-03-17 07:49:28288viz::SharedImageFormat ZeroCopyRasterBufferProvider::GetFormat() const {
danakja32578c2018-04-25 21:18:36289 return tile_format_;
prashant.nb4d4f492016-04-29 12:51:28290}
291
danakja32578c2018-04-25 21:18:36292bool ZeroCopyRasterBufferProvider::IsResourcePremultiplied() const {
Eric Karl247f09c2018-03-15 02:06:36293 return true;
294}
295
ericrk5ac42f322016-07-14 01:06:51296bool ZeroCopyRasterBufferProvider::CanPartialRasterIntoProvidedResource()
297 const {
ericrkeeda58992016-07-07 02:34:27298 return false;
299}
300
ericrk7f6a27f2017-01-31 22:34:32301bool ZeroCopyRasterBufferProvider::IsResourceReadyToDraw(
Steve Kobesad278432023-07-05 21:35:41302 const ResourcePool::InUsePoolResource& resource) {
ericrk7f6a27f2017-01-31 22:34:32303 // Zero-copy resources are immediately ready to draw.
304 return true;
305}
306
307uint64_t ZeroCopyRasterBufferProvider::SetReadyToDrawCallback(
danakj4e871d82018-01-18 21:56:57308 const std::vector<const ResourcePool::InUsePoolResource*>& resources,
kylechar4bb144d2019-01-11 20:42:07309 base::OnceClosure callback,
Steve Kobesad278432023-07-05 21:35:41310 uint64_t pending_callback_id) {
ericrk7f6a27f2017-01-31 22:34:32311 // Zero-copy resources are immediately ready to draw.
312 return 0;
313}
314
John Abd-El-Malek61fd3e12021-04-29 19:01:30315void ZeroCopyRasterBufferProvider::SetShutdownEvent(
316 base::WaitableEvent* shutdown_event) {
317 shutdown_event_ = shutdown_event;
318}
319
prashant.nb4d4f492016-04-29 12:51:28320void ZeroCopyRasterBufferProvider::Shutdown() {}
321
prashant.nb4d4f492016-04-29 12:51:28322} // namespace cc