Chromium Code Reviews| Index: cc/raster/gpu_rasterizer.cc |
| diff --git a/cc/raster/gpu_rasterizer.cc b/cc/raster/gpu_rasterizer.cc |
| index f6e0288f5ddbe30d9712b06eb9d292579ff8916c..47dc1793e7d93145baece21516890a7876acb5d8 100644 |
| --- a/cc/raster/gpu_rasterizer.cc |
| +++ b/cc/raster/gpu_rasterizer.cc |
| @@ -26,14 +26,32 @@ |
| namespace cc { |
| +namespace { |
| +SkColorType ToSkColorType(ResourceFormat format) { |
| + switch (format) { |
| + case RGBA_8888: |
| + return kRGBA_8888_SkColorType; |
| + case BGRA_8888: |
| + return kBGRA_8888_SkColorType; |
| + case RGBA_4444: |
| + return kARGB_4444_SkColorType; |
| + default: |
| + break; |
| + } |
| + DCHECK(false) << "Unsupported resource format."; |
| + return kN32_SkColorType; |
| +} |
| +} // namespace |
| + |
| GpuRasterizer::GpuRasterizer(ContextProvider* context_provider, |
| ResourceProvider* resource_provider, |
| - bool use_distance_field_text, |
| + bool use_device_independent_fonts, |
| int msaa_sample_count) |
| : resource_provider_(resource_provider), |
| - use_distance_field_text_(use_distance_field_text), |
| - msaa_sample_count_(msaa_sample_count) { |
| -} |
| + use_device_independent_fonts_(use_device_independent_fonts), |
| + msaa_sample_count_(msaa_sample_count), |
| + msaa_surface_use_device_independent_fonts_(false), |
| + msaa_surface_can_use_lcd_text_(false) {} |
| GpuRasterizer::~GpuRasterizer() { |
| } |
| @@ -57,20 +75,19 @@ void GpuRasterizer::RasterizeSource( |
| canvas->restore(); |
| sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture(); |
| - // Turn on distance fields for layers that have ever animated. |
| - bool use_distance_field_text = |
| - use_distance_field_text_ || |
| + // Turn on device independent fonts for layers that have ever animated. |
| + bool use_device_independent_fonts = |
| + use_device_independent_fonts_ || |
| raster_source->ShouldAttemptToUseDistanceFieldText(); |
| // Playback picture into resource. |
| { |
| - ScopedGpuRaster gpu_raster( |
| - resource_provider_->output_surface()->worker_context_provider()); |
| - write_lock->InitSkSurface(use_distance_field_text, |
| - raster_source->CanUseLCDText(), |
| - msaa_sample_count_); |
| - |
| - SkSurface* sk_surface = write_lock->sk_surface(); |
| + ContextProvider* context_provider = |
| + resource_provider_->output_surface()->worker_context_provider(); |
| + ScopedGpuRaster gpu_raster(context_provider); |
| + SkSurface* sk_surface = AcquireSurface( |
| + gpu_raster, context_provider, write_lock, use_device_independent_fonts, |
| + raster_source->CanUseLCDText()); |
| // Allocating an SkSurface will fail after a lost context. Pretend we |
| // rasterized, as the contents of the resource don't matter anymore. |
| @@ -80,8 +97,89 @@ void GpuRasterizer::RasterizeSource( |
| SkMultiPictureDraw multi_picture_draw; |
| multi_picture_draw.add(sk_surface->getCanvas(), picture.get()); |
| multi_picture_draw.draw(false); |
| - write_lock->ReleaseSkSurface(); |
| + ReleaseSurface(gpu_raster, write_lock); |
| } |
| } |
| +// ScopedGpuRaster is an argument so that we know caller holds it, proves |
| +// that Skia context has been reset. |
| +SkSurface* GpuRasterizer::AcquireSurface( |
| + const ScopedGpuRaster&, |
| + ContextProvider* context_provider, |
| + ResourceProvider::ScopedWriteLockGr* write_lock, |
| + bool use_device_independent_fonts, |
| + bool can_use_lcd_text) { |
| + bool uses_separate_msaa_backing_store = |
| + msaa_sample_count_ > 0 && |
| + !context_provider->ContextCapabilities() |
| + .gpu.multisampled_render_to_texture && |
|
Stephen White
2016/04/15 14:10:54
Rather than checking for the absence of multisampl
|
| + !context_provider->ContextCapabilities() |
| + .gpu.chromium_framebuffer_mixed_samples; |
|
Stephen White
2016/04/15 14:10:54
Out of curiosity, why do we not keep a persistent
|
| + if (uses_separate_msaa_backing_store) { |
| + // Creating SkSurface, rendering to it and then destroying the surface is |
| + // slow due to need to allocate the backing store, e.g. GL renderbuffers. |
| + // Use intermediate longlived MSAA surface for rendering and then copy this |
| + // to the actual tile. |
| + gfx::Size size = write_lock->GetResourceSize(); |
| + SkColorType color_type = ToSkColorType(write_lock->GetResourceFormat()); |
| + SkImageInfo surface_image_info = SkImageInfo::Make( |
| + size.width(), size.height(), color_type, kPremul_SkAlphaType); |
| + AllocateMSAASurfaceIfNeeded(surface_image_info, |
| + use_device_independent_fonts, can_use_lcd_text); |
| + if (msaa_surface_) |
| + return msaa_surface_.get(); |
| + } |
| + |
| + msaa_surface_.reset(); |
| + |
| + write_lock->InitSkSurface(use_device_independent_fonts, can_use_lcd_text, |
| + msaa_sample_count_); |
| + |
| + return write_lock->sk_surface(); |
| +} |
| +void GpuRasterizer::ReleaseSurface( |
| + const ScopedGpuRaster&, |
| + ResourceProvider::ScopedWriteLockGr* write_lock) { |
| + if (msaa_sample_count_ > 0 && msaa_surface_) { |
| + write_lock->InitSkSurface(false, false, 0); |
| + SkSurface* target_surface = write_lock->sk_surface(); |
| + if (!target_surface) |
| + return; |
| + msaa_surface_->draw(target_surface->getCanvas(), 0, 0, nullptr); |
|
Stephen White
2016/04/15 14:10:53
Is this the extra blit you're talking about?
So w
|
| + } |
| + write_lock->ReleaseSkSurface(); |
| +} |
| + |
| +void GpuRasterizer::AllocateMSAASurfaceIfNeeded( |
| + const SkImageInfo& image_info, |
| + bool use_device_independent_fonts, |
| + bool can_use_lcd_text) { |
| + if (msaa_surface_ && msaa_surface_image_info_ == image_info && |
| + msaa_surface_use_device_independent_fonts_ == |
| + use_device_independent_fonts && |
| + msaa_surface_can_use_lcd_text_ == can_use_lcd_text) |
| + return; |
| + |
| + msaa_surface_.reset(); |
| + |
| + uint32_t flags = use_device_independent_fonts |
| + ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag |
| + : 0; |
| + SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry); |
| + if (can_use_lcd_text) |
| + surface_props = |
| + SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType); |
| + |
| + bool use_worker_context = true; |
| + class GrContext* gr_context = |
| + resource_provider_->GrContext(use_worker_context); |
| + |
| + msaa_surface_ = |
| + SkSurface::MakeRenderTarget(gr_context, SkBudgeted::kYes, image_info, |
| + msaa_sample_count_, &surface_props); |
| + msaa_surface_image_info_ = image_info; |
| + msaa_surface_use_device_independent_fonts_ = use_device_independent_fonts; |
| + msaa_surface_can_use_lcd_text_ = can_use_lcd_text; |
| +} |
| + |
| } // namespace cc |