Chromium Code Reviews| Index: cc/raster/gpu_raster_buffer_provider.cc |
| diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc |
| index adeddbd718b01add7e3261e62059ba7a6f645fd2..4d2b6961fc8ff4ea6abff2aa5f22291aa7e1e0e1 100644 |
| --- a/cc/raster/gpu_raster_buffer_provider.cc |
| +++ b/cc/raster/gpu_raster_buffer_provider.cc |
| @@ -13,6 +13,7 @@ |
| #include "base/metrics/histogram_macros.h" |
| #include "base/trace_event/trace_event.h" |
| #include "cc/base/histograms.h" |
| +#include "cc/playback/image_hijack_canvas.h" |
| #include "cc/playback/raster_source.h" |
| #include "cc/raster/scoped_gpu_raster.h" |
| #include "cc/resources/resource.h" |
| @@ -63,19 +64,32 @@ static sk_sp<SkPicture> PlaybackToPicture( |
| sk_sp<SkCanvas> canvas = sk_ref_sp(recorder.beginRecording( |
| resource_size.width(), resource_size.height(), NULL, flags)); |
| canvas->save(); |
| + |
| + // The GPU image decode controller assumes that Skia is done with an image |
| + // when playback is complete. However, in this case, where we play back to a |
| + // picture, we don't actually finish with the images until the picture is |
| + // rasterized later. This can cause lifetime issues in the GPU image decode |
| + // controller. To avoid this, we disable the image hijack canvas (and image |
| + // decode controller) for this playback step, instead enabling it for the |
| + // later picture rasterization. |
| + RasterSource::PlaybackSettings settings = playback_settings; |
| + settings.use_image_hijack_canvas = false; |
| raster_source->PlaybackToCanvas(canvas.get(), raster_full_rect, playback_rect, |
| - scale, playback_settings); |
| + scale, settings); |
| canvas->restore(); |
| return recorder.finishRecordingAsPicture(); |
| } |
| -static void RasterizePicture(SkPicture* picture, |
| - ContextProvider* context_provider, |
| - ResourceProvider::ScopedWriteLockGL* resource_lock, |
| - bool async_worker_context_enabled, |
| - bool use_distance_field_text, |
| - bool can_use_lcd_text, |
| - int msaa_sample_count) { |
| +static void RasterizePicture( |
| + SkPicture* picture, |
| + ContextProvider* context_provider, |
| + ResourceProvider::ScopedWriteLockGL* resource_lock, |
| + bool async_worker_context_enabled, |
| + bool use_distance_field_text, |
| + bool can_use_lcd_text, |
| + int msaa_sample_count, |
| + const RasterSource* raster_source, |
|
vmpstr
2016/07/14 21:41:54
Can you just pass IDC here? and just "use_hijack_c
ericrk
2016/07/14 22:04:20
yup, makes sense.
|
| + const RasterSource::PlaybackSettings& playback_settings) { |
| ScopedGpuRaster gpu_raster(context_provider); |
| ResourceProvider::ScopedSkSurfaceProvider scoped_surface( |
| @@ -87,8 +101,27 @@ static void RasterizePicture(SkPicture* picture, |
| if (!sk_surface) |
| return; |
| + // As we did not use the image hijack canvas during the initial playback to |
| + // |picture| (see PlaybackToPicture), we must enable it here if requested. |
| + SkCanvas* canvas = sk_surface->getCanvas(); |
| + std::unique_ptr<ImageHijackCanvas> hijack_canvas; |
| + if (playback_settings.use_image_hijack_canvas) { |
| + const SkImageInfo& info = canvas->imageInfo(); |
| + hijack_canvas.reset( |
| + new ImageHijackCanvas(info.width(), info.height(), |
| + raster_source->GetImageDecodeController())); |
| + SkIRect raster_bounds; |
| + canvas->getClipDeviceBounds(&raster_bounds); |
| + hijack_canvas->clipRect(SkRect::MakeFromIRect(raster_bounds)); |
| + hijack_canvas->setMatrix(canvas->getTotalMatrix()); |
| + hijack_canvas->addCanvas(canvas); |
| + |
| + // Replace canvas with our ImageHijackCanvas which is wrapping it. |
| + canvas = hijack_canvas.get(); |
| + } |
| + |
| SkMultiPictureDraw multi_picture_draw; |
| - multi_picture_draw.add(sk_surface->getCanvas(), picture); |
| + multi_picture_draw.add(canvas, picture); |
| multi_picture_draw.draw(false); |
| } |
| @@ -236,7 +269,8 @@ void GpuRasterBufferProvider::PlaybackOnWorkerThread( |
| RasterizePicture(picture.get(), worker_context_provider_, resource_lock, |
| async_worker_context_enabled_, use_distance_field_text, |
| - raster_source->CanUseLCDText(), msaa_sample_count_); |
| + raster_source->CanUseLCDText(), msaa_sample_count_, |
| + raster_source, playback_settings); |
| const uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM(); |