[go: nahoru, domu]

blob: 31368680eb1a463881ac6ed0e461a6b5ea919329 [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
Keishi Hattori0e45c022021-11-27 09:25:5212#include "base/memory/raw_ptr.h"
Antoine Laboure5a2101a2018-11-07 23:36:2713#include "base/trace_event/process_memory_dump.h"
prashant.nb4d4f492016-04-29 12:51:2814#include "base/trace_event/trace_event.h"
David 'Digit' Turner59a87482018-10-29 13:27:1615#include "base/trace_event/traced_value.h"
danakjbd636052018-02-06 18:28:4916#include "cc/resources/resource_pool.h"
danakj57baa772018-05-29 15:59:1417#include "components/viz/client/client_resource_provider.h"
danakjbd636052018-02-06 18:28:4918#include "components/viz/common/gpu/context_provider.h"
Fady Samuel555c8d12017-07-07 23:14:0919#include "components/viz/common/resources/platform_color.h"
danakjbf124ca2018-01-04 16:35:5120#include "components/viz/common/resources/resource_format_utils.h"
danakjbd636052018-02-06 18:28:4921#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
Antoine Laboure5a2101a2018-11-07 23:36:2722#include "gpu/command_buffer/client/shared_image_interface.h"
danakjbd636052018-02-06 18:28:4923#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
Antoine Laboure5a2101a2018-11-07 23:36:2724#include "gpu/command_buffer/common/shared_image_trace_utils.h"
25#include "gpu/command_buffer/common/shared_image_usage.h"
prashant.nb4d4f492016-04-29 12:51:2826#include "ui/gfx/buffer_format_util.h"
27#include "ui/gfx/gpu_memory_buffer.h"
28
29namespace cc {
30namespace {
31
danakjbd636052018-02-06 18:28:4932constexpr 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.
36class ZeroCopyGpuBacking : public ResourcePool::GpuBacking {
37 public:
38 ~ZeroCopyGpuBacking() override {
Antoine Laboure5a2101a2018-11-07 23:36:2739 if (mailbox.IsZero())
40 return;
danakjbd636052018-02-06 18:28:4941 if (returned_sync_token.HasData())
Antoine Laboure5a2101a2018-11-07 23:36:2742 shared_image_interface->DestroySharedImage(returned_sync_token, mailbox);
43 else if (mailbox_sync_token.HasData())
44 shared_image_interface->DestroySharedImage(mailbox_sync_token, mailbox);
danakjbd636052018-02-06 18:28:4945 }
46
Alexandr Ilin0443a8f2018-07-20 20:14:5047 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 {
danakjbd636052018-02-06 18:28:4952 if (!gpu_memory_buffer)
Alexandr Ilin0443a8f2018-07-20 20:14:5053 return;
54 gpu_memory_buffer->OnMemoryDump(pmd, buffer_dump_guid, tracing_process_id,
55 importance);
danakjbd636052018-02-06 18:28:4956 }
57
Antoine Laboure5a2101a2018-11-07 23:36:2758 // The SharedImageInterface used to clean up the shared image.
Keishi Hattori0e45c022021-11-27 09:25:5259 raw_ptr<gpu::SharedImageInterface> shared_image_interface = nullptr;
danakjbd636052018-02-06 18:28:4960 // The backing for zero-copy gpu resources. The |texture_id| is bound to
61 // this.
62 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer;
danakjbd636052018-02-06 18:28:4963};
64
65// RasterBuffer for the zero copy upload, which is given to the raster worker
66// threads for raster/upload.
Daniel Bratell1bddcb332017-11-21 11:08:2967class ZeroCopyRasterBufferImpl : public RasterBuffer {
prashant.nb4d4f492016-04-29 12:51:2868 public:
danakj4e871d82018-01-18 21:56:5769 ZeroCopyRasterBufferImpl(
danakjbd636052018-02-06 18:28:4970 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
John Abd-El-Malek61fd3e12021-04-29 19:01:3071 base::WaitableEvent* shutdown_event,
danakjbd636052018-02-06 18:28:4972 const ResourcePool::InUsePoolResource& in_use_resource,
73 ZeroCopyGpuBacking* backing)
74 : backing_(backing),
75 gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
John Abd-El-Malek61fd3e12021-04-29 19:01:3076 shutdown_event_(shutdown_event),
danakj4e871d82018-01-18 21:56:5777 resource_size_(in_use_resource.size()),
Colin Blundell1190bd92023-03-21 11:49:0578 format_(in_use_resource.format()),
danakjbd636052018-02-06 18:28:4979 resource_color_space_(in_use_resource.color_space()),
80 gpu_memory_buffer_(std::move(backing_->gpu_memory_buffer)) {}
Vladimir Levinf06d1cd72019-03-13 18:24:1081 ZeroCopyRasterBufferImpl(const ZeroCopyRasterBufferImpl&) = delete;
danakjbd636052018-02-06 18:28:4982
83 ~ZeroCopyRasterBufferImpl() override {
Antoine Labour6363d8202018-10-29 22:36:0184 // 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
danakjbd636052018-02-06 18:28:4992 // 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 Laboure5a2101a2018-11-07 23:36:2797 gpu::SharedImageInterface* sii = backing_->shared_image_interface;
98 if (backing_->mailbox.IsZero()) {
Michael Tang82400382022-10-03 20:22:1399 uint32_t usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ |
100 gpu::SHARED_IMAGE_USAGE_SCANOUT;
Antoine Laboure5a2101a2018-11-07 23:36:27101 // Make a mailbox for export of the GpuMemoryBuffer to the display
102 // compositor.
Nathan Zabriskie659c2742020-07-16 03:49:32103 backing_->mailbox = sii->CreateSharedImage(
104 gpu_memory_buffer_.get(), gpu_memory_buffer_manager_,
105 resource_color_space_, kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType,
106 usage);
danakjbd636052018-02-06 18:28:49107 } else {
Antoine Laboure5a2101a2018-11-07 23:36:27108 sii->UpdateSharedImage(backing_->returned_sync_token, backing_->mailbox);
danakjbd636052018-02-06 18:28:49109 }
110
Antoine Laboure5a2101a2018-11-07 23:36:27111 backing_->mailbox_sync_token = sii->GenUnverifiedSyncToken();
danakjbd636052018-02-06 18:28:49112 backing_->gpu_memory_buffer = std::move(gpu_memory_buffer_);
113 }
prashant.nb4d4f492016-04-29 12:51:28114
Vladimir Levinf06d1cd72019-03-13 18:24:10115 ZeroCopyRasterBufferImpl& operator=(const ZeroCopyRasterBufferImpl&) = delete;
116
prashant.nb4d4f492016-04-29 12:51:28117 // Overridden from RasterBuffer:
Khushal49836ab2018-07-25 02:08:45118 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.n60e135b02016-06-08 04:12:23125 TRACE_EVENT0("cc", "ZeroCopyRasterBuffer::Playback");
prashant.nb4d4f492016-04-29 12:51:28126
danakjbd636052018-02-06 18:28:49127 if (!gpu_memory_buffer_) {
128 gpu_memory_buffer_ = gpu_memory_buffer_manager_->CreateGpuMemoryBuffer(
Colin Blundell04316232023-03-16 08:14:15129 resource_size_, viz::BufferFormat(format_.resource_format()),
130 kBufferUsage, gpu::kNullSurfaceHandle, shutdown_event_);
Christopher Cameron79358bd2018-08-02 04:31:44131 // Note that GpuMemoryBuffer allocation can fail.
132 // https://crbug.com/554541
danakjbd636052018-02-06 18:28:49133 if (!gpu_memory_buffer_)
134 return;
135 }
136
Mark Yacoub72b01342019-07-17 22:56:56137 DCHECK_EQ(1u, gfx::NumberOfPlanesForLinearBufferFormat(
danakjbd636052018-02-06 18:28:49138 gpu_memory_buffer_->GetFormat()));
139 bool rv = gpu_memory_buffer_->Map();
prashant.nb4d4f492016-04-29 12:51:28140 DCHECK(rv);
danakjbd636052018-02-06 18:28:49141 DCHECK(gpu_memory_buffer_->memory(0));
prashant.nb4d4f492016-04-29 12:51:28142 // RasterBufferProvider::PlaybackToMemory only supports unsigned strides.
danakjbd636052018-02-06 18:28:49143 DCHECK_GE(gpu_memory_buffer_->stride(0), 0);
prashant.nb4d4f492016-04-29 12:51:28144
145 // TODO(danakj): Implement partial raster with raster_dirty_rect.
146 RasterBufferProvider::PlaybackToMemory(
Colin Blundell04316232023-03-16 08:14:15147 gpu_memory_buffer_->memory(0), format_, resource_size_,
danakjbd636052018-02-06 18:28:49148 gpu_memory_buffer_->stride(0), raster_source, raster_full_rect,
danakja32578c2018-04-25 21:18:36149 raster_full_rect, transform, resource_color_space_,
150 /*gpu_compositing=*/true, playback_settings);
danakjbd636052018-02-06 18:28:49151 gpu_memory_buffer_->Unmap();
prashant.nb4d4f492016-04-29 12:51:28152 }
153
Francois Dorayaffe0912020-06-30 20:29:21154 bool SupportsBackgroundThreadPriority() const override { return true; }
155
prashant.nb4d4f492016-04-29 12:51:28156 private:
danakjbd636052018-02-06 18:28:49157 // This field may only be used on the compositor thread.
Keishi Hattori0e45c022021-11-27 09:25:52158 raw_ptr<ZeroCopyGpuBacking> backing_;
danakjbd636052018-02-06 18:28:49159
160 // These fields are for use on the worker thread.
Keishi Hattori0e45c022021-11-27 09:25:52161 raw_ptr<gpu::GpuMemoryBufferManager> gpu_memory_buffer_manager_;
162 raw_ptr<base::WaitableEvent> shutdown_event_;
danakj4e871d82018-01-18 21:56:57163 gfx::Size resource_size_;
Colin Blundell04316232023-03-16 08:14:15164 viz::SharedImageFormat format_;
danakjbd636052018-02-06 18:28:49165 gfx::ColorSpace resource_color_space_;
166 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
prashant.nb4d4f492016-04-29 12:51:28167};
168
169} // namespace
170
prashant.nb4d4f492016-04-29 12:51:28171ZeroCopyRasterBufferProvider::ZeroCopyRasterBufferProvider(
danakjbd636052018-02-06 18:28:49172 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
173 viz::ContextProvider* compositor_context_provider,
Colin Blundelld2396b82023-03-20 09:23:15174 viz::SharedImageFormat tile_format)
danakja32578c2018-04-25 21:18:36175 : gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
danakjbd636052018-02-06 18:28:49176 compositor_context_provider_(compositor_context_provider),
Colin Blundelld2396b82023-03-20 09:23:15177 tile_format_(tile_format) {}
prashant.nb4d4f492016-04-29 12:51:28178
Chris Watkinsf6353292017-12-04 02:36:05179ZeroCopyRasterBufferProvider::~ZeroCopyRasterBufferProvider() = default;
prashant.nb4d4f492016-04-29 12:51:28180
181std::unique_ptr<RasterBuffer>
182ZeroCopyRasterBufferProvider::AcquireBufferForRaster(
danakj4e871d82018-01-18 21:56:57183 const ResourcePool::InUsePoolResource& resource,
prashant.nb4d4f492016-04-29 12:51:28184 uint64_t resource_content_id,
Andres Calderon Jaramillob6b26dc2019-11-25 21:24:05185 uint64_t previous_content_id,
Andres Calderon Jaramillo5057f232019-11-29 23:05:48186 bool depends_on_at_raster_decodes,
187 bool depends_on_hardware_accelerated_jpeg_candidates,
188 bool depends_on_hardware_accelerated_webp_candidates) {
danakjbd636052018-02-06 18:28:49189 if (!resource.gpu_backing()) {
190 auto backing = std::make_unique<ZeroCopyGpuBacking>();
Antoine Laboure5a2101a2018-11-07 23:36:27191 const gpu::Capabilities& caps =
192 compositor_context_provider_->ContextCapabilities();
193 backing->texture_target = gpu::GetBufferTextureTarget(
Colin Blundell1190bd92023-03-21 11:49:05194 kBufferUsage, BufferFormat(resource.format().resource_format()), caps);
Antoine Laboure5a2101a2018-11-07 23:36:27195 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();
danakjbd636052018-02-06 18:28:49203 resource.set_gpu_backing(std::move(backing));
204 }
205 ZeroCopyGpuBacking* backing =
206 static_cast<ZeroCopyGpuBacking*>(resource.gpu_backing());
207
John Abd-El-Malek61fd3e12021-04-29 19:01:30208 return std::make_unique<ZeroCopyRasterBufferImpl>(
209 gpu_memory_buffer_manager_, shutdown_event_, resource, backing);
prashant.nb4d4f492016-04-29 12:51:28210}
211
Sunny Sachanandani5f5419e22017-05-12 20:35:30212void ZeroCopyRasterBufferProvider::Flush() {}
213
Colin Blundell68d83e72023-03-17 07:49:28214viz::SharedImageFormat ZeroCopyRasterBufferProvider::GetFormat() const {
danakja32578c2018-04-25 21:18:36215 return tile_format_;
prashant.nb4d4f492016-04-29 12:51:28216}
217
danakja32578c2018-04-25 21:18:36218bool ZeroCopyRasterBufferProvider::IsResourcePremultiplied() const {
Eric Karl247f09c2018-03-15 02:06:36219 return true;
220}
221
ericrk5ac42f322016-07-14 01:06:51222bool ZeroCopyRasterBufferProvider::CanPartialRasterIntoProvidedResource()
223 const {
ericrkeeda58992016-07-07 02:34:27224 return false;
225}
226
ericrk7f6a27f2017-01-31 22:34:32227bool ZeroCopyRasterBufferProvider::IsResourceReadyToDraw(
danakj4e871d82018-01-18 21:56:57228 const ResourcePool::InUsePoolResource& resource) const {
ericrk7f6a27f2017-01-31 22:34:32229 // Zero-copy resources are immediately ready to draw.
230 return true;
231}
232
233uint64_t ZeroCopyRasterBufferProvider::SetReadyToDrawCallback(
danakj4e871d82018-01-18 21:56:57234 const std::vector<const ResourcePool::InUsePoolResource*>& resources,
kylechar4bb144d2019-01-11 20:42:07235 base::OnceClosure callback,
ericrk7f6a27f2017-01-31 22:34:32236 uint64_t pending_callback_id) const {
237 // Zero-copy resources are immediately ready to draw.
238 return 0;
239}
240
John Abd-El-Malek61fd3e12021-04-29 19:01:30241void ZeroCopyRasterBufferProvider::SetShutdownEvent(
242 base::WaitableEvent* shutdown_event) {
243 shutdown_event_ = shutdown_event;
244}
245
prashant.nb4d4f492016-04-29 12:51:28246void ZeroCopyRasterBufferProvider::Shutdown() {}
247
prashant.nb4d4f492016-04-29 12:51:28248} // namespace cc