[go: nahoru, domu]

blob: c8121751f1ab90fee09e569a020b8c339beb4555 [file] [log] [blame]
prashant.nb4d4f492016-04-29 12:51:281// Copyright 2013 The Chromium Authors. All rights reserved.
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>
10
11#include "base/macros.h"
Antoine Laboure5a2101a2018-11-07 23:36:2712#include "base/trace_event/process_memory_dump.h"
prashant.nb4d4f492016-04-29 12:51:2813#include "base/trace_event/trace_event.h"
David 'Digit' Turner59a87482018-10-29 13:27:1614#include "base/trace_event/traced_value.h"
danakjbd636052018-02-06 18:28:4915#include "cc/resources/resource_pool.h"
danakj57baa772018-05-29 15:59:1416#include "components/viz/client/client_resource_provider.h"
danakjbd636052018-02-06 18:28:4917#include "components/viz/common/gpu/context_provider.h"
Fady Samuel555c8d12017-07-07 23:14:0918#include "components/viz/common/resources/platform_color.h"
danakjbf124ca2018-01-04 16:35:5119#include "components/viz/common/resources/resource_format_utils.h"
danakjbd636052018-02-06 18:28:4920#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
Antoine Laboure5a2101a2018-11-07 23:36:2721#include "gpu/command_buffer/client/shared_image_interface.h"
danakjbd636052018-02-06 18:28:4922#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
Antoine Laboure5a2101a2018-11-07 23:36:2723#include "gpu/command_buffer/common/shared_image_trace_utils.h"
24#include "gpu/command_buffer/common/shared_image_usage.h"
prashant.nb4d4f492016-04-29 12:51:2825#include "ui/gfx/buffer_format_util.h"
26#include "ui/gfx/gpu_memory_buffer.h"
27
28namespace cc {
29namespace {
30
danakjbd636052018-02-06 18:28:4931constexpr static auto kBufferUsage = gfx::BufferUsage::GPU_READ_CPU_READ_WRITE;
32
33// Subclass for InUsePoolResource that holds ownership of a zero-copy backing
34// and does cleanup of the backing when destroyed.
35class ZeroCopyGpuBacking : public ResourcePool::GpuBacking {
36 public:
37 ~ZeroCopyGpuBacking() override {
Antoine Laboure5a2101a2018-11-07 23:36:2738 if (mailbox.IsZero())
39 return;
danakjbd636052018-02-06 18:28:4940 if (returned_sync_token.HasData())
Antoine Laboure5a2101a2018-11-07 23:36:2741 shared_image_interface->DestroySharedImage(returned_sync_token, mailbox);
42 else if (mailbox_sync_token.HasData())
43 shared_image_interface->DestroySharedImage(mailbox_sync_token, mailbox);
danakjbd636052018-02-06 18:28:4944 }
45
Alexandr Ilin0443a8f2018-07-20 20:14:5046 void OnMemoryDump(
47 base::trace_event::ProcessMemoryDump* pmd,
48 const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
49 uint64_t tracing_process_id,
50 int importance) const override {
danakjbd636052018-02-06 18:28:4951 if (!gpu_memory_buffer)
Alexandr Ilin0443a8f2018-07-20 20:14:5052 return;
53 gpu_memory_buffer->OnMemoryDump(pmd, buffer_dump_guid, tracing_process_id,
54 importance);
danakjbd636052018-02-06 18:28:4955 }
56
Antoine Laboure5a2101a2018-11-07 23:36:2757 // The SharedImageInterface used to clean up the shared image.
58 gpu::SharedImageInterface* shared_image_interface = nullptr;
danakjbd636052018-02-06 18:28:4959 // The backing for zero-copy gpu resources. The |texture_id| is bound to
60 // this.
61 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer;
danakjbd636052018-02-06 18:28:4962};
63
64// RasterBuffer for the zero copy upload, which is given to the raster worker
65// threads for raster/upload.
Daniel Bratell1bddcb332017-11-21 11:08:2966class ZeroCopyRasterBufferImpl : public RasterBuffer {
prashant.nb4d4f492016-04-29 12:51:2867 public:
danakj4e871d82018-01-18 21:56:5768 ZeroCopyRasterBufferImpl(
danakjbd636052018-02-06 18:28:4969 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
70 const ResourcePool::InUsePoolResource& in_use_resource,
71 ZeroCopyGpuBacking* backing)
72 : backing_(backing),
73 gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
danakj4e871d82018-01-18 21:56:5774 resource_size_(in_use_resource.size()),
danakjbd636052018-02-06 18:28:4975 resource_format_(in_use_resource.format()),
76 resource_color_space_(in_use_resource.color_space()),
77 gpu_memory_buffer_(std::move(backing_->gpu_memory_buffer)) {}
78
79 ~ZeroCopyRasterBufferImpl() override {
Antoine Labour6363d8202018-10-29 22:36:0180 // If GpuMemoryBuffer allocation failed (https://crbug.com/554541), then
81 // we don't have anything to give to the display compositor, so we report a
82 // zero mailbox that will result in checkerboarding.
83 if (!gpu_memory_buffer_) {
84 DCHECK(backing_->mailbox.IsZero());
85 return;
86 }
87
danakjbd636052018-02-06 18:28:4988 // This is destroyed on the compositor thread when raster is complete, but
89 // before the backing is prepared for export to the display compositor. So
90 // we can set up the texture and SyncToken here.
91 // TODO(danakj): This could be done with the worker context in Playback. Do
92 // we need to do things in IsResourceReadyToDraw() and OrderingBarrier then?
Antoine Laboure5a2101a2018-11-07 23:36:2793 gpu::SharedImageInterface* sii = backing_->shared_image_interface;
94 if (backing_->mailbox.IsZero()) {
95 uint32_t usage =
96 gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT;
97 // Make a mailbox for export of the GpuMemoryBuffer to the display
98 // compositor.
99 backing_->mailbox = sii->CreateSharedImage(gpu_memory_buffer_.get(),
100 gpu_memory_buffer_manager_,
101 resource_color_space_, usage);
danakjbd636052018-02-06 18:28:49102 } else {
Antoine Laboure5a2101a2018-11-07 23:36:27103 sii->UpdateSharedImage(backing_->returned_sync_token, backing_->mailbox);
danakjbd636052018-02-06 18:28:49104 }
105
Antoine Laboure5a2101a2018-11-07 23:36:27106 backing_->mailbox_sync_token = sii->GenUnverifiedSyncToken();
danakjbd636052018-02-06 18:28:49107 backing_->gpu_memory_buffer = std::move(gpu_memory_buffer_);
108 }
prashant.nb4d4f492016-04-29 12:51:28109
110 // Overridden from RasterBuffer:
Khushal49836ab2018-07-25 02:08:45111 void Playback(const RasterSource* raster_source,
112 const gfx::Rect& raster_full_rect,
113 const gfx::Rect& raster_dirty_rect,
114 uint64_t new_content_id,
115 const gfx::AxisTransform2d& transform,
116 const RasterSource::PlaybackSettings& playback_settings,
117 const GURL& url) override {
prashant.n60e135b02016-06-08 04:12:23118 TRACE_EVENT0("cc", "ZeroCopyRasterBuffer::Playback");
prashant.nb4d4f492016-04-29 12:51:28119
danakjbd636052018-02-06 18:28:49120 if (!gpu_memory_buffer_) {
121 gpu_memory_buffer_ = gpu_memory_buffer_manager_->CreateGpuMemoryBuffer(
122 resource_size_, viz::BufferFormat(resource_format_), kBufferUsage,
123 gpu::kNullSurfaceHandle);
Christopher Cameron79358bd2018-08-02 04:31:44124 // Note that GpuMemoryBuffer allocation can fail.
125 // https://crbug.com/554541
danakjbd636052018-02-06 18:28:49126 if (!gpu_memory_buffer_)
127 return;
128 }
129
130 DCHECK_EQ(1u, gfx::NumberOfPlanesForBufferFormat(
131 gpu_memory_buffer_->GetFormat()));
132 bool rv = gpu_memory_buffer_->Map();
prashant.nb4d4f492016-04-29 12:51:28133 DCHECK(rv);
danakjbd636052018-02-06 18:28:49134 DCHECK(gpu_memory_buffer_->memory(0));
prashant.nb4d4f492016-04-29 12:51:28135 // RasterBufferProvider::PlaybackToMemory only supports unsigned strides.
danakjbd636052018-02-06 18:28:49136 DCHECK_GE(gpu_memory_buffer_->stride(0), 0);
prashant.nb4d4f492016-04-29 12:51:28137
138 // TODO(danakj): Implement partial raster with raster_dirty_rect.
139 RasterBufferProvider::PlaybackToMemory(
danakjbd636052018-02-06 18:28:49140 gpu_memory_buffer_->memory(0), resource_format_, resource_size_,
141 gpu_memory_buffer_->stride(0), raster_source, raster_full_rect,
danakja32578c2018-04-25 21:18:36142 raster_full_rect, transform, resource_color_space_,
143 /*gpu_compositing=*/true, playback_settings);
danakjbd636052018-02-06 18:28:49144 gpu_memory_buffer_->Unmap();
prashant.nb4d4f492016-04-29 12:51:28145 }
146
147 private:
danakjbd636052018-02-06 18:28:49148 // This field may only be used on the compositor thread.
149 ZeroCopyGpuBacking* backing_;
150
151 // These fields are for use on the worker thread.
152 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
danakj4e871d82018-01-18 21:56:57153 gfx::Size resource_size_;
154 viz::ResourceFormat resource_format_;
danakjbd636052018-02-06 18:28:49155 gfx::ColorSpace resource_color_space_;
156 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
prashant.nb4d4f492016-04-29 12:51:28157
Daniel Bratell1bddcb332017-11-21 11:08:29158 DISALLOW_COPY_AND_ASSIGN(ZeroCopyRasterBufferImpl);
prashant.nb4d4f492016-04-29 12:51:28159};
160
161} // namespace
162
prashant.nb4d4f492016-04-29 12:51:28163ZeroCopyRasterBufferProvider::ZeroCopyRasterBufferProvider(
danakjbd636052018-02-06 18:28:49164 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
165 viz::ContextProvider* compositor_context_provider,
danakja32578c2018-04-25 21:18:36166 viz::ResourceFormat tile_format)
167 : gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
danakjbd636052018-02-06 18:28:49168 compositor_context_provider_(compositor_context_provider),
danakja32578c2018-04-25 21:18:36169 tile_format_(tile_format) {}
prashant.nb4d4f492016-04-29 12:51:28170
Chris Watkinsf6353292017-12-04 02:36:05171ZeroCopyRasterBufferProvider::~ZeroCopyRasterBufferProvider() = default;
prashant.nb4d4f492016-04-29 12:51:28172
173std::unique_ptr<RasterBuffer>
174ZeroCopyRasterBufferProvider::AcquireBufferForRaster(
danakj4e871d82018-01-18 21:56:57175 const ResourcePool::InUsePoolResource& resource,
prashant.nb4d4f492016-04-29 12:51:28176 uint64_t resource_content_id,
177 uint64_t previous_content_id) {
danakjbd636052018-02-06 18:28:49178 if (!resource.gpu_backing()) {
179 auto backing = std::make_unique<ZeroCopyGpuBacking>();
Antoine Laboure5a2101a2018-11-07 23:36:27180 const gpu::Capabilities& caps =
181 compositor_context_provider_->ContextCapabilities();
182 backing->texture_target = gpu::GetBufferTextureTarget(
183 gfx::BufferUsage::SCANOUT, BufferFormat(resource.format()), caps);
184 backing->overlay_candidate = true;
185 // This RasterBufferProvider will modify the resource outside of the
186 // GL command stream. So resources should not become available for reuse
187 // until they are not in use by the gpu anymore, which a fence is used
188 // to determine.
189 backing->wait_on_fence_required = true;
190 backing->shared_image_interface =
191 compositor_context_provider_->SharedImageInterface();
danakjbd636052018-02-06 18:28:49192 resource.set_gpu_backing(std::move(backing));
193 }
194 ZeroCopyGpuBacking* backing =
195 static_cast<ZeroCopyGpuBacking*>(resource.gpu_backing());
196
Antoine Laboure5a2101a2018-11-07 23:36:27197 return std::make_unique<ZeroCopyRasterBufferImpl>(gpu_memory_buffer_manager_,
198 resource, backing);
prashant.nb4d4f492016-04-29 12:51:28199}
200
Sunny Sachanandani5f5419e22017-05-12 20:35:30201void ZeroCopyRasterBufferProvider::Flush() {}
202
danakja32578c2018-04-25 21:18:36203viz::ResourceFormat ZeroCopyRasterBufferProvider::GetResourceFormat() const {
204 return tile_format_;
prashant.nb4d4f492016-04-29 12:51:28205}
206
danakja32578c2018-04-25 21:18:36207bool ZeroCopyRasterBufferProvider::IsResourceSwizzleRequired() const {
208 return !viz::PlatformColor::SameComponentOrder(GetResourceFormat());
prashant.nb4d4f492016-04-29 12:51:28209}
210
danakja32578c2018-04-25 21:18:36211bool ZeroCopyRasterBufferProvider::IsResourcePremultiplied() const {
Eric Karl247f09c2018-03-15 02:06:36212 return true;
213}
214
ericrk5ac42f322016-07-14 01:06:51215bool ZeroCopyRasterBufferProvider::CanPartialRasterIntoProvidedResource()
216 const {
ericrkeeda58992016-07-07 02:34:27217 return false;
218}
219
ericrk7f6a27f2017-01-31 22:34:32220bool ZeroCopyRasterBufferProvider::IsResourceReadyToDraw(
danakj4e871d82018-01-18 21:56:57221 const ResourcePool::InUsePoolResource& resource) const {
ericrk7f6a27f2017-01-31 22:34:32222 // Zero-copy resources are immediately ready to draw.
223 return true;
224}
225
226uint64_t ZeroCopyRasterBufferProvider::SetReadyToDrawCallback(
danakj4e871d82018-01-18 21:56:57227 const std::vector<const ResourcePool::InUsePoolResource*>& resources,
ericrk7f6a27f2017-01-31 22:34:32228 const base::Closure& callback,
229 uint64_t pending_callback_id) const {
230 // Zero-copy resources are immediately ready to draw.
231 return 0;
232}
233
prashant.nb4d4f492016-04-29 12:51:28234void ZeroCopyRasterBufferProvider::Shutdown() {}
235
Khushalcd8fbb772018-10-16 22:46:14236bool ZeroCopyRasterBufferProvider::CheckRasterFinishedQueries() {
237 return false;
238}
239
prashant.nb4d4f492016-04-29 12:51:28240} // namespace cc