[go: nahoru, domu]

blob: fd2bb2118c864bf34b38715428100c2da24a431c [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"
prashant.nb4d4f492016-04-29 12:51:2812#include "base/trace_event/trace_event.h"
13#include "base/trace_event/trace_event_argument.h"
Xu Xingc101c862017-08-24 17:26:4514#include "cc/resources/layer_tree_resource_provider.h"
danakjbd636052018-02-06 18:28:4915#include "cc/resources/resource_pool.h"
16#include "components/viz/common/gpu/context_provider.h"
Fady Samuel555c8d12017-07-07 23:14:0917#include "components/viz/common/resources/platform_color.h"
danakjbf124ca2018-01-04 16:35:5118#include "components/viz/common/resources/resource_format_utils.h"
danakjbd636052018-02-06 18:28:4919#include "gpu/command_buffer/client/gles2_interface.h"
20#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
21#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
prashant.nb4d4f492016-04-29 12:51:2822#include "ui/gfx/buffer_format_util.h"
23#include "ui/gfx/gpu_memory_buffer.h"
24
25namespace cc {
26namespace {
27
danakjbd636052018-02-06 18:28:4928constexpr static auto kBufferUsage = gfx::BufferUsage::GPU_READ_CPU_READ_WRITE;
29
30// Subclass for InUsePoolResource that holds ownership of a zero-copy backing
31// and does cleanup of the backing when destroyed.
32class ZeroCopyGpuBacking : public ResourcePool::GpuBacking {
33 public:
34 ~ZeroCopyGpuBacking() override {
35 gpu::gles2::GLES2Interface* gl = compositor_context_provider->ContextGL();
36 if (returned_sync_token.HasData())
37 gl->WaitSyncTokenCHROMIUM(returned_sync_token.GetConstData());
38 if (texture_id)
39 gl->DeleteTextures(1, &texture_id);
40 if (image_id)
41 gl->DestroyImageCHROMIUM(image_id);
42 }
43
44 base::trace_event::MemoryAllocatorDumpGuid MemoryDumpGuid(
45 uint64_t tracing_process_id) override {
46 if (!gpu_memory_buffer)
47 return {};
48 return gpu_memory_buffer->GetGUIDForTracing(tracing_process_id);
49 }
50
51 base::UnguessableToken SharedMemoryGuid() override {
danakj2c201ec32018-02-08 18:25:3652 if (!gpu_memory_buffer)
53 return {};
danakjbd636052018-02-06 18:28:4954 return gpu_memory_buffer->GetHandle().handle.GetGUID();
55 }
56
57 // The ContextProvider used to clean up the texture and image ids.
58 viz::ContextProvider* compositor_context_provider = nullptr;
59 // The backing for zero-copy gpu resources. The |texture_id| is bound to
60 // this.
61 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer;
62 // The texture id bound to the GpuMemoryBuffer.
63 uint32_t texture_id = 0;
64 // The image id that associates the |gpu_memory_buffer| and the
65 // |texture_id|.
66 uint32_t image_id = 0;
67};
68
69// RasterBuffer for the zero copy upload, which is given to the raster worker
70// threads for raster/upload.
Daniel Bratell1bddcb332017-11-21 11:08:2971class ZeroCopyRasterBufferImpl : public RasterBuffer {
prashant.nb4d4f492016-04-29 12:51:2872 public:
danakj4e871d82018-01-18 21:56:5773 ZeroCopyRasterBufferImpl(
danakjbd636052018-02-06 18:28:4974 viz::ContextProvider* context_provider,
75 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
76 const ResourcePool::InUsePoolResource& in_use_resource,
77 ZeroCopyGpuBacking* backing)
78 : backing_(backing),
79 gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
danakj4e871d82018-01-18 21:56:5780 resource_size_(in_use_resource.size()),
danakjbd636052018-02-06 18:28:4981 resource_format_(in_use_resource.format()),
82 resource_color_space_(in_use_resource.color_space()),
83 gpu_memory_buffer_(std::move(backing_->gpu_memory_buffer)) {}
84
85 ~ZeroCopyRasterBufferImpl() override {
86 // This is destroyed on the compositor thread when raster is complete, but
87 // before the backing is prepared for export to the display compositor. So
88 // we can set up the texture and SyncToken here.
89 // TODO(danakj): This could be done with the worker context in Playback. Do
90 // we need to do things in IsResourceReadyToDraw() and OrderingBarrier then?
91 gpu::gles2::GLES2Interface* gl =
92 backing_->compositor_context_provider->ContextGL();
93 const gpu::Capabilities& caps =
94 backing_->compositor_context_provider->ContextCapabilities();
95
96 if (backing_->returned_sync_token.HasData()) {
97 gl->WaitSyncTokenCHROMIUM(backing_->returned_sync_token.GetConstData());
98 backing_->returned_sync_token = gpu::SyncToken();
99 }
100
101 if (!backing_->texture_id) {
102 // Make a texture and a mailbox for export of the GpuMemoryBuffer to the
103 // display compositor.
104 gl->GenTextures(1, &backing_->texture_id);
105 backing_->texture_target = gpu::GetBufferTextureTarget(
106 kBufferUsage, viz::BufferFormat(resource_format_), caps);
107 backing_->mailbox = gpu::Mailbox::Generate();
108 gl->ProduceTextureDirectCHROMIUM(backing_->texture_id,
109 backing_->mailbox.name);
danakjaf3170e2018-02-09 17:31:58110 backing_->overlay_candidate = true;
danakj63c438c2018-02-20 23:51:44111 // This RasterBufferProvider will modify the resource outside of the
112 // GL command stream. So resources should not become available for reuse
113 // until they are not in use by the gpu anymore, which a fence is used to
114 // determine.
115 backing_->wait_on_fence_required = true;
danakjbd636052018-02-06 18:28:49116
117 gl->BindTexture(backing_->texture_target, backing_->texture_id);
118 gl->TexParameteri(backing_->texture_target, GL_TEXTURE_MIN_FILTER,
119 GL_LINEAR);
120 gl->TexParameteri(backing_->texture_target, GL_TEXTURE_MAG_FILTER,
121 GL_LINEAR);
122 gl->TexParameteri(backing_->texture_target, GL_TEXTURE_WRAP_S,
123 GL_CLAMP_TO_EDGE);
124 gl->TexParameteri(backing_->texture_target, GL_TEXTURE_WRAP_T,
125 GL_CLAMP_TO_EDGE);
126 } else {
127 gl->BindTexture(backing_->texture_target, backing_->texture_id);
128 }
129
130 if (!backing_->image_id) {
131 // If GpuMemoryBuffer allocation failed (https://crbug.com/554541), then
132 // we don't have anything to give to the display compositor, but also no
133 // way to report an error, so we just make a texture but don't bind
134 // anything to it..
135 if (gpu_memory_buffer_) {
136 backing_->image_id = gl->CreateImageCHROMIUM(
137 gpu_memory_buffer_->AsClientBuffer(), resource_size_.width(),
138 resource_size_.height(), viz::GLInternalFormat(resource_format_));
139 gl->BindTexImage2DCHROMIUM(backing_->texture_target,
140 backing_->image_id);
141 }
142 } else {
143 gl->ReleaseTexImage2DCHROMIUM(backing_->texture_target,
144 backing_->image_id);
145 gl->BindTexImage2DCHROMIUM(backing_->texture_target, backing_->image_id);
146 }
147 gl->BindTexture(backing_->texture_target, 0);
148
149 backing_->mailbox_sync_token =
150 LayerTreeResourceProvider::GenerateSyncTokenHelper(gl);
151 backing_->gpu_memory_buffer = std::move(gpu_memory_buffer_);
152 }
prashant.nb4d4f492016-04-29 12:51:28153
154 // Overridden from RasterBuffer:
155 void Playback(
156 const RasterSource* raster_source,
157 const gfx::Rect& raster_full_rect,
158 const gfx::Rect& raster_dirty_rect,
159 uint64_t new_content_id,
trchen178ac912017-04-04 10:11:10160 const gfx::AxisTransform2d& transform,
prashant.nb4d4f492016-04-29 12:51:28161 const RasterSource::PlaybackSettings& playback_settings) override {
prashant.n60e135b02016-06-08 04:12:23162 TRACE_EVENT0("cc", "ZeroCopyRasterBuffer::Playback");
prashant.nb4d4f492016-04-29 12:51:28163
danakjbd636052018-02-06 18:28:49164 if (!gpu_memory_buffer_) {
165 gpu_memory_buffer_ = gpu_memory_buffer_manager_->CreateGpuMemoryBuffer(
166 resource_size_, viz::BufferFormat(resource_format_), kBufferUsage,
167 gpu::kNullSurfaceHandle);
168 // GpuMemoryBuffer allocation can fail (https://crbug.com/554541).
169 if (!gpu_memory_buffer_)
170 return;
Christopher Cameron3cf3eea2018-04-03 23:49:55171 gpu_memory_buffer_->SetColorSpace(resource_color_space_);
danakjbd636052018-02-06 18:28:49172 }
173
174 DCHECK_EQ(1u, gfx::NumberOfPlanesForBufferFormat(
175 gpu_memory_buffer_->GetFormat()));
176 bool rv = gpu_memory_buffer_->Map();
prashant.nb4d4f492016-04-29 12:51:28177 DCHECK(rv);
danakjbd636052018-02-06 18:28:49178 DCHECK(gpu_memory_buffer_->memory(0));
prashant.nb4d4f492016-04-29 12:51:28179 // RasterBufferProvider::PlaybackToMemory only supports unsigned strides.
danakjbd636052018-02-06 18:28:49180 DCHECK_GE(gpu_memory_buffer_->stride(0), 0);
prashant.nb4d4f492016-04-29 12:51:28181
182 // TODO(danakj): Implement partial raster with raster_dirty_rect.
183 RasterBufferProvider::PlaybackToMemory(
danakjbd636052018-02-06 18:28:49184 gpu_memory_buffer_->memory(0), resource_format_, resource_size_,
185 gpu_memory_buffer_->stride(0), raster_source, raster_full_rect,
danakja32578c2018-04-25 21:18:36186 raster_full_rect, transform, resource_color_space_,
187 /*gpu_compositing=*/true, playback_settings);
danakjbd636052018-02-06 18:28:49188 gpu_memory_buffer_->Unmap();
prashant.nb4d4f492016-04-29 12:51:28189 }
190
191 private:
danakjbd636052018-02-06 18:28:49192 // This field may only be used on the compositor thread.
193 ZeroCopyGpuBacking* backing_;
194
195 // These fields are for use on the worker thread.
196 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
danakj4e871d82018-01-18 21:56:57197 gfx::Size resource_size_;
198 viz::ResourceFormat resource_format_;
danakjbd636052018-02-06 18:28:49199 gfx::ColorSpace resource_color_space_;
200 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
prashant.nb4d4f492016-04-29 12:51:28201
Daniel Bratell1bddcb332017-11-21 11:08:29202 DISALLOW_COPY_AND_ASSIGN(ZeroCopyRasterBufferImpl);
prashant.nb4d4f492016-04-29 12:51:28203};
204
205} // namespace
206
prashant.nb4d4f492016-04-29 12:51:28207ZeroCopyRasterBufferProvider::ZeroCopyRasterBufferProvider(
danakjbd636052018-02-06 18:28:49208 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
209 viz::ContextProvider* compositor_context_provider,
danakja32578c2018-04-25 21:18:36210 viz::ResourceFormat tile_format)
211 : gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
danakjbd636052018-02-06 18:28:49212 compositor_context_provider_(compositor_context_provider),
danakja32578c2018-04-25 21:18:36213 tile_format_(tile_format) {}
prashant.nb4d4f492016-04-29 12:51:28214
Chris Watkinsf6353292017-12-04 02:36:05215ZeroCopyRasterBufferProvider::~ZeroCopyRasterBufferProvider() = default;
prashant.nb4d4f492016-04-29 12:51:28216
217std::unique_ptr<RasterBuffer>
218ZeroCopyRasterBufferProvider::AcquireBufferForRaster(
danakj4e871d82018-01-18 21:56:57219 const ResourcePool::InUsePoolResource& resource,
prashant.nb4d4f492016-04-29 12:51:28220 uint64_t resource_content_id,
221 uint64_t previous_content_id) {
danakjbd636052018-02-06 18:28:49222 if (!resource.gpu_backing()) {
223 auto backing = std::make_unique<ZeroCopyGpuBacking>();
224 backing->compositor_context_provider = compositor_context_provider_;
225 resource.set_gpu_backing(std::move(backing));
226 }
227 ZeroCopyGpuBacking* backing =
228 static_cast<ZeroCopyGpuBacking*>(resource.gpu_backing());
229
230 return std::make_unique<ZeroCopyRasterBufferImpl>(
231 compositor_context_provider_, gpu_memory_buffer_manager_, resource,
232 backing);
prashant.nb4d4f492016-04-29 12:51:28233}
234
Sunny Sachanandani5f5419e22017-05-12 20:35:30235void ZeroCopyRasterBufferProvider::Flush() {}
236
danakja32578c2018-04-25 21:18:36237viz::ResourceFormat ZeroCopyRasterBufferProvider::GetResourceFormat() const {
238 return tile_format_;
prashant.nb4d4f492016-04-29 12:51:28239}
240
danakja32578c2018-04-25 21:18:36241bool ZeroCopyRasterBufferProvider::IsResourceSwizzleRequired() const {
242 return !viz::PlatformColor::SameComponentOrder(GetResourceFormat());
prashant.nb4d4f492016-04-29 12:51:28243}
244
danakja32578c2018-04-25 21:18:36245bool ZeroCopyRasterBufferProvider::IsResourcePremultiplied() const {
Eric Karl247f09c2018-03-15 02:06:36246 return true;
247}
248
ericrk5ac42f322016-07-14 01:06:51249bool ZeroCopyRasterBufferProvider::CanPartialRasterIntoProvidedResource()
250 const {
ericrkeeda58992016-07-07 02:34:27251 return false;
252}
253
ericrk7f6a27f2017-01-31 22:34:32254bool ZeroCopyRasterBufferProvider::IsResourceReadyToDraw(
danakj4e871d82018-01-18 21:56:57255 const ResourcePool::InUsePoolResource& resource) const {
ericrk7f6a27f2017-01-31 22:34:32256 // Zero-copy resources are immediately ready to draw.
257 return true;
258}
259
260uint64_t ZeroCopyRasterBufferProvider::SetReadyToDrawCallback(
danakj4e871d82018-01-18 21:56:57261 const std::vector<const ResourcePool::InUsePoolResource*>& resources,
ericrk7f6a27f2017-01-31 22:34:32262 const base::Closure& callback,
263 uint64_t pending_callback_id) const {
264 // Zero-copy resources are immediately ready to draw.
265 return 0;
266}
267
prashant.nb4d4f492016-04-29 12:51:28268void ZeroCopyRasterBufferProvider::Shutdown() {}
269
270} // namespace cc