[go: nahoru, domu]

blob: f2dd3f92e5138b1f6b1dba88cb385e5767f2d281 [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"
ericrke4027312016-06-30 00:12:4212#include "base/metrics/histogram_macros.h"
ssid904ce3b2015-01-27 15:20:1613#include "base/trace_event/trace_event.h"
ericrkc7c9e3f2016-07-01 17:30:1614#include "cc/base/histograms.h"
Adrienne Walker436a7752017-08-28 23:33:0915#include "cc/paint/display_item_list.h"
enne5a9630362017-02-24 23:41:0316#include "cc/paint/paint_canvas.h"
Adrienne Walker436a7752017-08-28 23:33:0917#include "cc/paint/paint_recorder.h"
chrishtrac41ff92017-03-17 05:07:3018#include "cc/raster/raster_source.h"
danakj920156852015-05-18 20:22:2919#include "cc/raster/scoped_gpu_raster.h"
danakja32578c2018-04-25 21:18:3620#include "cc/resources/layer_tree_resource_provider.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
Eric Karl247f09c2018-03-15 02:06:3641class ScopedSkSurfaceForUnpremultiplyAndDither {
42 public:
43 ScopedSkSurfaceForUnpremultiplyAndDither(
44 viz::RasterContextProvider* context_provider,
45 const gfx::Rect& playback_rect,
46 const gfx::Rect& raster_full_rect,
47 const gfx::Size& max_tile_size,
48 GLuint texture_id,
49 const gfx::Size& texture_size,
Eric Karl247f09c2018-03-15 02:06:3650 bool can_use_lcd_text,
51 int msaa_sample_count)
52 : context_provider_(context_provider),
53 texture_id_(texture_id),
54 offset_(playback_rect.OffsetFromOrigin() -
55 raster_full_rect.OffsetFromOrigin()),
56 size_(playback_rect.size()) {
57 // Determine the |intermediate_size| to use for our 32-bit texture. If we
58 // know the max tile size, use that. This prevents GPU cache explosion due
59 // to using lots of different 32-bit texture sizes. Otherwise just use the
60 // exact size of the target texture.
61 gfx::Size intermediate_size;
62 if (!max_tile_size.IsEmpty()) {
63 DCHECK_GE(max_tile_size.width(), texture_size.width());
64 DCHECK_GE(max_tile_size.height(), texture_size.height());
65 intermediate_size = max_tile_size;
66 } else {
67 intermediate_size = texture_size;
68 }
69
70 // Allocate a 32-bit surface for raster. We will copy from that into our
71 // actual surface in destruction.
72 SkImageInfo n32Info = SkImageInfo::MakeN32Premul(
73 intermediate_size.width(), intermediate_size.height());
74 SkSurfaceProps surface_props =
75 LayerTreeResourceProvider::ScopedSkSurface::ComputeSurfaceProps(
Adrienne Walker7774c3c2018-03-21 23:40:3476 can_use_lcd_text);
Eric Karl247f09c2018-03-15 02:06:3677 surface_ = SkSurface::MakeRenderTarget(
78 context_provider->GrContext(), SkBudgeted::kNo, n32Info,
79 msaa_sample_count, kTopLeft_GrSurfaceOrigin, &surface_props);
80 }
81
82 ~ScopedSkSurfaceForUnpremultiplyAndDither() {
83 // In lost-context cases, |surface_| may be null and there's nothing
84 // meaningful to do here.
85 if (!surface_)
86 return;
87
Greg Daniel0691c672018-04-17 17:21:1488 GrBackendTexture backend_texture =
89 surface_->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess);
90 if (!backend_texture.isValid()) {
91 return;
92 }
93 GrGLTextureInfo info;
94 if (!backend_texture.getGLTextureInfo(&info)) {
95 return;
96 }
Eric Karl247f09c2018-03-15 02:06:3697 context_provider_->ContextGL()->UnpremultiplyAndDitherCopyCHROMIUM(
Greg Daniel0691c672018-04-17 17:21:1498 info.fID, texture_id_, offset_.x(), offset_.y(), size_.width(),
Eric Karl247f09c2018-03-15 02:06:3699 size_.height());
100 }
101
102 SkSurface* surface() { return surface_.get(); }
103
104 private:
105 viz::RasterContextProvider* context_provider_;
106 GLuint texture_id_;
107 gfx::Vector2d offset_;
108 gfx::Size size_;
109 sk_sp<SkSurface> surface_;
110};
111
Adrienne Walker436a7752017-08-28 23:33:09112static void RasterizeSourceOOP(
113 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,
Adrienne Walker436a7752017-08-28 23:33:09122 const gfx::Rect& raster_full_rect,
123 const gfx::Rect& playback_rect,
124 const gfx::AxisTransform2d& transform,
125 const RasterSource::PlaybackSettings& playback_settings,
Victor Miura29b7ea3d2017-12-19 20:23:59126 viz::RasterContextProvider* context_provider,
Adrienne Walker436a7752017-08-28 23:33:09127 int msaa_sample_count) {
Victor Miura29b7ea3d2017-12-19 20:23:59128 gpu::raster::RasterInterface* ri = context_provider->RasterInterface();
Victor Miura7f7070d2018-03-02 19:22:24129 GLuint texture_id = ri->CreateAndConsumeTexture(
130 texture_is_overlay_candidate, gfx::BufferUsage::SCANOUT, resource_format,
131 mailbox.name);
danakjaf3170e2018-02-09 17:31:58132 if (!texture_storage_allocated) {
133 viz::TextureAllocation alloc = {texture_id, texture_target,
134 texture_is_overlay_candidate};
135 viz::TextureAllocation::AllocateStorage(
136 ri, context_provider->ContextCapabilities(), resource_format,
137 resource_size, alloc, color_space);
138 }
Adrienne Walker436a7752017-08-28 23:33:09139
danakjaf3170e2018-02-09 17:31:58140 // TODO(enne): Use the |texture_target|? GpuMemoryBuffer backed textures don't
141 // use GL_TEXTURE_2D.
danakja32578c2018-04-25 21:18:36142 ri->BeginRasterCHROMIUM(texture_id, raster_source->background_color(),
143 msaa_sample_count, playback_settings.use_lcd_text,
144 viz::ResourceFormatToClosestSkColorType(
145 /*gpu_compositing=*/true, resource_format),
146 playback_settings.raster_color_space);
Adrienne Walkerbc5cd82e2017-10-31 21:58:15147 float recording_to_raster_scale =
148 transform.scale() / raster_source->recording_scale_factor();
Adrienne Walker51c8e382018-02-06 20:30:33149 gfx::Size content_size = raster_source->GetContentSize(transform.scale());
150 // TODO(enne): could skip the clear on new textures, as the service side has
151 // to do that anyway. resource_has_previous_content implies that the texture
152 // is not new, but the reverse does not hold, so more plumbing is needed.
Victor Miura3a4ad4f82017-12-13 06:03:45153 ri->RasterCHROMIUM(raster_source->GetDisplayItemList().get(),
Adrienne Walker51c8e382018-02-06 20:30:33154 playback_settings.image_provider, content_size,
155 raster_full_rect, playback_rect, transform.translation(),
156 recording_to_raster_scale,
157 raster_source->requires_clear());
Victor Miura3a4ad4f82017-12-13 06:03:45158 ri->EndRasterCHROMIUM();
Adrienne Walker436a7752017-08-28 23:33:09159
Eric Karl247f09c2018-03-15 02:06:36160 // TODO(ericrk): Handle unpremultiply+dither for 4444 cases.
161 // https://crbug.com/789153
162
Victor Miura3a4ad4f82017-12-13 06:03:45163 ri->DeleteTextures(1, &texture_id);
Adrienne Walker436a7752017-08-28 23:33:09164}
165
Justin Novosad60f840e2018-03-21 22:00:50166// The following class is needed to correctly reset GL state when rendering to
167// SkCanvases with a GrContext on a RasterInterface enabled context.
168class ScopedGrContextAccess {
169 public:
170 explicit ScopedGrContextAccess(viz::RasterContextProvider* context_provider)
171 : context_provider_(context_provider) {
172 gpu::raster::RasterInterface* ri = context_provider_->RasterInterface();
173 ri->BeginGpuRaster();
Justin Novosad60f840e2018-03-21 22:00:50174 }
175 ~ScopedGrContextAccess() {
176 gpu::raster::RasterInterface* ri = context_provider_->RasterInterface();
177 ri->EndGpuRaster();
178 }
179
180 private:
181 viz::RasterContextProvider* context_provider_;
182};
183
vmiuraf7c765c2016-12-03 21:02:32184static void RasterizeSource(
sunnyps5d6ff0d02016-06-28 00:40:11185 const RasterSource* raster_source,
186 bool resource_has_previous_content,
danakjaf3170e2018-02-09 17:31:58187 const gpu::Mailbox& mailbox,
188 GLenum texture_target,
189 bool texture_is_overlay_candidate,
190 bool texture_storage_allocated,
191 const gfx::Size& resource_size,
192 viz::ResourceFormat resource_format,
193 const gfx::ColorSpace& color_space,
sunnyps5d6ff0d02016-06-28 00:40:11194 const gfx::Rect& raster_full_rect,
Adrienne Walker436a7752017-08-28 23:33:09195 const gfx::Rect& playback_rect,
trchen178ac912017-04-04 10:11:10196 const gfx::AxisTransform2d& transform,
vmiuraf7c765c2016-12-03 21:02:32197 const RasterSource::PlaybackSettings& playback_settings,
Victor Miura29b7ea3d2017-12-19 20:23:59198 viz::RasterContextProvider* context_provider,
Eric Karl247f09c2018-03-15 02:06:36199 int msaa_sample_count,
200 bool unpremultiply_and_dither,
201 const gfx::Size& max_tile_size) {
Victor Miura29b7ea3d2017-12-19 20:23:59202 gpu::raster::RasterInterface* ri = context_provider->RasterInterface();
Victor Miura7f7070d2018-03-02 19:22:24203 GLuint texture_id = ri->CreateAndConsumeTexture(
204 texture_is_overlay_candidate, gfx::BufferUsage::SCANOUT, resource_format,
205 mailbox.name);
danakjaf3170e2018-02-09 17:31:58206 if (!texture_storage_allocated) {
207 viz::TextureAllocation alloc = {texture_id, texture_target,
208 texture_is_overlay_candidate};
209 viz::TextureAllocation::AllocateStorage(
210 ri, context_provider->ContextCapabilities(), resource_format,
211 resource_size, alloc, color_space);
212 }
Sunny Sachanandani0cb875e2017-08-15 02:54:52213
214 {
Justin Novosad60f840e2018-03-21 22:00:50215 ScopedGrContextAccess gr_context_access(context_provider);
Eric Karl247f09c2018-03-15 02:06:36216 base::Optional<LayerTreeResourceProvider::ScopedSkSurface> scoped_surface;
217 base::Optional<ScopedSkSurfaceForUnpremultiplyAndDither>
218 scoped_dither_surface;
219 SkSurface* surface;
220 if (!unpremultiply_and_dither) {
221 scoped_surface.emplace(context_provider->GrContext(), texture_id,
222 texture_target, resource_size, resource_format,
Eric Karl247f09c2018-03-15 02:06:36223 playback_settings.use_lcd_text, msaa_sample_count);
224 surface = scoped_surface->surface();
225 } else {
226 scoped_dither_surface.emplace(
227 context_provider, playback_rect, raster_full_rect, max_tile_size,
Adrienne Walker7774c3c2018-03-21 23:40:34228 texture_id, resource_size, playback_settings.use_lcd_text,
229 msaa_sample_count);
Eric Karl247f09c2018-03-15 02:06:36230 surface = scoped_dither_surface->surface();
231 }
Sunny Sachanandani0cb875e2017-08-15 02:54:52232
233 // Allocating an SkSurface will fail after a lost context. Pretend we
234 // rasterized, as the contents of the resource don't matter anymore.
235 if (!surface) {
236 DLOG(ERROR) << "Failed to allocate raster surface";
237 return;
238 }
239
Sunny Sachanandani0cb875e2017-08-15 02:54:52240 SkCanvas* canvas = surface->getCanvas();
241
242 // As an optimization, inform Skia to discard when not doing partial raster.
243 if (raster_full_rect == playback_rect)
244 canvas->discard();
245
Adrienne Walker51c8e382018-02-06 20:30:33246 gfx::Size content_size = raster_source->GetContentSize(transform.scale());
danakjaf3170e2018-02-09 17:31:58247 raster_source->PlaybackToCanvas(canvas, color_space, content_size,
248 raster_full_rect, playback_rect, transform,
249 playback_settings);
ccameron220942362017-02-06 20:29:19250 }
vmiuraf7c765c2016-12-03 21:02:32251
Victor Miura3a4ad4f82017-12-13 06:03:45252 ri->DeleteTextures(1, &texture_id);
sunnyps5d6ff0d02016-06-28 00:40:11253}
reveman47560ab2014-09-18 19:39:21254
255} // namespace
vmiura78b69282015-02-14 00:01:17256
danakjaf3170e2018-02-09 17:31:58257// Subclass for InUsePoolResource that holds ownership of a gpu-rastered backing
258// and does cleanup of the backing when destroyed.
259class GpuRasterBufferProvider::GpuRasterBacking
260 : public ResourcePool::GpuBacking {
261 public:
262 ~GpuRasterBacking() override {
263 gpu::gles2::GLES2Interface* gl = compositor_context_provider->ContextGL();
264 if (returned_sync_token.HasData())
265 gl->WaitSyncTokenCHROMIUM(returned_sync_token.GetConstData());
266 if (mailbox_sync_token.HasData())
267 gl->WaitSyncTokenCHROMIUM(mailbox_sync_token.GetConstData());
268 if (texture_id)
269 gl->DeleteTextures(1, &texture_id);
270 }
271
272 base::trace_event::MemoryAllocatorDumpGuid MemoryDumpGuid(
273 uint64_t tracing_process_id) override {
danakj50fc16e2018-02-14 21:49:48274 if (!storage_allocated)
275 return {};
danakjaf3170e2018-02-09 17:31:58276 return gl::GetGLTextureClientGUIDForTracing(
277 compositor_context_provider->ContextSupport()->ShareGroupTracingGUID(),
278 texture_id);
279 }
280 base::UnguessableToken SharedMemoryGuid() override { return {}; }
281
282 // The ContextProvider used to clean up the texture id.
283 viz::ContextProvider* compositor_context_provider = nullptr;
284 // The texture backing of the resource.
285 GLuint texture_id = 0;
286 // The allocation of storage for the |texture_id| is deferred, and this tracks
287 // if it has been done.
288 bool storage_allocated = false;
289};
290
sunnyps5d6ff0d02016-06-28 00:40:11291GpuRasterBufferProvider::RasterBufferImpl::RasterBufferImpl(
292 GpuRasterBufferProvider* client,
danakjaf3170e2018-02-09 17:31:58293 const ResourcePool::InUsePoolResource& in_use_resource,
294 GpuRasterBacking* backing,
danakjd1dd03152018-02-23 18:13:46295 const gpu::SyncToken& before_raster_sync_token,
sunnyps5d6ff0d02016-06-28 00:40:11296 bool resource_has_previous_content)
297 : client_(client),
danakjaf3170e2018-02-09 17:31:58298 backing_(backing),
299 resource_size_(in_use_resource.size()),
300 resource_format_(in_use_resource.format()),
301 color_space_(in_use_resource.color_space()),
302 resource_has_previous_content_(resource_has_previous_content),
danakjd1dd03152018-02-23 18:13:46303 before_raster_sync_token_(before_raster_sync_token),
danakjaf3170e2018-02-09 17:31:58304 mailbox_(backing->mailbox),
305 texture_target_(backing->texture_target),
306 texture_is_overlay_candidate_(backing->overlay_candidate),
danakjd1dd03152018-02-23 18:13:46307 texture_storage_allocated_(backing->storage_allocated) {}
sunnyps5d6ff0d02016-06-28 00:40:11308
309GpuRasterBufferProvider::RasterBufferImpl::~RasterBufferImpl() {
danakjaf3170e2018-02-09 17:31:58310 // This SyncToken was created on the worker context after rastering the
311 // texture content.
312 backing_->mailbox_sync_token = after_raster_sync_token_;
313 if (after_raster_sync_token_.HasData()) {
314 // The returned SyncToken was waited on in Playback. We know Playback
315 // happened if the |after_raster_sync_token_| was set.
316 backing_->returned_sync_token = gpu::SyncToken();
317 }
318 backing_->storage_allocated = texture_storage_allocated_;
sunnyps5d6ff0d02016-06-28 00:40:11319}
320
321void GpuRasterBufferProvider::RasterBufferImpl::Playback(
322 const RasterSource* raster_source,
323 const gfx::Rect& raster_full_rect,
324 const gfx::Rect& raster_dirty_rect,
325 uint64_t new_content_id,
trchen178ac912017-04-04 10:11:10326 const gfx::AxisTransform2d& transform,
sunnyps5d6ff0d02016-06-28 00:40:11327 const RasterSource::PlaybackSettings& playback_settings) {
328 TRACE_EVENT0("cc", "GpuRasterBuffer::Playback");
danakjd1dd03152018-02-23 18:13:46329 // The |before_raster_sync_token_| passed in here was created on the
330 // compositor thread, or given back with the texture for reuse. This call
331 // returns another SyncToken generated on the worker thread to synchronize
332 // with after the raster is complete.
danakjaf3170e2018-02-09 17:31:58333 after_raster_sync_token_ = client_->PlaybackOnWorkerThread(
334 mailbox_, texture_target_, texture_is_overlay_candidate_,
335 texture_storage_allocated_, before_raster_sync_token_, resource_size_,
336 resource_format_, color_space_, resource_has_previous_content_,
337 raster_source, raster_full_rect, raster_dirty_rect, new_content_id,
338 transform, playback_settings);
339 texture_storage_allocated_ = true;
sunnyps5d6ff0d02016-06-28 00:40:11340}
341
prashant.nb4d4f492016-04-29 12:51:28342GpuRasterBufferProvider::GpuRasterBufferProvider(
Xu Xing32549162017-07-17 22:25:43343 viz::ContextProvider* compositor_context_provider,
Victor Miura29b7ea3d2017-12-19 20:23:59344 viz::RasterContextProvider* worker_context_provider,
danakjaf3170e2018-02-09 17:31:58345 bool use_gpu_memory_buffer_resources,
sunnyps5d6ff0d02016-06-28 00:40:11346 int gpu_rasterization_msaa_sample_count,
danakja32578c2018-04-25 21:18:36347 viz::ResourceFormat tile_format,
Eric Karl247f09c2018-03-15 02:06:36348 const gfx::Size& max_tile_size,
Eric Karla6ff8862018-04-16 20:21:06349 bool unpremultiply_and_dither_low_bit_depth_tiles,
Adrienne Walker436a7752017-08-28 23:33:09350 bool enable_oop_rasterization)
danakj0de0c95a2016-05-25 01:42:49351 : compositor_context_provider_(compositor_context_provider),
sunnyps5d6ff0d02016-06-28 00:40:11352 worker_context_provider_(worker_context_provider),
danakjaf3170e2018-02-09 17:31:58353 use_gpu_memory_buffer_resources_(use_gpu_memory_buffer_resources),
sunnyps5d6ff0d02016-06-28 00:40:11354 msaa_sample_count_(gpu_rasterization_msaa_sample_count),
danakja32578c2018-04-25 21:18:36355 tile_format_(tile_format),
Eric Karl247f09c2018-03-15 02:06:36356 max_tile_size_(max_tile_size),
Eric Karla6ff8862018-04-16 20:21:06357 unpremultiply_and_dither_low_bit_depth_tiles_(
358 unpremultiply_and_dither_low_bit_depth_tiles),
Adrienne Walker436a7752017-08-28 23:33:09359 enable_oop_rasterization_(enable_oop_rasterization) {
sunnyps5d6ff0d02016-06-28 00:40:11360 DCHECK(compositor_context_provider);
361 DCHECK(worker_context_provider);
danakj0de0c95a2016-05-25 01:42:49362}
reveman@chromium.orgb5641b92014-02-15 14:21:58363
sunnyps5d6ff0d02016-06-28 00:40:11364GpuRasterBufferProvider::~GpuRasterBufferProvider() {
sunnyps5d6ff0d02016-06-28 00:40:11365}
reveman@chromium.orgb5641b92014-02-15 14:21:58366
prashant.nb4d4f492016-04-29 12:51:28367std::unique_ptr<RasterBuffer> GpuRasterBufferProvider::AcquireBufferForRaster(
danakj4e871d82018-01-18 21:56:57368 const ResourcePool::InUsePoolResource& resource,
danakj510822aa2015-06-01 20:23:02369 uint64_t resource_content_id,
danakje0b54782015-05-29 22:47:52370 uint64_t previous_content_id) {
danakjd1dd03152018-02-23 18:13:46371 gpu::SyncToken before_raster_sync_token;
372 bool new_resource = false;
danakjaf3170e2018-02-09 17:31:58373 if (!resource.gpu_backing()) {
374 auto backing = std::make_unique<GpuRasterBacking>();
375 backing->compositor_context_provider = compositor_context_provider_;
376
377 gpu::gles2::GLES2Interface* gl = compositor_context_provider_->ContextGL();
378 const auto& caps = compositor_context_provider_->ContextCapabilities();
379
380 viz::TextureAllocation alloc = viz::TextureAllocation::MakeTextureId(
381 gl, caps, resource.format(), use_gpu_memory_buffer_resources_,
382 /*for_framebuffer_attachment=*/true);
383 backing->texture_id = alloc.texture_id;
384 backing->texture_target = alloc.texture_target;
385 backing->overlay_candidate = alloc.overlay_candidate;
386 backing->mailbox = gpu::Mailbox::Generate();
danakjaf3170e2018-02-09 17:31:58387 gl->ProduceTextureDirectCHROMIUM(backing->texture_id,
388 backing->mailbox.name);
danakjd1dd03152018-02-23 18:13:46389 before_raster_sync_token =
390 LayerTreeResourceProvider::GenerateSyncTokenHelper(gl);
danakjaf3170e2018-02-09 17:31:58391
392 resource.set_gpu_backing(std::move(backing));
danakjd1dd03152018-02-23 18:13:46393 new_resource = true;
danakjaf3170e2018-02-09 17:31:58394 }
395 GpuRasterBacking* backing =
396 static_cast<GpuRasterBacking*>(resource.gpu_backing());
danakjd1dd03152018-02-23 18:13:46397 if (!new_resource)
398 before_raster_sync_token = backing->returned_sync_token;
danakjaf3170e2018-02-09 17:31:58399
sunnyps5d6ff0d02016-06-28 00:40:11400 bool resource_has_previous_content =
401 resource_content_id && resource_content_id == previous_content_id;
danakjaf3170e2018-02-09 17:31:58402 return std::make_unique<RasterBufferImpl>(this, resource, backing,
danakjd1dd03152018-02-23 18:13:46403 before_raster_sync_token,
danakj4e871d82018-01-18 21:56:57404 resource_has_previous_content);
reveman@chromium.orgb5641b92014-02-15 14:21:58405}
406
Sunny Sachanandani5f5419e22017-05-12 20:35:30407void GpuRasterBufferProvider::Flush() {
Victor Miuraff6488612017-12-21 04:16:15408 compositor_context_provider_->ContextSupport()->FlushPendingWork();
Sunny Sachanandani5f5419e22017-05-12 20:35:30409}
410
danakja32578c2018-04-25 21:18:36411viz::ResourceFormat GpuRasterBufferProvider::GetResourceFormat() const {
412 return tile_format_;
prashant.nb4d4f492016-04-29 12:51:28413}
414
danakja32578c2018-04-25 21:18:36415bool GpuRasterBufferProvider::IsResourceSwizzleRequired() const {
prashant.nb4d4f492016-04-29 12:51:28416 // This doesn't require a swizzle because we rasterize to the correct format.
417 return false;
418}
419
danakja32578c2018-04-25 21:18:36420bool GpuRasterBufferProvider::IsResourcePremultiplied() const {
421 return !ShouldUnpremultiplyAndDitherResource(GetResourceFormat());
Eric Karl247f09c2018-03-15 02:06:36422}
423
ericrk5ac42f322016-07-14 01:06:51424bool GpuRasterBufferProvider::CanPartialRasterIntoProvidedResource() const {
ericrkc9ed0832016-07-20 19:42:50425 // Partial raster doesn't support MSAA, as the MSAA resolve is unaware of clip
426 // rects.
427 // TODO(crbug.com/629683): See if we can work around this limitation.
428 return msaa_sample_count_ == 0;
ericrkeeda58992016-07-07 02:34:27429}
430
ericrk7f6a27f2017-01-31 22:34:32431bool GpuRasterBufferProvider::IsResourceReadyToDraw(
danakj4e871d82018-01-18 21:56:57432 const ResourcePool::InUsePoolResource& resource) const {
danakjaf3170e2018-02-09 17:31:58433 const gpu::SyncToken& sync_token = resource.gpu_backing()->mailbox_sync_token;
434 // This SyncToken() should have been set by calling OrderingBarrier() before
435 // calling this.
436 DCHECK(sync_token.HasData());
ericrk7f6a27f2017-01-31 22:34:32437
sunnyps74996292017-03-15 02:35:48438 // IsSyncTokenSignaled is thread-safe, no need for worker context lock.
439 return worker_context_provider_->ContextSupport()->IsSyncTokenSignaled(
ericrk7f6a27f2017-01-31 22:34:32440 sync_token);
441}
442
443uint64_t GpuRasterBufferProvider::SetReadyToDrawCallback(
danakj4e871d82018-01-18 21:56:57444 const std::vector<const ResourcePool::InUsePoolResource*>& resources,
ericrk7f6a27f2017-01-31 22:34:32445 const base::Closure& callback,
446 uint64_t pending_callback_id) const {
danakjaf3170e2018-02-09 17:31:58447 gpu::SyncToken latest_sync_token;
448 for (const auto* in_use : resources) {
449 const gpu::SyncToken& sync_token =
450 in_use->gpu_backing()->mailbox_sync_token;
451 if (sync_token.release_count() > latest_sync_token.release_count())
452 latest_sync_token = sync_token;
453 }
454 uint64_t callback_id = latest_sync_token.release_count();
ericrk7f6a27f2017-01-31 22:34:32455 DCHECK_NE(callback_id, 0u);
456
457 // If the callback is different from the one the caller is already waiting on,
sunnyps31c92fe2017-02-10 23:46:55458 // pass the callback through to SignalSyncToken. Otherwise the request is
ericrk7f6a27f2017-01-31 22:34:32459 // redundant.
460 if (callback_id != pending_callback_id) {
danakjaf3170e2018-02-09 17:31:58461 // Use the compositor context because we want this callback on the
462 // compositor thread.
463 compositor_context_provider_->ContextSupport()->SignalSyncToken(
464 latest_sync_token, callback);
ericrk7f6a27f2017-01-31 22:34:32465 }
466
467 return callback_id;
468}
469
sunnyps5d6ff0d02016-06-28 00:40:11470void GpuRasterBufferProvider::Shutdown() {
sunnyps5d6ff0d02016-06-28 00:40:11471}
472
danakjaf3170e2018-02-09 17:31:58473gpu::SyncToken GpuRasterBufferProvider::PlaybackOnWorkerThread(
474 const gpu::Mailbox& mailbox,
475 GLenum texture_target,
476 bool texture_is_overlay_candidate,
477 bool texture_storage_allocated,
sunnyps5d6ff0d02016-06-28 00:40:11478 const gpu::SyncToken& sync_token,
danakjaf3170e2018-02-09 17:31:58479 const gfx::Size& resource_size,
480 viz::ResourceFormat resource_format,
481 const gfx::ColorSpace& color_space,
sunnyps5d6ff0d02016-06-28 00:40:11482 bool resource_has_previous_content,
483 const RasterSource* raster_source,
484 const gfx::Rect& raster_full_rect,
485 const gfx::Rect& raster_dirty_rect,
486 uint64_t new_content_id,
trchen178ac912017-04-04 10:11:10487 const gfx::AxisTransform2d& transform,
sunnyps5d6ff0d02016-06-28 00:40:11488 const RasterSource::PlaybackSettings& playback_settings) {
Victor Miura29b7ea3d2017-12-19 20:23:59489 viz::RasterContextProvider::ScopedRasterContextLock scoped_context(
Xu Xing32549162017-07-17 22:25:43490 worker_context_provider_);
Victor Miura29b7ea3d2017-12-19 20:23:59491 gpu::raster::RasterInterface* ri = scoped_context.RasterInterface();
Victor Miura3a4ad4f82017-12-13 06:03:45492 DCHECK(ri);
sunnyps5d6ff0d02016-06-28 00:40:11493
danakjaf3170e2018-02-09 17:31:58494 // Wait on the SyncToken that was created on the compositor thread after
495 // making the mailbox. This ensures that the mailbox we consume here is valid
496 // by the time the consume command executes.
Victor Miura3a4ad4f82017-12-13 06:03:45497 ri->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
sunnyps5d6ff0d02016-06-28 00:40:11498
Adrienne Walker436a7752017-08-28 23:33:09499 gfx::Rect playback_rect = raster_full_rect;
500 if (resource_has_previous_content) {
501 playback_rect.Intersect(raster_dirty_rect);
502 }
503 DCHECK(!playback_rect.IsEmpty())
504 << "Why are we rastering a tile that's not dirty?";
505
506 // Log a histogram of the percentage of pixels that were saved due to
507 // partial raster.
508 const char* client_name = GetClientNameForMetrics();
509 float full_rect_size = raster_full_rect.size().GetArea();
510 if (full_rect_size > 0 && client_name) {
511 float fraction_partial_rastered =
512 static_cast<float>(playback_rect.size().GetArea()) / full_rect_size;
513 float fraction_saved = 1.0f - fraction_partial_rastered;
514 UMA_HISTOGRAM_PERCENTAGE(
515 base::StringPrintf("Renderer4.%s.PartialRasterPercentageSaved.Gpu",
516 client_name),
517 100.0f * fraction_saved);
518 }
519
520 if (enable_oop_rasterization_) {
Adrienne Walker7774c3c2018-03-21 23:40:34521 RasterizeSourceOOP(raster_source, resource_has_previous_content, mailbox,
522 texture_target, texture_is_overlay_candidate,
523 texture_storage_allocated, resource_size,
524 resource_format, color_space, raster_full_rect,
525 playback_rect, transform, playback_settings,
526 worker_context_provider_, msaa_sample_count_);
Adrienne Walker436a7752017-08-28 23:33:09527 } else {
Eric Karl247f09c2018-03-15 02:06:36528 RasterizeSource(
529 raster_source, resource_has_previous_content, mailbox, texture_target,
530 texture_is_overlay_candidate, texture_storage_allocated, resource_size,
531 resource_format, color_space, raster_full_rect, playback_rect,
532 transform, playback_settings, worker_context_provider_,
Adrienne Walker7774c3c2018-03-21 23:40:34533 msaa_sample_count_,
Eric Karl247f09c2018-03-15 02:06:36534 ShouldUnpremultiplyAndDitherResource(resource_format), max_tile_size_);
Adrienne Walker436a7752017-08-28 23:33:09535 }
sunnyps5d6ff0d02016-06-28 00:40:11536
Sunny Sachanandani0cb875e2017-08-15 02:54:52537 // Generate sync token for cross context synchronization.
danakjaf3170e2018-02-09 17:31:58538 return LayerTreeResourceProvider::GenerateSyncTokenHelper(ri);
sunnyps5d6ff0d02016-06-28 00:40:11539}
prashant.nb4d4f492016-04-29 12:51:28540
Eric Karla6ff8862018-04-16 20:21:06541bool GpuRasterBufferProvider::ShouldUnpremultiplyAndDitherResource(
542 viz::ResourceFormat format) const {
543 switch (format) {
544 case viz::RGBA_4444:
545 return unpremultiply_and_dither_low_bit_depth_tiles_;
546 default:
547 return false;
548 }
549}
550
reveman@chromium.orgb5641b92014-02-15 14:21:58551} // namespace cc