Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: cc/raster/gpu_raster_buffer_provider.cc

Issue 2535153002: Remove intermediate SkPicture recording from GPU tile rasterization. (Closed)
Patch Set: Rebase. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/playback/raster_source.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/raster/gpu_raster_buffer_provider.h" 5 #include "cc/raster/gpu_raster_buffer_provider.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
13 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
14 #include "base/trace_event/trace_event.h" 14 #include "base/trace_event/trace_event.h"
15 #include "cc/base/histograms.h" 15 #include "cc/base/histograms.h"
16 #include "cc/playback/image_hijack_canvas.h" 16 #include "cc/playback/image_hijack_canvas.h"
17 #include "cc/playback/raster_source.h" 17 #include "cc/playback/raster_source.h"
18 #include "cc/raster/scoped_gpu_raster.h" 18 #include "cc/raster/scoped_gpu_raster.h"
19 #include "cc/resources/resource.h" 19 #include "cc/resources/resource.h"
20 #include "gpu/command_buffer/client/gles2_interface.h" 20 #include "gpu/command_buffer/client/gles2_interface.h"
21 #include "third_party/skia/include/core/SkMultiPictureDraw.h" 21 #include "third_party/skia/include/core/SkMultiPictureDraw.h"
22 #include "third_party/skia/include/core/SkPictureRecorder.h" 22 #include "third_party/skia/include/core/SkPictureRecorder.h"
23 #include "third_party/skia/include/core/SkSurface.h" 23 #include "third_party/skia/include/core/SkSurface.h"
24 #include "third_party/skia/include/gpu/GrContext.h" 24 #include "third_party/skia/include/gpu/GrContext.h"
25 25
26 namespace cc { 26 namespace cc {
27 namespace { 27 namespace {
28 28
29 static sk_sp<SkPicture> PlaybackToPicture( 29 static void RasterizeSource(
30 const RasterSource* raster_source, 30 const RasterSource* raster_source,
31 bool resource_has_previous_content, 31 bool resource_has_previous_content,
32 const gfx::Size& resource_size, 32 const gfx::Size& resource_size,
33 const gfx::Rect& raster_full_rect, 33 const gfx::Rect& raster_full_rect,
34 const gfx::Rect& raster_dirty_rect, 34 const gfx::Rect& raster_dirty_rect,
35 const gfx::SizeF& scales, 35 const gfx::SizeF& scales,
36 const RasterSource::PlaybackSettings& playback_settings) { 36 const RasterSource::PlaybackSettings& playback_settings,
37 // GPU raster doesn't do low res tiles, so should always include images. 37 ContextProvider* context_provider,
38 DCHECK(!playback_settings.skip_images); 38 ResourceProvider::ScopedWriteLockGL* resource_lock,
39 bool async_worker_context_enabled,
40 bool use_distance_field_text,
41 int msaa_sample_count) {
42 ScopedGpuRaster gpu_raster(context_provider);
39 43
44 ResourceProvider::ScopedSkSurfaceProvider scoped_surface(
45 context_provider, resource_lock, async_worker_context_enabled,
46 use_distance_field_text, raster_source->CanUseLCDText(),
47 raster_source->HasImpliedColorSpace(), msaa_sample_count);
48 SkSurface* sk_surface = scoped_surface.sk_surface();
49 // Allocating an SkSurface will fail after a lost context. Pretend we
50 // rasterized, as the contents of the resource don't matter anymore.
51 if (!sk_surface)
52 return;
53
54 // Playback
40 gfx::Rect playback_rect = raster_full_rect; 55 gfx::Rect playback_rect = raster_full_rect;
41 if (resource_has_previous_content) { 56 if (resource_has_previous_content) {
42 playback_rect.Intersect(raster_dirty_rect); 57 playback_rect.Intersect(raster_dirty_rect);
43 } 58 }
44 DCHECK(!playback_rect.IsEmpty()) 59 DCHECK(!playback_rect.IsEmpty())
45 << "Why are we rastering a tile that's not dirty?"; 60 << "Why are we rastering a tile that's not dirty?";
46 61
47 // Log a histogram of the percentage of pixels that were saved due to 62 // Log a histogram of the percentage of pixels that were saved due to
48 // partial raster. 63 // partial raster.
49 const char* client_name = GetClientNameForMetrics(); 64 const char* client_name = GetClientNameForMetrics();
50 float full_rect_size = raster_full_rect.size().GetArea(); 65 float full_rect_size = raster_full_rect.size().GetArea();
51 if (full_rect_size > 0 && client_name) { 66 if (full_rect_size > 0 && client_name) {
52 float fraction_partial_rastered = 67 float fraction_partial_rastered =
53 static_cast<float>(playback_rect.size().GetArea()) / full_rect_size; 68 static_cast<float>(playback_rect.size().GetArea()) / full_rect_size;
54 float fraction_saved = 1.0f - fraction_partial_rastered; 69 float fraction_saved = 1.0f - fraction_partial_rastered;
55 UMA_HISTOGRAM_PERCENTAGE( 70 UMA_HISTOGRAM_PERCENTAGE(
56 base::StringPrintf("Renderer4.%s.PartialRasterPercentageSaved.Gpu", 71 base::StringPrintf("Renderer4.%s.PartialRasterPercentageSaved.Gpu",
57 client_name), 72 client_name),
58 100.0f * fraction_saved); 73 100.0f * fraction_saved);
59 } 74 }
60 75
61 // Play back raster_source into temp SkPicture. 76 raster_source->PlaybackToCanvas(sk_surface->getCanvas(), raster_full_rect,
62 SkPictureRecorder recorder; 77 playback_rect, scales, playback_settings);
63 SkCanvas* canvas =
64 recorder.beginRecording(resource_size.width(), resource_size.height());
65 canvas->save();
66
67 // The GPU image decode controller assumes that Skia is done with an image
68 // when playback is complete. However, in this case, where we play back to a
69 // picture, we don't actually finish with the images until the picture is
70 // rasterized later. This can cause lifetime issues in the GPU image decode
71 // controller. To avoid this, we disable the image hijack canvas (and image
72 // decode controller) for this playback step, instead enabling it for the
73 // later picture rasterization.
74 RasterSource::PlaybackSettings settings = playback_settings;
75 settings.use_image_hijack_canvas = false;
76 raster_source->PlaybackToCanvas(canvas, raster_full_rect, playback_rect,
77 scales, settings);
78 canvas->restore();
79 return recorder.finishRecordingAsPicture();
80 }
81
82 static void RasterizePicture(SkPicture* picture,
83 ContextProvider* context_provider,
84 ResourceProvider::ScopedWriteLockGL* resource_lock,
85 bool async_worker_context_enabled,
86 bool use_distance_field_text,
87 bool can_use_lcd_text,
88 bool ignore_resource_color_space,
89 int msaa_sample_count,
90 ImageDecodeCache* image_decode_cache,
91 bool use_image_hijack_canvas) {
92 ScopedGpuRaster gpu_raster(context_provider);
93
94 ResourceProvider::ScopedSkSurfaceProvider scoped_surface(
95 context_provider, resource_lock, async_worker_context_enabled,
96 use_distance_field_text, can_use_lcd_text, ignore_resource_color_space,
97 msaa_sample_count);
98 SkSurface* sk_surface = scoped_surface.sk_surface();
99 // Allocating an SkSurface will fail after a lost context. Pretend we
100 // rasterized, as the contents of the resource don't matter anymore.
101 if (!sk_surface)
102 return;
103
104 // As we did not use the image hijack canvas during the initial playback to
105 // |picture| (see PlaybackToPicture), we must enable it here if requested.
106 SkCanvas* canvas = sk_surface->getCanvas();
107 std::unique_ptr<ImageHijackCanvas> hijack_canvas;
108 if (use_image_hijack_canvas) {
109 DCHECK(image_decode_cache);
110 const SkImageInfo& info = canvas->imageInfo();
111 hijack_canvas.reset(
112 new ImageHijackCanvas(info.width(), info.height(), image_decode_cache));
113 SkIRect raster_bounds;
114 canvas->getClipDeviceBounds(&raster_bounds);
115 hijack_canvas->clipRect(SkRect::MakeFromIRect(raster_bounds));
116 hijack_canvas->setMatrix(canvas->getTotalMatrix());
117 hijack_canvas->addCanvas(canvas);
118
119 // Replace canvas with our ImageHijackCanvas which is wrapping it.
120 canvas = hijack_canvas.get();
121 }
122
123 SkMultiPictureDraw multi_picture_draw;
124 multi_picture_draw.add(canvas, picture);
125 multi_picture_draw.draw(false);
126 } 78 }
127 79
128 } // namespace 80 } // namespace
129 81
130 GpuRasterBufferProvider::RasterBufferImpl::RasterBufferImpl( 82 GpuRasterBufferProvider::RasterBufferImpl::RasterBufferImpl(
131 GpuRasterBufferProvider* client, 83 GpuRasterBufferProvider* client,
132 ResourceProvider* resource_provider, 84 ResourceProvider* resource_provider,
133 ResourceId resource_id, 85 ResourceId resource_id,
134 bool async_worker_context_enabled, 86 bool async_worker_context_enabled,
135 bool resource_has_previous_content) 87 bool resource_has_previous_content)
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 206
255 if (async_worker_context_enabled_) { 207 if (async_worker_context_enabled_) {
256 // Early out if sync token is invalid. This happens if the compositor 208 // Early out if sync token is invalid. This happens if the compositor
257 // context was lost before ScheduleTasks was called. 209 // context was lost before ScheduleTasks was called.
258 if (!sync_token.HasData()) 210 if (!sync_token.HasData())
259 return; 211 return;
260 // Synchronize with compositor. 212 // Synchronize with compositor.
261 gl->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); 213 gl->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
262 } 214 }
263 215
264 sk_sp<SkPicture> picture = PlaybackToPicture(
265 raster_source, resource_has_previous_content, resource_lock->size(),
266 raster_full_rect, raster_dirty_rect, scales, playback_settings);
267
268 // Turn on distance fields for layers that have ever animated. 216 // Turn on distance fields for layers that have ever animated.
269 bool use_distance_field_text = 217 bool use_distance_field_text =
270 use_distance_field_text_ || 218 use_distance_field_text_ ||
271 raster_source->ShouldAttemptToUseDistanceFieldText(); 219 raster_source->ShouldAttemptToUseDistanceFieldText();
272 220
273 RasterizePicture(picture.get(), worker_context_provider_, resource_lock, 221 RasterizeSource(raster_source, resource_has_previous_content,
274 async_worker_context_enabled_, use_distance_field_text, 222 resource_lock->size(), raster_full_rect, raster_dirty_rect,
275 raster_source->CanUseLCDText(), 223 scales, playback_settings, worker_context_provider_,
276 raster_source->HasImpliedColorSpace(), msaa_sample_count_, 224 resource_lock, async_worker_context_enabled_,
277 raster_source->image_decode_cache(), 225 use_distance_field_text, msaa_sample_count_);
278 playback_settings.use_image_hijack_canvas);
279 226
280 const uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM(); 227 const uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM();
281 228
282 // Barrier to sync worker context output to cc context. 229 // Barrier to sync worker context output to cc context.
283 gl->OrderingBarrierCHROMIUM(); 230 gl->OrderingBarrierCHROMIUM();
284 231
285 // Generate sync token after the barrier for cross context synchronization. 232 // Generate sync token after the barrier for cross context synchronization.
286 gpu::SyncToken resource_sync_token; 233 gpu::SyncToken resource_sync_token;
287 gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, resource_sync_token.GetData()); 234 gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, resource_sync_token.GetData());
288 resource_lock->set_sync_token(resource_sync_token); 235 resource_lock->set_sync_token(resource_sync_token);
289 resource_lock->set_synchronized(!async_worker_context_enabled_); 236 resource_lock->set_synchronized(!async_worker_context_enabled_);
290 } 237 }
291 238
292 } // namespace cc 239 } // namespace cc
OLDNEW
« no previous file with comments | « cc/playback/raster_source.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698