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 |