Avi Drissman | 3f7a9d8 | 2022-09-08 20:55:42 | [diff] [blame] | 1 | // Copyright 2013 The Chromium Authors |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 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/raster/zero_copy_raster_buffer_provider.h" |
| 6 | |
| 7 | #include <stdint.h> |
| 8 | |
| 9 | #include <algorithm> |
Chris Blume | d435433 | 2020-11-11 08:40:16 | [diff] [blame] | 10 | #include <utility> |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 11 | |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 12 | #include "base/memory/raw_ptr.h" |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 13 | #include "base/trace_event/process_memory_dump.h" |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 14 | #include "base/trace_event/trace_event.h" |
David 'Digit' Turner | 59a8748 | 2018-10-29 13:27:16 | [diff] [blame] | 15 | #include "base/trace_event/traced_value.h" |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 16 | #include "cc/resources/resource_pool.h" |
danakj | 57baa77 | 2018-05-29 15:59:14 | [diff] [blame] | 17 | #include "components/viz/client/client_resource_provider.h" |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 18 | #include "components/viz/common/gpu/context_provider.h" |
Fady Samuel | 555c8d1 | 2017-07-07 23:14:09 | [diff] [blame] | 19 | #include "components/viz/common/resources/platform_color.h" |
danakj | bf124ca | 2018-01-04 16:35:51 | [diff] [blame] | 20 | #include "components/viz/common/resources/resource_format_utils.h" |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 21 | #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 22 | #include "gpu/command_buffer/client/shared_image_interface.h" |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 23 | #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 24 | #include "gpu/command_buffer/common/shared_image_trace_utils.h" |
| 25 | #include "gpu/command_buffer/common/shared_image_usage.h" |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 26 | #include "ui/gfx/buffer_format_util.h" |
| 27 | #include "ui/gfx/gpu_memory_buffer.h" |
| 28 | |
| 29 | namespace cc { |
| 30 | namespace { |
| 31 | |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 32 | constexpr static auto kBufferUsage = gfx::BufferUsage::GPU_READ_CPU_READ_WRITE; |
| 33 | |
| 34 | // Subclass for InUsePoolResource that holds ownership of a zero-copy backing |
| 35 | // and does cleanup of the backing when destroyed. |
| 36 | class ZeroCopyGpuBacking : public ResourcePool::GpuBacking { |
| 37 | public: |
| 38 | ~ZeroCopyGpuBacking() override { |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 39 | if (mailbox.IsZero()) |
| 40 | return; |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 41 | if (returned_sync_token.HasData()) |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 42 | shared_image_interface->DestroySharedImage(returned_sync_token, mailbox); |
| 43 | else if (mailbox_sync_token.HasData()) |
| 44 | shared_image_interface->DestroySharedImage(mailbox_sync_token, mailbox); |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 45 | } |
| 46 | |
Alexandr Ilin | 0443a8f | 2018-07-20 20:14:50 | [diff] [blame] | 47 | void OnMemoryDump( |
| 48 | base::trace_event::ProcessMemoryDump* pmd, |
| 49 | const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid, |
| 50 | uint64_t tracing_process_id, |
| 51 | int importance) const override { |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 52 | if (!gpu_memory_buffer) |
Alexandr Ilin | 0443a8f | 2018-07-20 20:14:50 | [diff] [blame] | 53 | return; |
| 54 | gpu_memory_buffer->OnMemoryDump(pmd, buffer_dump_guid, tracing_process_id, |
| 55 | importance); |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 56 | } |
| 57 | |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 58 | // The SharedImageInterface used to clean up the shared image. |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 59 | raw_ptr<gpu::SharedImageInterface> shared_image_interface = nullptr; |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 60 | // The backing for zero-copy gpu resources. The |texture_id| is bound to |
| 61 | // this. |
| 62 | std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer; |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 63 | }; |
| 64 | |
| 65 | // RasterBuffer for the zero copy upload, which is given to the raster worker |
| 66 | // threads for raster/upload. |
Daniel Bratell | 1bddcb33 | 2017-11-21 11:08:29 | [diff] [blame] | 67 | class ZeroCopyRasterBufferImpl : public RasterBuffer { |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 68 | public: |
danakj | 4e871d8 | 2018-01-18 21:56:57 | [diff] [blame] | 69 | ZeroCopyRasterBufferImpl( |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 70 | gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, |
John Abd-El-Malek | 61fd3e1 | 2021-04-29 19:01:30 | [diff] [blame] | 71 | base::WaitableEvent* shutdown_event, |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 72 | const ResourcePool::InUsePoolResource& in_use_resource, |
| 73 | ZeroCopyGpuBacking* backing) |
| 74 | : backing_(backing), |
| 75 | gpu_memory_buffer_manager_(gpu_memory_buffer_manager), |
John Abd-El-Malek | 61fd3e1 | 2021-04-29 19:01:30 | [diff] [blame] | 76 | shutdown_event_(shutdown_event), |
danakj | 4e871d8 | 2018-01-18 21:56:57 | [diff] [blame] | 77 | resource_size_(in_use_resource.size()), |
Colin Blundell | 1190bd9 | 2023-03-21 11:49:05 | [diff] [blame^] | 78 | format_(in_use_resource.format()), |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 79 | resource_color_space_(in_use_resource.color_space()), |
| 80 | gpu_memory_buffer_(std::move(backing_->gpu_memory_buffer)) {} |
Vladimir Levin | f06d1cd7 | 2019-03-13 18:24:10 | [diff] [blame] | 81 | ZeroCopyRasterBufferImpl(const ZeroCopyRasterBufferImpl&) = delete; |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 82 | |
| 83 | ~ZeroCopyRasterBufferImpl() override { |
Antoine Labour | 6363d820 | 2018-10-29 22:36:01 | [diff] [blame] | 84 | // If GpuMemoryBuffer allocation failed (https://crbug.com/554541), then |
| 85 | // we don't have anything to give to the display compositor, so we report a |
| 86 | // zero mailbox that will result in checkerboarding. |
| 87 | if (!gpu_memory_buffer_) { |
| 88 | DCHECK(backing_->mailbox.IsZero()); |
| 89 | return; |
| 90 | } |
| 91 | |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 92 | // This is destroyed on the compositor thread when raster is complete, but |
| 93 | // before the backing is prepared for export to the display compositor. So |
| 94 | // we can set up the texture and SyncToken here. |
| 95 | // TODO(danakj): This could be done with the worker context in Playback. Do |
| 96 | // we need to do things in IsResourceReadyToDraw() and OrderingBarrier then? |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 97 | gpu::SharedImageInterface* sii = backing_->shared_image_interface; |
| 98 | if (backing_->mailbox.IsZero()) { |
Michael Tang | 8240038 | 2022-10-03 20:22:13 | [diff] [blame] | 99 | uint32_t usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | |
| 100 | gpu::SHARED_IMAGE_USAGE_SCANOUT; |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 101 | // Make a mailbox for export of the GpuMemoryBuffer to the display |
| 102 | // compositor. |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 103 | backing_->mailbox = sii->CreateSharedImage( |
| 104 | gpu_memory_buffer_.get(), gpu_memory_buffer_manager_, |
| 105 | resource_color_space_, kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, |
| 106 | usage); |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 107 | } else { |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 108 | sii->UpdateSharedImage(backing_->returned_sync_token, backing_->mailbox); |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 109 | } |
| 110 | |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 111 | backing_->mailbox_sync_token = sii->GenUnverifiedSyncToken(); |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 112 | backing_->gpu_memory_buffer = std::move(gpu_memory_buffer_); |
| 113 | } |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 114 | |
Vladimir Levin | f06d1cd7 | 2019-03-13 18:24:10 | [diff] [blame] | 115 | ZeroCopyRasterBufferImpl& operator=(const ZeroCopyRasterBufferImpl&) = delete; |
| 116 | |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 117 | // Overridden from RasterBuffer: |
Khushal | 49836ab | 2018-07-25 02:08:45 | [diff] [blame] | 118 | void Playback(const RasterSource* raster_source, |
| 119 | const gfx::Rect& raster_full_rect, |
| 120 | const gfx::Rect& raster_dirty_rect, |
| 121 | uint64_t new_content_id, |
| 122 | const gfx::AxisTransform2d& transform, |
| 123 | const RasterSource::PlaybackSettings& playback_settings, |
| 124 | const GURL& url) override { |
prashant.n | 60e135b0 | 2016-06-08 04:12:23 | [diff] [blame] | 125 | TRACE_EVENT0("cc", "ZeroCopyRasterBuffer::Playback"); |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 126 | |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 127 | if (!gpu_memory_buffer_) { |
| 128 | gpu_memory_buffer_ = gpu_memory_buffer_manager_->CreateGpuMemoryBuffer( |
Colin Blundell | 0431623 | 2023-03-16 08:14:15 | [diff] [blame] | 129 | resource_size_, viz::BufferFormat(format_.resource_format()), |
| 130 | kBufferUsage, gpu::kNullSurfaceHandle, shutdown_event_); |
Christopher Cameron | 79358bd | 2018-08-02 04:31:44 | [diff] [blame] | 131 | // Note that GpuMemoryBuffer allocation can fail. |
| 132 | // https://crbug.com/554541 |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 133 | if (!gpu_memory_buffer_) |
| 134 | return; |
| 135 | } |
| 136 | |
Mark Yacoub | 72b0134 | 2019-07-17 22:56:56 | [diff] [blame] | 137 | DCHECK_EQ(1u, gfx::NumberOfPlanesForLinearBufferFormat( |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 138 | gpu_memory_buffer_->GetFormat())); |
| 139 | bool rv = gpu_memory_buffer_->Map(); |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 140 | DCHECK(rv); |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 141 | DCHECK(gpu_memory_buffer_->memory(0)); |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 142 | // RasterBufferProvider::PlaybackToMemory only supports unsigned strides. |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 143 | DCHECK_GE(gpu_memory_buffer_->stride(0), 0); |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 144 | |
| 145 | // TODO(danakj): Implement partial raster with raster_dirty_rect. |
| 146 | RasterBufferProvider::PlaybackToMemory( |
Colin Blundell | 0431623 | 2023-03-16 08:14:15 | [diff] [blame] | 147 | gpu_memory_buffer_->memory(0), format_, resource_size_, |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 148 | gpu_memory_buffer_->stride(0), raster_source, raster_full_rect, |
danakj | a32578c | 2018-04-25 21:18:36 | [diff] [blame] | 149 | raster_full_rect, transform, resource_color_space_, |
| 150 | /*gpu_compositing=*/true, playback_settings); |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 151 | gpu_memory_buffer_->Unmap(); |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 152 | } |
| 153 | |
Francois Doray | affe091 | 2020-06-30 20:29:21 | [diff] [blame] | 154 | bool SupportsBackgroundThreadPriority() const override { return true; } |
| 155 | |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 156 | private: |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 157 | // This field may only be used on the compositor thread. |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 158 | raw_ptr<ZeroCopyGpuBacking> backing_; |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 159 | |
| 160 | // These fields are for use on the worker thread. |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 161 | raw_ptr<gpu::GpuMemoryBufferManager> gpu_memory_buffer_manager_; |
| 162 | raw_ptr<base::WaitableEvent> shutdown_event_; |
danakj | 4e871d8 | 2018-01-18 21:56:57 | [diff] [blame] | 163 | gfx::Size resource_size_; |
Colin Blundell | 0431623 | 2023-03-16 08:14:15 | [diff] [blame] | 164 | viz::SharedImageFormat format_; |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 165 | gfx::ColorSpace resource_color_space_; |
| 166 | std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_; |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 167 | }; |
| 168 | |
| 169 | } // namespace |
| 170 | |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 171 | ZeroCopyRasterBufferProvider::ZeroCopyRasterBufferProvider( |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 172 | gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, |
| 173 | viz::ContextProvider* compositor_context_provider, |
Colin Blundell | d2396b8 | 2023-03-20 09:23:15 | [diff] [blame] | 174 | viz::SharedImageFormat tile_format) |
danakj | a32578c | 2018-04-25 21:18:36 | [diff] [blame] | 175 | : gpu_memory_buffer_manager_(gpu_memory_buffer_manager), |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 176 | compositor_context_provider_(compositor_context_provider), |
Colin Blundell | d2396b8 | 2023-03-20 09:23:15 | [diff] [blame] | 177 | tile_format_(tile_format) {} |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 178 | |
Chris Watkins | f635329 | 2017-12-04 02:36:05 | [diff] [blame] | 179 | ZeroCopyRasterBufferProvider::~ZeroCopyRasterBufferProvider() = default; |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 180 | |
| 181 | std::unique_ptr<RasterBuffer> |
| 182 | ZeroCopyRasterBufferProvider::AcquireBufferForRaster( |
danakj | 4e871d8 | 2018-01-18 21:56:57 | [diff] [blame] | 183 | const ResourcePool::InUsePoolResource& resource, |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 184 | uint64_t resource_content_id, |
Andres Calderon Jaramillo | b6b26dc | 2019-11-25 21:24:05 | [diff] [blame] | 185 | uint64_t previous_content_id, |
Andres Calderon Jaramillo | 5057f23 | 2019-11-29 23:05:48 | [diff] [blame] | 186 | bool depends_on_at_raster_decodes, |
| 187 | bool depends_on_hardware_accelerated_jpeg_candidates, |
| 188 | bool depends_on_hardware_accelerated_webp_candidates) { |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 189 | if (!resource.gpu_backing()) { |
| 190 | auto backing = std::make_unique<ZeroCopyGpuBacking>(); |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 191 | const gpu::Capabilities& caps = |
| 192 | compositor_context_provider_->ContextCapabilities(); |
| 193 | backing->texture_target = gpu::GetBufferTextureTarget( |
Colin Blundell | 1190bd9 | 2023-03-21 11:49:05 | [diff] [blame^] | 194 | kBufferUsage, BufferFormat(resource.format().resource_format()), caps); |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 195 | backing->overlay_candidate = true; |
| 196 | // This RasterBufferProvider will modify the resource outside of the |
| 197 | // GL command stream. So resources should not become available for reuse |
| 198 | // until they are not in use by the gpu anymore, which a fence is used |
| 199 | // to determine. |
| 200 | backing->wait_on_fence_required = true; |
| 201 | backing->shared_image_interface = |
| 202 | compositor_context_provider_->SharedImageInterface(); |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 203 | resource.set_gpu_backing(std::move(backing)); |
| 204 | } |
| 205 | ZeroCopyGpuBacking* backing = |
| 206 | static_cast<ZeroCopyGpuBacking*>(resource.gpu_backing()); |
| 207 | |
John Abd-El-Malek | 61fd3e1 | 2021-04-29 19:01:30 | [diff] [blame] | 208 | return std::make_unique<ZeroCopyRasterBufferImpl>( |
| 209 | gpu_memory_buffer_manager_, shutdown_event_, resource, backing); |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 210 | } |
| 211 | |
Sunny Sachanandani | 5f5419e2 | 2017-05-12 20:35:30 | [diff] [blame] | 212 | void ZeroCopyRasterBufferProvider::Flush() {} |
| 213 | |
Colin Blundell | 68d83e7 | 2023-03-17 07:49:28 | [diff] [blame] | 214 | viz::SharedImageFormat ZeroCopyRasterBufferProvider::GetFormat() const { |
danakj | a32578c | 2018-04-25 21:18:36 | [diff] [blame] | 215 | return tile_format_; |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 216 | } |
| 217 | |
danakj | a32578c | 2018-04-25 21:18:36 | [diff] [blame] | 218 | bool ZeroCopyRasterBufferProvider::IsResourcePremultiplied() const { |
Eric Karl | 247f09c | 2018-03-15 02:06:36 | [diff] [blame] | 219 | return true; |
| 220 | } |
| 221 | |
ericrk | 5ac42f32 | 2016-07-14 01:06:51 | [diff] [blame] | 222 | bool ZeroCopyRasterBufferProvider::CanPartialRasterIntoProvidedResource() |
| 223 | const { |
ericrk | eeda5899 | 2016-07-07 02:34:27 | [diff] [blame] | 224 | return false; |
| 225 | } |
| 226 | |
ericrk | 7f6a27f | 2017-01-31 22:34:32 | [diff] [blame] | 227 | bool ZeroCopyRasterBufferProvider::IsResourceReadyToDraw( |
danakj | 4e871d8 | 2018-01-18 21:56:57 | [diff] [blame] | 228 | const ResourcePool::InUsePoolResource& resource) const { |
ericrk | 7f6a27f | 2017-01-31 22:34:32 | [diff] [blame] | 229 | // Zero-copy resources are immediately ready to draw. |
| 230 | return true; |
| 231 | } |
| 232 | |
| 233 | uint64_t ZeroCopyRasterBufferProvider::SetReadyToDrawCallback( |
danakj | 4e871d8 | 2018-01-18 21:56:57 | [diff] [blame] | 234 | const std::vector<const ResourcePool::InUsePoolResource*>& resources, |
kylechar | 4bb144d | 2019-01-11 20:42:07 | [diff] [blame] | 235 | base::OnceClosure callback, |
ericrk | 7f6a27f | 2017-01-31 22:34:32 | [diff] [blame] | 236 | uint64_t pending_callback_id) const { |
| 237 | // Zero-copy resources are immediately ready to draw. |
| 238 | return 0; |
| 239 | } |
| 240 | |
John Abd-El-Malek | 61fd3e1 | 2021-04-29 19:01:30 | [diff] [blame] | 241 | void ZeroCopyRasterBufferProvider::SetShutdownEvent( |
| 242 | base::WaitableEvent* shutdown_event) { |
| 243 | shutdown_event_ = shutdown_event; |
| 244 | } |
| 245 | |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 246 | void ZeroCopyRasterBufferProvider::Shutdown() {} |
| 247 | |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 248 | } // namespace cc |