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" |
kylechar | ffcf091 | 2023-06-09 18:57:22 | [diff] [blame] | 18 | #include "components/viz/common/gpu/raster_context_provider.h" |
Fady Samuel | 555c8d1 | 2017-07-07 23:14:09 | [diff] [blame] | 19 | #include "components/viz/common/resources/platform_color.h" |
Colin Blundell | 81fb20ca | 2023-05-30 09:37:54 | [diff] [blame] | 20 | #include "components/viz/common/resources/shared_image_format_utils.h" |
Mingjing Zhang | 3f1265c | 2023-10-26 02:16:55 | [diff] [blame] | 21 | #include "gpu/command_buffer/client/client_shared_image.h" |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 22 | #include "gpu/command_buffer/client/shared_image_interface.h" |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 23 | #include "gpu/command_buffer/common/shared_image_trace_utils.h" |
| 24 | #include "gpu/command_buffer/common/shared_image_usage.h" |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 25 | #include "ui/gfx/buffer_format_util.h" |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 26 | |
| 27 | namespace cc { |
| 28 | namespace { |
| 29 | |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 30 | constexpr static auto kBufferUsage = gfx::BufferUsage::GPU_READ_CPU_READ_WRITE; |
| 31 | |
| 32 | // Subclass for InUsePoolResource that holds ownership of a zero-copy backing |
| 33 | // and does cleanup of the backing when destroyed. |
| 34 | class ZeroCopyGpuBacking : public ResourcePool::GpuBacking { |
| 35 | public: |
| 36 | ~ZeroCopyGpuBacking() override { |
Mingjing Zhang | 9a99ee4 | 2023-11-22 16:23:19 | [diff] [blame] | 37 | if (!shared_image) { |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 38 | return; |
luci-bisection@appspot.gserviceaccount.com | e9ab19e | 2023-11-10 17:28:31 | [diff] [blame] | 39 | } |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 40 | if (returned_sync_token.HasData()) |
Mingjing Zhang | 9a99ee4 | 2023-11-22 16:23:19 | [diff] [blame] | 41 | shared_image_interface->DestroySharedImage(returned_sync_token, |
| 42 | std::move(shared_image)); |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 43 | else if (mailbox_sync_token.HasData()) |
Mingjing Zhang | 9a99ee4 | 2023-11-22 16:23:19 | [diff] [blame] | 44 | shared_image_interface->DestroySharedImage(mailbox_sync_token, |
| 45 | std::move(shared_image)); |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 46 | } |
| 47 | |
Alexandr Ilin | 0443a8f | 2018-07-20 20:14:50 | [diff] [blame] | 48 | void OnMemoryDump( |
| 49 | base::trace_event::ProcessMemoryDump* pmd, |
| 50 | const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid, |
| 51 | uint64_t tracing_process_id, |
| 52 | int importance) const override { |
Colin Blundell | 0fd5a82 | 2023-12-08 17:31:47 | [diff] [blame] | 53 | if (!shared_image) { |
| 54 | return; |
Colin Blundell | 4281969 | 2023-09-25 15:24:28 | [diff] [blame] | 55 | } |
Colin Blundell | 0fd5a82 | 2023-12-08 17:31:47 | [diff] [blame] | 56 | auto mapping = shared_image->Map(); |
| 57 | if (!mapping) { |
| 58 | return; |
| 59 | } |
| 60 | mapping->OnMemoryDump(pmd, buffer_dump_guid, tracing_process_id, |
| 61 | importance); |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 62 | } |
| 63 | |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 64 | // The SharedImageInterface used to clean up the shared image. |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 65 | raw_ptr<gpu::SharedImageInterface> shared_image_interface = nullptr; |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 66 | }; |
| 67 | |
| 68 | // RasterBuffer for the zero copy upload, which is given to the raster worker |
| 69 | // threads for raster/upload. |
Daniel Bratell | 1bddcb33 | 2017-11-21 11:08:29 | [diff] [blame] | 70 | class ZeroCopyRasterBufferImpl : public RasterBuffer { |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 71 | public: |
danakj | 4e871d8 | 2018-01-18 21:56:57 | [diff] [blame] | 72 | ZeroCopyRasterBufferImpl( |
John Abd-El-Malek | 61fd3e1 | 2021-04-29 19:01:30 | [diff] [blame] | 73 | base::WaitableEvent* shutdown_event, |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 74 | const ResourcePool::InUsePoolResource& in_use_resource, |
| 75 | ZeroCopyGpuBacking* backing) |
| 76 | : backing_(backing), |
John Abd-El-Malek | 61fd3e1 | 2021-04-29 19:01:30 | [diff] [blame] | 77 | shutdown_event_(shutdown_event), |
danakj | 4e871d8 | 2018-01-18 21:56:57 | [diff] [blame] | 78 | resource_size_(in_use_resource.size()), |
Colin Blundell | 1190bd9 | 2023-03-21 11:49:05 | [diff] [blame] | 79 | format_(in_use_resource.format()), |
Colin Blundell | 0fd5a82 | 2023-12-08 17:31:47 | [diff] [blame] | 80 | resource_color_space_(in_use_resource.color_space()) {} |
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 { |
Colin Blundell | 0fd5a82 | 2023-12-08 17:31:47 | [diff] [blame] | 84 | // If MappableSharedImage 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 (!backing_->shared_image) { |
| 88 | return; |
Antoine Labour | 6363d820 | 2018-10-29 22:36:01 | [diff] [blame] | 89 | } |
| 90 | |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 91 | // This is destroyed on the compositor thread when raster is complete, but |
| 92 | // before the backing is prepared for export to the display compositor. So |
| 93 | // we can set up the texture and SyncToken here. |
| 94 | // TODO(danakj): This could be done with the worker context in Playback. Do |
| 95 | // we need to do things in IsResourceReadyToDraw() and OrderingBarrier then? |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 96 | gpu::SharedImageInterface* sii = backing_->shared_image_interface; |
Colin Blundell | 0fd5a82 | 2023-12-08 17:31:47 | [diff] [blame] | 97 | sii->UpdateSharedImage(backing_->returned_sync_token, |
| 98 | backing_->shared_image->mailbox()); |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 99 | |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 100 | backing_->mailbox_sync_token = sii->GenUnverifiedSyncToken(); |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 101 | } |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 102 | |
Vladimir Levin | f06d1cd7 | 2019-03-13 18:24:10 | [diff] [blame] | 103 | ZeroCopyRasterBufferImpl& operator=(const ZeroCopyRasterBufferImpl&) = delete; |
| 104 | |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 105 | // Overridden from RasterBuffer: |
Khushal | 49836ab | 2018-07-25 02:08:45 | [diff] [blame] | 106 | void Playback(const RasterSource* raster_source, |
| 107 | const gfx::Rect& raster_full_rect, |
| 108 | const gfx::Rect& raster_dirty_rect, |
| 109 | uint64_t new_content_id, |
| 110 | const gfx::AxisTransform2d& transform, |
| 111 | const RasterSource::PlaybackSettings& playback_settings, |
| 112 | const GURL& url) override { |
prashant.n | 60e135b0 | 2016-06-08 04:12:23 | [diff] [blame] | 113 | TRACE_EVENT0("cc", "ZeroCopyRasterBuffer::Playback"); |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 114 | |
Colin Blundell | 0fd5a82 | 2023-12-08 17:31:47 | [diff] [blame] | 115 | gpu::SharedImageInterface* sii = backing_->shared_image_interface; |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 116 | |
Colin Blundell | 0fd5a82 | 2023-12-08 17:31:47 | [diff] [blame] | 117 | // Create a MappableSI if necessary. |
| 118 | if (!backing_->shared_image) { |
| 119 | uint32_t usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | |
| 120 | gpu::SHARED_IMAGE_USAGE_SCANOUT; |
| 121 | backing_->shared_image = sii->CreateSharedImage( |
| 122 | format_, resource_size_, resource_color_space_, |
| 123 | kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, usage, |
| 124 | "ZeroCopyRasterTile", gpu::kNullSurfaceHandle, kBufferUsage); |
Mingjing Zhang | 9a99ee4 | 2023-11-22 16:23:19 | [diff] [blame] | 125 | if (!backing_->shared_image) { |
Colin Blundell | 0fd5a82 | 2023-12-08 17:31:47 | [diff] [blame] | 126 | LOG(ERROR) << "Creation of MappableSharedImage failed."; |
Colin Blundell | 4281969 | 2023-09-25 15:24:28 | [diff] [blame] | 127 | return; |
| 128 | } |
Colin Blundell | 0fd5a82 | 2023-12-08 17:31:47 | [diff] [blame] | 129 | } |
Colin Blundell | 4281969 | 2023-09-25 15:24:28 | [diff] [blame] | 130 | |
Colin Blundell | 0fd5a82 | 2023-12-08 17:31:47 | [diff] [blame] | 131 | std::unique_ptr<gpu::ClientSharedImage::ScopedMapping> mapping = |
| 132 | backing_->shared_image->Map(); |
| 133 | if (!mapping) { |
| 134 | LOG(ERROR) << "MapSharedImage Failed."; |
| 135 | sii->DestroySharedImage(gpu::SyncToken(), |
| 136 | std::move(backing_->shared_image)); |
| 137 | return; |
Colin Blundell | 4281969 | 2023-09-25 15:24:28 | [diff] [blame] | 138 | } |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 139 | |
| 140 | // TODO(danakj): Implement partial raster with raster_dirty_rect. |
| 141 | RasterBufferProvider::PlaybackToMemory( |
Colin Blundell | 0fd5a82 | 2023-12-08 17:31:47 | [diff] [blame] | 142 | mapping->Memory(0), format_, resource_size_, mapping->Stride(0), |
| 143 | raster_source, raster_full_rect, raster_full_rect, transform, |
| 144 | resource_color_space_, |
danakj | a32578c | 2018-04-25 21:18:36 | [diff] [blame] | 145 | /*gpu_compositing=*/true, playback_settings); |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 146 | } |
| 147 | |
Francois Doray | affe091 | 2020-06-30 20:29:21 | [diff] [blame] | 148 | bool SupportsBackgroundThreadPriority() const override { return true; } |
| 149 | |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 150 | private: |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 151 | // This field may only be used on the compositor thread. |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 152 | raw_ptr<ZeroCopyGpuBacking> backing_; |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 153 | |
| 154 | // These fields are for use on the worker thread. |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 155 | raw_ptr<base::WaitableEvent> shutdown_event_; |
danakj | 4e871d8 | 2018-01-18 21:56:57 | [diff] [blame] | 156 | gfx::Size resource_size_; |
Colin Blundell | 0431623 | 2023-03-16 08:14:15 | [diff] [blame] | 157 | viz::SharedImageFormat format_; |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 158 | gfx::ColorSpace resource_color_space_; |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 159 | }; |
| 160 | |
| 161 | } // namespace |
| 162 | |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 163 | ZeroCopyRasterBufferProvider::ZeroCopyRasterBufferProvider( |
kylechar | ffcf091 | 2023-06-09 18:57:22 | [diff] [blame] | 164 | viz::RasterContextProvider* compositor_context_provider, |
kylechar | 8cce494 | 2023-06-20 18:03:03 | [diff] [blame] | 165 | const RasterCapabilities& raster_caps) |
Colin Blundell | 0fd5a82 | 2023-12-08 17:31:47 | [diff] [blame] | 166 | : compositor_context_provider_(compositor_context_provider), |
kylechar | 58c09f7 | 2023-07-11 21:27:34 | [diff] [blame] | 167 | tile_format_(raster_caps.tile_format), |
| 168 | tile_texture_target_(raster_caps.tile_texture_target) {} |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 169 | |
Chris Watkins | f635329 | 2017-12-04 02:36:05 | [diff] [blame] | 170 | ZeroCopyRasterBufferProvider::~ZeroCopyRasterBufferProvider() = default; |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 171 | |
| 172 | std::unique_ptr<RasterBuffer> |
| 173 | ZeroCopyRasterBufferProvider::AcquireBufferForRaster( |
danakj | 4e871d8 | 2018-01-18 21:56:57 | [diff] [blame] | 174 | const ResourcePool::InUsePoolResource& resource, |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 175 | uint64_t resource_content_id, |
Andres Calderon Jaramillo | b6b26dc | 2019-11-25 21:24:05 | [diff] [blame] | 176 | uint64_t previous_content_id, |
Andres Calderon Jaramillo | 5057f23 | 2019-11-29 23:05:48 | [diff] [blame] | 177 | bool depends_on_at_raster_decodes, |
| 178 | bool depends_on_hardware_accelerated_jpeg_candidates, |
| 179 | bool depends_on_hardware_accelerated_webp_candidates) { |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 180 | if (!resource.gpu_backing()) { |
| 181 | auto backing = std::make_unique<ZeroCopyGpuBacking>(); |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 182 | backing->overlay_candidate = true; |
kylechar | 58c09f7 | 2023-07-11 21:27:34 | [diff] [blame] | 183 | backing->texture_target = tile_texture_target_; |
Antoine Labour | e5a2101a | 2018-11-07 23:36:27 | [diff] [blame] | 184 | // This RasterBufferProvider will modify the resource outside of the |
| 185 | // GL command stream. So resources should not become available for reuse |
| 186 | // until they are not in use by the gpu anymore, which a fence is used |
| 187 | // to determine. |
| 188 | backing->wait_on_fence_required = true; |
| 189 | backing->shared_image_interface = |
| 190 | compositor_context_provider_->SharedImageInterface(); |
danakj | bd63605 | 2018-02-06 18:28:49 | [diff] [blame] | 191 | resource.set_gpu_backing(std::move(backing)); |
| 192 | } |
| 193 | ZeroCopyGpuBacking* backing = |
| 194 | static_cast<ZeroCopyGpuBacking*>(resource.gpu_backing()); |
| 195 | |
Colin Blundell | 0fd5a82 | 2023-12-08 17:31:47 | [diff] [blame] | 196 | return std::make_unique<ZeroCopyRasterBufferImpl>(shutdown_event_, resource, |
| 197 | backing); |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 198 | } |
| 199 | |
Sunny Sachanandani | 5f5419e2 | 2017-05-12 20:35:30 | [diff] [blame] | 200 | void ZeroCopyRasterBufferProvider::Flush() {} |
| 201 | |
Colin Blundell | 68d83e7 | 2023-03-17 07:49:28 | [diff] [blame] | 202 | viz::SharedImageFormat ZeroCopyRasterBufferProvider::GetFormat() const { |
danakj | a32578c | 2018-04-25 21:18:36 | [diff] [blame] | 203 | return tile_format_; |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 204 | } |
| 205 | |
danakj | a32578c | 2018-04-25 21:18:36 | [diff] [blame] | 206 | bool ZeroCopyRasterBufferProvider::IsResourcePremultiplied() const { |
Eric Karl | 247f09c | 2018-03-15 02:06:36 | [diff] [blame] | 207 | return true; |
| 208 | } |
| 209 | |
ericrk | 5ac42f32 | 2016-07-14 01:06:51 | [diff] [blame] | 210 | bool ZeroCopyRasterBufferProvider::CanPartialRasterIntoProvidedResource() |
| 211 | const { |
ericrk | eeda5899 | 2016-07-07 02:34:27 | [diff] [blame] | 212 | return false; |
| 213 | } |
| 214 | |
ericrk | 7f6a27f | 2017-01-31 22:34:32 | [diff] [blame] | 215 | bool ZeroCopyRasterBufferProvider::IsResourceReadyToDraw( |
Steve Kobes | ad27843 | 2023-07-05 21:35:41 | [diff] [blame] | 216 | const ResourcePool::InUsePoolResource& resource) { |
ericrk | 7f6a27f | 2017-01-31 22:34:32 | [diff] [blame] | 217 | // Zero-copy resources are immediately ready to draw. |
| 218 | return true; |
| 219 | } |
| 220 | |
| 221 | uint64_t ZeroCopyRasterBufferProvider::SetReadyToDrawCallback( |
danakj | 4e871d8 | 2018-01-18 21:56:57 | [diff] [blame] | 222 | const std::vector<const ResourcePool::InUsePoolResource*>& resources, |
kylechar | 4bb144d | 2019-01-11 20:42:07 | [diff] [blame] | 223 | base::OnceClosure callback, |
Steve Kobes | ad27843 | 2023-07-05 21:35:41 | [diff] [blame] | 224 | uint64_t pending_callback_id) { |
ericrk | 7f6a27f | 2017-01-31 22:34:32 | [diff] [blame] | 225 | // Zero-copy resources are immediately ready to draw. |
| 226 | return 0; |
| 227 | } |
| 228 | |
John Abd-El-Malek | 61fd3e1 | 2021-04-29 19:01:30 | [diff] [blame] | 229 | void ZeroCopyRasterBufferProvider::SetShutdownEvent( |
| 230 | base::WaitableEvent* shutdown_event) { |
| 231 | shutdown_event_ = shutdown_event; |
| 232 | } |
| 233 | |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 234 | void ZeroCopyRasterBufferProvider::Shutdown() {} |
| 235 | |
prashant.n | b4d4f49 | 2016-04-29 12:51:28 | [diff] [blame] | 236 | } // namespace cc |