[go: nahoru, domu]

blob: ed755ba4cc7b966c5d1efc1cd15dc1c8d3c964be [file] [log] [blame]
reveman@chromium.orgb5641b92014-02-15 14:21:581// Copyright 2014 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
prashant.nb4d4f492016-04-29 12:51:285#include "cc/raster/gpu_raster_buffer_provider.h"
reveman@chromium.orgb5641b92014-02-15 14:21:586
avi02a4d172015-12-21 06:14:367#include <stdint.h>
8
ernstm69fedbd2014-09-18 01:23:419#include <algorithm>
10
avi02a4d172015-12-21 06:14:3611#include "base/macros.h"
danakj60bc3bc2016-04-09 00:24:4812#include "base/memory/ptr_util.h"
ericrke4027312016-06-30 00:12:4213#include "base/metrics/histogram_macros.h"
ssid904ce3b2015-01-27 15:20:1614#include "base/trace_event/trace_event.h"
ericrkc7c9e3f2016-07-01 17:30:1615#include "cc/base/histograms.h"
Adrienne Walker436a7752017-08-28 23:33:0916#include "cc/paint/display_item_list.h"
enne5a9630362017-02-24 23:41:0317#include "cc/paint/paint_canvas.h"
Adrienne Walker436a7752017-08-28 23:33:0918#include "cc/paint/paint_recorder.h"
chrishtrac41ff92017-03-17 05:07:3019#include "cc/raster/raster_source.h"
danakj920156852015-05-18 20:22:2920#include "cc/raster/scoped_gpu_raster.h"
reveman@chromium.orgb5641b92014-02-15 14:21:5821#include "cc/resources/resource.h"
Victor Miura29b7ea3d2017-12-19 20:23:5922#include "components/viz/common/gpu/context_provider.h"
23#include "components/viz/common/gpu/raster_context_provider.h"
danakjaf3170e2018-02-09 17:31:5824#include "components/viz/common/gpu/texture_allocation.h"
danakjbf124ca2018-01-04 16:35:5125#include "components/viz/common/resources/resource_format_utils.h"
danakjaf3170e2018-02-09 17:31:5826#include "gpu/GLES2/gl2extchromium.h"
ericrk7f6a27f2017-01-31 22:34:3227#include "gpu/command_buffer/client/context_support.h"
reveman@chromium.orgb5641b92014-02-15 14:21:5828#include "gpu/command_buffer/client/gles2_interface.h"
Victor Miura3a4ad4f82017-12-13 06:03:4529#include "gpu/command_buffer/client/raster_interface.h"
danakjaf3170e2018-02-09 17:31:5830#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
hendrikw04cea972014-09-23 20:50:5331#include "third_party/skia/include/core/SkMultiPictureDraw.h"
32#include "third_party/skia/include/core/SkPictureRecorder.h"
reveman47560ab2014-09-18 19:39:2133#include "third_party/skia/include/core/SkSurface.h"
reveman@chromium.orgb5641b92014-02-15 14:21:5834#include "third_party/skia/include/gpu/GrContext.h"
Adrienne Walker436a7752017-08-28 23:33:0935#include "ui/gfx/geometry/axis_transform2d.h"
danakjaf3170e2018-02-09 17:31:5836#include "ui/gl/trace_util.h"
reveman@chromium.orgb5641b92014-02-15 14:21:5837
38namespace cc {
reveman47560ab2014-09-18 19:39:2139namespace {
40
Adrienne Walker436a7752017-08-28 23:33:0941static void RasterizeSourceOOP(
42 const RasterSource* raster_source,
43 bool resource_has_previous_content,
danakjaf3170e2018-02-09 17:31:5844 const gpu::Mailbox& mailbox,
45 GLenum texture_target,
46 bool texture_is_overlay_candidate,
47 bool texture_storage_allocated,
48 const gfx::Size& resource_size,
49 viz::ResourceFormat resource_format,
50 const gfx::ColorSpace& color_space,
Adrienne Walker436a7752017-08-28 23:33:0951 const gfx::Rect& raster_full_rect,
52 const gfx::Rect& playback_rect,
53 const gfx::AxisTransform2d& transform,
54 const RasterSource::PlaybackSettings& playback_settings,
Victor Miura29b7ea3d2017-12-19 20:23:5955 viz::RasterContextProvider* context_provider,
Adrienne Walker436a7752017-08-28 23:33:0956 bool use_distance_field_text,
57 int msaa_sample_count) {
Victor Miura29b7ea3d2017-12-19 20:23:5958 gpu::raster::RasterInterface* ri = context_provider->RasterInterface();
danakjaf3170e2018-02-09 17:31:5859 GLuint texture_id = ri->CreateAndConsumeTextureCHROMIUM(mailbox.name);
60 if (!texture_storage_allocated) {
61 viz::TextureAllocation alloc = {texture_id, texture_target,
62 texture_is_overlay_candidate};
63 viz::TextureAllocation::AllocateStorage(
64 ri, context_provider->ContextCapabilities(), resource_format,
65 resource_size, alloc, color_space);
66 }
Adrienne Walker436a7752017-08-28 23:33:0967
danakjaf3170e2018-02-09 17:31:5868 // TODO(enne): Use the |texture_target|? GpuMemoryBuffer backed textures don't
69 // use GL_TEXTURE_2D.
70 ri->BeginRasterCHROMIUM(
71 texture_id, raster_source->background_color(), msaa_sample_count,
72 playback_settings.use_lcd_text, use_distance_field_text,
73 viz::ResourceFormatToClosestSkColorType(resource_format),
74 playback_settings.raster_color_space);
Adrienne Walkerbc5cd82e2017-10-31 21:58:1575 float recording_to_raster_scale =
76 transform.scale() / raster_source->recording_scale_factor();
Adrienne Walker51c8e382018-02-06 20:30:3377 gfx::Size content_size = raster_source->GetContentSize(transform.scale());
78 // TODO(enne): could skip the clear on new textures, as the service side has
79 // to do that anyway. resource_has_previous_content implies that the texture
80 // is not new, but the reverse does not hold, so more plumbing is needed.
Victor Miura3a4ad4f82017-12-13 06:03:4581 ri->RasterCHROMIUM(raster_source->GetDisplayItemList().get(),
Adrienne Walker51c8e382018-02-06 20:30:3382 playback_settings.image_provider, content_size,
83 raster_full_rect, playback_rect, transform.translation(),
84 recording_to_raster_scale,
85 raster_source->requires_clear());
Victor Miura3a4ad4f82017-12-13 06:03:4586 ri->EndRasterCHROMIUM();
Adrienne Walker436a7752017-08-28 23:33:0987
Victor Miura3a4ad4f82017-12-13 06:03:4588 ri->DeleteTextures(1, &texture_id);
Adrienne Walker436a7752017-08-28 23:33:0989}
90
Victor Miura406891a2017-12-16 03:58:3091// The following class is needed to correctly reset GL state when rendering to
92// SkCanvases with a GrContext on a RasterInterface enabled context.
93class ScopedGrContextAccess {
94 public:
Victor Miura29b7ea3d2017-12-19 20:23:5995 explicit ScopedGrContextAccess(viz::RasterContextProvider* context_provider)
Victor Miura406891a2017-12-16 03:58:3096 : context_provider_(context_provider) {
Victor Miura29b7ea3d2017-12-19 20:23:5997 gpu::raster::RasterInterface* ri = context_provider_->RasterInterface();
Victor Miura406891a2017-12-16 03:58:3098 ri->BeginGpuRaster();
99
100 class GrContext* gr_context = context_provider_->GrContext();
101 gr_context->resetContext();
102 }
103 ~ScopedGrContextAccess() {
Victor Miura29b7ea3d2017-12-19 20:23:59104 gpu::raster::RasterInterface* ri = context_provider_->RasterInterface();
Victor Miura406891a2017-12-16 03:58:30105 ri->EndGpuRaster();
106 }
107
108 private:
Victor Miura29b7ea3d2017-12-19 20:23:59109 viz::RasterContextProvider* context_provider_;
Victor Miura406891a2017-12-16 03:58:30110};
111
vmiuraf7c765c2016-12-03 21:02:32112static void RasterizeSource(
sunnyps5d6ff0d02016-06-28 00:40:11113 const RasterSource* raster_source,
114 bool resource_has_previous_content,
danakjaf3170e2018-02-09 17:31:58115 const gpu::Mailbox& mailbox,
116 GLenum texture_target,
117 bool texture_is_overlay_candidate,
118 bool texture_storage_allocated,
119 const gfx::Size& resource_size,
120 viz::ResourceFormat resource_format,
121 const gfx::ColorSpace& color_space,
sunnyps5d6ff0d02016-06-28 00:40:11122 const gfx::Rect& raster_full_rect,
Adrienne Walker436a7752017-08-28 23:33:09123 const gfx::Rect& playback_rect,
trchen178ac912017-04-04 10:11:10124 const gfx::AxisTransform2d& transform,
vmiuraf7c765c2016-12-03 21:02:32125 const RasterSource::PlaybackSettings& playback_settings,
Victor Miura29b7ea3d2017-12-19 20:23:59126 viz::RasterContextProvider* context_provider,
vmiuraf7c765c2016-12-03 21:02:32127 bool use_distance_field_text,
128 int msaa_sample_count) {
Victor Miura406891a2017-12-16 03:58:30129 ScopedGrContextAccess gr_context_access(context_provider);
sunnyps5d6ff0d02016-06-28 00:40:11130
Victor Miura29b7ea3d2017-12-19 20:23:59131 gpu::raster::RasterInterface* ri = context_provider->RasterInterface();
danakjaf3170e2018-02-09 17:31:58132 GLuint texture_id = ri->CreateAndConsumeTextureCHROMIUM(mailbox.name);
133 if (!texture_storage_allocated) {
134 viz::TextureAllocation alloc = {texture_id, texture_target,
135 texture_is_overlay_candidate};
136 viz::TextureAllocation::AllocateStorage(
137 ri, context_provider->ContextCapabilities(), resource_format,
138 resource_size, alloc, color_space);
139 }
Sunny Sachanandani0cb875e2017-08-15 02:54:52140
141 {
Xu Xing4d363812018-01-11 01:59:34142 LayerTreeResourceProvider::ScopedSkSurface scoped_surface(
danakjaf3170e2018-02-09 17:31:58143 context_provider->GrContext(), texture_id, texture_target,
144 resource_size, resource_format, use_distance_field_text,
Sunny Sachanandani0cb875e2017-08-15 02:54:52145 playback_settings.use_lcd_text, msaa_sample_count);
146
147 SkSurface* surface = scoped_surface.surface();
148
149 // Allocating an SkSurface will fail after a lost context. Pretend we
150 // rasterized, as the contents of the resource don't matter anymore.
151 if (!surface) {
152 DLOG(ERROR) << "Failed to allocate raster surface";
153 return;
154 }
155
Sunny Sachanandani0cb875e2017-08-15 02:54:52156 SkCanvas* canvas = surface->getCanvas();
157
158 // As an optimization, inform Skia to discard when not doing partial raster.
159 if (raster_full_rect == playback_rect)
160 canvas->discard();
161
Adrienne Walker51c8e382018-02-06 20:30:33162 gfx::Size content_size = raster_source->GetContentSize(transform.scale());
danakjaf3170e2018-02-09 17:31:58163 raster_source->PlaybackToCanvas(canvas, color_space, content_size,
164 raster_full_rect, playback_rect, transform,
165 playback_settings);
ccameron220942362017-02-06 20:29:19166 }
vmiuraf7c765c2016-12-03 21:02:32167
Victor Miura3a4ad4f82017-12-13 06:03:45168 ri->DeleteTextures(1, &texture_id);
sunnyps5d6ff0d02016-06-28 00:40:11169}
reveman47560ab2014-09-18 19:39:21170
171} // namespace
vmiura78b69282015-02-14 00:01:17172
danakjaf3170e2018-02-09 17:31:58173// Subclass for InUsePoolResource that holds ownership of a gpu-rastered backing
174// and does cleanup of the backing when destroyed.
175class GpuRasterBufferProvider::GpuRasterBacking
176 : public ResourcePool::GpuBacking {
177 public:
178 ~GpuRasterBacking() override {
179 gpu::gles2::GLES2Interface* gl = compositor_context_provider->ContextGL();
180 if (returned_sync_token.HasData())
181 gl->WaitSyncTokenCHROMIUM(returned_sync_token.GetConstData());
182 if (mailbox_sync_token.HasData())
183 gl->WaitSyncTokenCHROMIUM(mailbox_sync_token.GetConstData());
184 if (texture_id)
185 gl->DeleteTextures(1, &texture_id);
186 }
187
188 base::trace_event::MemoryAllocatorDumpGuid MemoryDumpGuid(
189 uint64_t tracing_process_id) override {
190 return gl::GetGLTextureClientGUIDForTracing(
191 compositor_context_provider->ContextSupport()->ShareGroupTracingGUID(),
192 texture_id);
193 }
194 base::UnguessableToken SharedMemoryGuid() override { return {}; }
195
196 // The ContextProvider used to clean up the texture id.
197 viz::ContextProvider* compositor_context_provider = nullptr;
198 // The texture backing of the resource.
199 GLuint texture_id = 0;
200 // The allocation of storage for the |texture_id| is deferred, and this tracks
201 // if it has been done.
202 bool storage_allocated = false;
203};
204
sunnyps5d6ff0d02016-06-28 00:40:11205GpuRasterBufferProvider::RasterBufferImpl::RasterBufferImpl(
206 GpuRasterBufferProvider* client,
danakjaf3170e2018-02-09 17:31:58207 const ResourcePool::InUsePoolResource& in_use_resource,
208 GpuRasterBacking* backing,
sunnyps5d6ff0d02016-06-28 00:40:11209 bool resource_has_previous_content)
210 : client_(client),
danakjaf3170e2018-02-09 17:31:58211 backing_(backing),
212 resource_size_(in_use_resource.size()),
213 resource_format_(in_use_resource.format()),
214 color_space_(in_use_resource.color_space()),
215 resource_has_previous_content_(resource_has_previous_content),
216 returned_sync_token_(backing->returned_sync_token),
217 mailbox_(backing->mailbox),
218 texture_target_(backing->texture_target),
219 texture_is_overlay_candidate_(backing->overlay_candidate),
220 texture_storage_allocated_(backing->storage_allocated) {
sunnyps5d6ff0d02016-06-28 00:40:11221 client_->pending_raster_buffers_.insert(this);
222}
223
224GpuRasterBufferProvider::RasterBufferImpl::~RasterBufferImpl() {
225 client_->pending_raster_buffers_.erase(this);
danakjaf3170e2018-02-09 17:31:58226
227 // This SyncToken was created on the worker context after rastering the
228 // texture content.
229 backing_->mailbox_sync_token = after_raster_sync_token_;
230 if (after_raster_sync_token_.HasData()) {
231 // The returned SyncToken was waited on in Playback. We know Playback
232 // happened if the |after_raster_sync_token_| was set.
233 backing_->returned_sync_token = gpu::SyncToken();
234 }
235 backing_->storage_allocated = texture_storage_allocated_;
sunnyps5d6ff0d02016-06-28 00:40:11236}
237
238void GpuRasterBufferProvider::RasterBufferImpl::Playback(
239 const RasterSource* raster_source,
240 const gfx::Rect& raster_full_rect,
241 const gfx::Rect& raster_dirty_rect,
242 uint64_t new_content_id,
trchen178ac912017-04-04 10:11:10243 const gfx::AxisTransform2d& transform,
sunnyps5d6ff0d02016-06-28 00:40:11244 const RasterSource::PlaybackSettings& playback_settings) {
245 TRACE_EVENT0("cc", "GpuRasterBuffer::Playback");
danakjaf3170e2018-02-09 17:31:58246 // Either a SyncToken had to be made in OrderingBarrier, because a texture
247 // was made in AcquireBufferForRaster, or a texture already existed and we're
248 // reusing it. In that case a SyncToken was on the GpuBacking that we must
249 // wait on befor using the texture.
250 if (returned_sync_token_.HasData())
251 before_raster_sync_token_ = returned_sync_token_;
252 // The |sync_token_| passed in here was created on the compositor thread, or
253 // given back with the texture for reuse. This call returns another SyncToken
254 // generated on the worker thread to synchronize with after the raster is
255 // complete.
256 after_raster_sync_token_ = client_->PlaybackOnWorkerThread(
257 mailbox_, texture_target_, texture_is_overlay_candidate_,
258 texture_storage_allocated_, before_raster_sync_token_, resource_size_,
259 resource_format_, color_space_, resource_has_previous_content_,
260 raster_source, raster_full_rect, raster_dirty_rect, new_content_id,
261 transform, playback_settings);
262 texture_storage_allocated_ = true;
sunnyps5d6ff0d02016-06-28 00:40:11263}
264
prashant.nb4d4f492016-04-29 12:51:28265GpuRasterBufferProvider::GpuRasterBufferProvider(
Xu Xing32549162017-07-17 22:25:43266 viz::ContextProvider* compositor_context_provider,
Victor Miura29b7ea3d2017-12-19 20:23:59267 viz::RasterContextProvider* worker_context_provider,
Xu Xingb57edf32017-08-22 04:18:47268 LayerTreeResourceProvider* resource_provider,
hendrikw59d449482015-04-04 00:44:32269 bool use_distance_field_text,
danakjaf3170e2018-02-09 17:31:58270 bool use_gpu_memory_buffer_resources,
sunnyps5d6ff0d02016-06-28 00:40:11271 int gpu_rasterization_msaa_sample_count,
Fady Samuel555c8d12017-07-07 23:14:09272 viz::ResourceFormat preferred_tile_format,
Adrienne Walker436a7752017-08-28 23:33:09273 bool enable_oop_rasterization)
danakj0de0c95a2016-05-25 01:42:49274 : compositor_context_provider_(compositor_context_provider),
sunnyps5d6ff0d02016-06-28 00:40:11275 worker_context_provider_(worker_context_provider),
276 resource_provider_(resource_provider),
277 use_distance_field_text_(use_distance_field_text),
danakjaf3170e2018-02-09 17:31:58278 use_gpu_memory_buffer_resources_(use_gpu_memory_buffer_resources),
sunnyps5d6ff0d02016-06-28 00:40:11279 msaa_sample_count_(gpu_rasterization_msaa_sample_count),
ericrkd03c005d2017-03-24 18:48:52280 preferred_tile_format_(preferred_tile_format),
Adrienne Walker436a7752017-08-28 23:33:09281 enable_oop_rasterization_(enable_oop_rasterization) {
sunnyps5d6ff0d02016-06-28 00:40:11282 DCHECK(compositor_context_provider);
283 DCHECK(worker_context_provider);
danakj0de0c95a2016-05-25 01:42:49284}
reveman@chromium.orgb5641b92014-02-15 14:21:58285
sunnyps5d6ff0d02016-06-28 00:40:11286GpuRasterBufferProvider::~GpuRasterBufferProvider() {
287 DCHECK(pending_raster_buffers_.empty());
288}
reveman@chromium.orgb5641b92014-02-15 14:21:58289
prashant.nb4d4f492016-04-29 12:51:28290std::unique_ptr<RasterBuffer> GpuRasterBufferProvider::AcquireBufferForRaster(
danakj4e871d82018-01-18 21:56:57291 const ResourcePool::InUsePoolResource& resource,
danakj510822aa2015-06-01 20:23:02292 uint64_t resource_content_id,
danakje0b54782015-05-29 22:47:52293 uint64_t previous_content_id) {
danakjaf3170e2018-02-09 17:31:58294 if (!resource.gpu_backing()) {
295 auto backing = std::make_unique<GpuRasterBacking>();
296 backing->compositor_context_provider = compositor_context_provider_;
297
298 gpu::gles2::GLES2Interface* gl = compositor_context_provider_->ContextGL();
299 const auto& caps = compositor_context_provider_->ContextCapabilities();
300
301 viz::TextureAllocation alloc = viz::TextureAllocation::MakeTextureId(
302 gl, caps, resource.format(), use_gpu_memory_buffer_resources_,
303 /*for_framebuffer_attachment=*/true);
304 backing->texture_id = alloc.texture_id;
305 backing->texture_target = alloc.texture_target;
306 backing->overlay_candidate = alloc.overlay_candidate;
307 backing->mailbox = gpu::Mailbox::Generate();
308 // The SyncToken in order to use this mailbox on another context will be
309 // generated later by OrderingBarrier(), once for all mailboxes made at a
310 // given time.
311 gl->ProduceTextureDirectCHROMIUM(backing->texture_id,
312 backing->mailbox.name);
313
314 resource.set_gpu_backing(std::move(backing));
315 }
316 GpuRasterBacking* backing =
317 static_cast<GpuRasterBacking*>(resource.gpu_backing());
318
sunnyps5d6ff0d02016-06-28 00:40:11319 bool resource_has_previous_content =
320 resource_content_id && resource_content_id == previous_content_id;
danakjaf3170e2018-02-09 17:31:58321 return std::make_unique<RasterBufferImpl>(this, resource, backing,
danakj4e871d82018-01-18 21:56:57322 resource_has_previous_content);
reveman@chromium.orgb5641b92014-02-15 14:21:58323}
324
sunnyps12074d3d2016-06-21 01:57:48325void GpuRasterBufferProvider::OrderingBarrier() {
prashant.nb4d4f492016-04-29 12:51:28326 TRACE_EVENT0("cc", "GpuRasterBufferProvider::OrderingBarrier");
sunnyps5d6ff0d02016-06-28 00:40:11327
328 gpu::gles2::GLES2Interface* gl = compositor_context_provider_->ContextGL();
Xu Xing4d363812018-01-11 01:59:34329 gpu::SyncToken sync_token =
330 LayerTreeResourceProvider::GenerateSyncTokenHelper(gl);
Victor Miuraff6488612017-12-21 04:16:15331 for (RasterBufferImpl* buffer : pending_raster_buffers_)
332 buffer->set_sync_token(sync_token);
sunnyps5d6ff0d02016-06-28 00:40:11333 pending_raster_buffers_.clear();
prashant.nb4d4f492016-04-29 12:51:28334}
335
Sunny Sachanandani5f5419e22017-05-12 20:35:30336void GpuRasterBufferProvider::Flush() {
Victor Miuraff6488612017-12-21 04:16:15337 compositor_context_provider_->ContextSupport()->FlushPendingWork();
Sunny Sachanandani5f5419e22017-05-12 20:35:30338}
339
Fady Samuel555c8d12017-07-07 23:14:09340viz::ResourceFormat GpuRasterBufferProvider::GetResourceFormat(
prashant.nb4d4f492016-04-29 12:51:28341 bool must_support_alpha) const {
ericrkd03c005d2017-03-24 18:48:52342 if (resource_provider_->IsRenderBufferFormatSupported(
343 preferred_tile_format_) &&
344 (DoesResourceFormatSupportAlpha(preferred_tile_format_) ||
345 !must_support_alpha)) {
346 return preferred_tile_format_;
347 }
348
sunnyps5d6ff0d02016-06-28 00:40:11349 return resource_provider_->best_render_buffer_format();
prashant.nb4d4f492016-04-29 12:51:28350}
351
ericrkeeda58992016-07-07 02:34:27352bool GpuRasterBufferProvider::IsResourceSwizzleRequired(
prashant.nb4d4f492016-04-29 12:51:28353 bool must_support_alpha) const {
354 // This doesn't require a swizzle because we rasterize to the correct format.
355 return false;
356}
357
ericrk5ac42f322016-07-14 01:06:51358bool GpuRasterBufferProvider::CanPartialRasterIntoProvidedResource() const {
ericrkc9ed0832016-07-20 19:42:50359 // Partial raster doesn't support MSAA, as the MSAA resolve is unaware of clip
360 // rects.
361 // TODO(crbug.com/629683): See if we can work around this limitation.
362 return msaa_sample_count_ == 0;
ericrkeeda58992016-07-07 02:34:27363}
364
ericrk7f6a27f2017-01-31 22:34:32365bool GpuRasterBufferProvider::IsResourceReadyToDraw(
danakj4e871d82018-01-18 21:56:57366 const ResourcePool::InUsePoolResource& resource) const {
danakjaf3170e2018-02-09 17:31:58367 const gpu::SyncToken& sync_token = resource.gpu_backing()->mailbox_sync_token;
368 // This SyncToken() should have been set by calling OrderingBarrier() before
369 // calling this.
370 DCHECK(sync_token.HasData());
ericrk7f6a27f2017-01-31 22:34:32371
sunnyps74996292017-03-15 02:35:48372 // IsSyncTokenSignaled is thread-safe, no need for worker context lock.
373 return worker_context_provider_->ContextSupport()->IsSyncTokenSignaled(
ericrk7f6a27f2017-01-31 22:34:32374 sync_token);
375}
376
377uint64_t GpuRasterBufferProvider::SetReadyToDrawCallback(
danakj4e871d82018-01-18 21:56:57378 const std::vector<const ResourcePool::InUsePoolResource*>& resources,
ericrk7f6a27f2017-01-31 22:34:32379 const base::Closure& callback,
380 uint64_t pending_callback_id) const {
danakjaf3170e2018-02-09 17:31:58381 gpu::SyncToken latest_sync_token;
382 for (const auto* in_use : resources) {
383 const gpu::SyncToken& sync_token =
384 in_use->gpu_backing()->mailbox_sync_token;
385 if (sync_token.release_count() > latest_sync_token.release_count())
386 latest_sync_token = sync_token;
387 }
388 uint64_t callback_id = latest_sync_token.release_count();
ericrk7f6a27f2017-01-31 22:34:32389 DCHECK_NE(callback_id, 0u);
390
391 // If the callback is different from the one the caller is already waiting on,
sunnyps31c92fe2017-02-10 23:46:55392 // pass the callback through to SignalSyncToken. Otherwise the request is
ericrk7f6a27f2017-01-31 22:34:32393 // redundant.
394 if (callback_id != pending_callback_id) {
danakjaf3170e2018-02-09 17:31:58395 // Use the compositor context because we want this callback on the
396 // compositor thread.
397 compositor_context_provider_->ContextSupport()->SignalSyncToken(
398 latest_sync_token, callback);
ericrk7f6a27f2017-01-31 22:34:32399 }
400
401 return callback_id;
402}
403
sunnyps5d6ff0d02016-06-28 00:40:11404void GpuRasterBufferProvider::Shutdown() {
405 pending_raster_buffers_.clear();
406}
407
danakjaf3170e2018-02-09 17:31:58408gpu::SyncToken GpuRasterBufferProvider::PlaybackOnWorkerThread(
409 const gpu::Mailbox& mailbox,
410 GLenum texture_target,
411 bool texture_is_overlay_candidate,
412 bool texture_storage_allocated,
sunnyps5d6ff0d02016-06-28 00:40:11413 const gpu::SyncToken& sync_token,
danakjaf3170e2018-02-09 17:31:58414 const gfx::Size& resource_size,
415 viz::ResourceFormat resource_format,
416 const gfx::ColorSpace& color_space,
sunnyps5d6ff0d02016-06-28 00:40:11417 bool resource_has_previous_content,
418 const RasterSource* raster_source,
419 const gfx::Rect& raster_full_rect,
420 const gfx::Rect& raster_dirty_rect,
421 uint64_t new_content_id,
trchen178ac912017-04-04 10:11:10422 const gfx::AxisTransform2d& transform,
sunnyps5d6ff0d02016-06-28 00:40:11423 const RasterSource::PlaybackSettings& playback_settings) {
Victor Miura29b7ea3d2017-12-19 20:23:59424 viz::RasterContextProvider::ScopedRasterContextLock scoped_context(
Xu Xing32549162017-07-17 22:25:43425 worker_context_provider_);
Victor Miura29b7ea3d2017-12-19 20:23:59426 gpu::raster::RasterInterface* ri = scoped_context.RasterInterface();
Victor Miura3a4ad4f82017-12-13 06:03:45427 DCHECK(ri);
sunnyps5d6ff0d02016-06-28 00:40:11428
danakjaf3170e2018-02-09 17:31:58429 // Wait on the SyncToken that was created on the compositor thread after
430 // making the mailbox. This ensures that the mailbox we consume here is valid
431 // by the time the consume command executes.
Victor Miura3a4ad4f82017-12-13 06:03:45432 ri->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
sunnyps5d6ff0d02016-06-28 00:40:11433
Adrienne Walker436a7752017-08-28 23:33:09434 gfx::Rect playback_rect = raster_full_rect;
435 if (resource_has_previous_content) {
436 playback_rect.Intersect(raster_dirty_rect);
437 }
438 DCHECK(!playback_rect.IsEmpty())
439 << "Why are we rastering a tile that's not dirty?";
440
441 // Log a histogram of the percentage of pixels that were saved due to
442 // partial raster.
443 const char* client_name = GetClientNameForMetrics();
444 float full_rect_size = raster_full_rect.size().GetArea();
445 if (full_rect_size > 0 && client_name) {
446 float fraction_partial_rastered =
447 static_cast<float>(playback_rect.size().GetArea()) / full_rect_size;
448 float fraction_saved = 1.0f - fraction_partial_rastered;
449 UMA_HISTOGRAM_PERCENTAGE(
450 base::StringPrintf("Renderer4.%s.PartialRasterPercentageSaved.Gpu",
451 client_name),
452 100.0f * fraction_saved);
453 }
454
455 if (enable_oop_rasterization_) {
Adrienne Walker51c8e382018-02-06 20:30:33456 RasterizeSourceOOP(
danakjaf3170e2018-02-09 17:31:58457 raster_source, resource_has_previous_content, mailbox, texture_target,
458 texture_is_overlay_candidate, texture_storage_allocated, resource_size,
459 resource_format, color_space, raster_full_rect, playback_rect,
460 transform, playback_settings, worker_context_provider_,
461 use_distance_field_text_, msaa_sample_count_);
Adrienne Walker436a7752017-08-28 23:33:09462 } else {
danakjaf3170e2018-02-09 17:31:58463 RasterizeSource(raster_source, resource_has_previous_content, mailbox,
464 texture_target, texture_is_overlay_candidate,
465 texture_storage_allocated, resource_size, resource_format,
466 color_space, raster_full_rect, playback_rect, transform,
467 playback_settings, worker_context_provider_,
Adrienne Walker51c8e382018-02-06 20:30:33468 use_distance_field_text_, msaa_sample_count_);
Adrienne Walker436a7752017-08-28 23:33:09469 }
sunnyps5d6ff0d02016-06-28 00:40:11470
Sunny Sachanandani0cb875e2017-08-15 02:54:52471 // Generate sync token for cross context synchronization.
danakjaf3170e2018-02-09 17:31:58472 return LayerTreeResourceProvider::GenerateSyncTokenHelper(ri);
sunnyps5d6ff0d02016-06-28 00:40:11473}
prashant.nb4d4f492016-04-29 12:51:28474
reveman@chromium.orgb5641b92014-02-15 14:21:58475} // namespace cc