| Index: cc/raster/gpu_rasterizer.cc
|
| diff --git a/cc/raster/gpu_rasterizer.cc b/cc/raster/gpu_rasterizer.cc
|
| index 827235b2af8c490319448b5705608af270b276cd..f8a7566b4869bb9e5008568cd78799ea9b9f0c8e 100644
|
| --- a/cc/raster/gpu_rasterizer.cc
|
| +++ b/cc/raster/gpu_rasterizer.cc
|
| @@ -25,16 +25,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* worker_context_provider,
|
| ResourceProvider* resource_provider,
|
| - bool use_distance_field_text,
|
| + bool use_device_independent_fonts,
|
| int msaa_sample_count)
|
| : worker_context_provider_(worker_context_provider),
|
| resource_provider_(resource_provider),
|
| - use_distance_field_text_(use_distance_field_text),
|
| - msaa_sample_count_(msaa_sample_count) {
|
| - DCHECK(worker_context_provider_);
|
| -}
|
| + 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() {
|
| }
|
| @@ -58,19 +74,17 @@ 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(worker_context_provider_);
|
| - write_lock->InitSkSurface(
|
| - worker_context_provider_->GrContext(), use_distance_field_text,
|
| - raster_source->CanUseLCDText(), msaa_sample_count_);
|
| -
|
| - SkSurface* sk_surface = write_lock->sk_surface();
|
| + SkSurface* sk_surface =
|
| + AcquireSurface(gpu_raster, 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 +94,86 @@ 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&,
|
| + ResourceProvider::ScopedWriteLockGr* write_lock,
|
| + bool use_device_independent_fonts,
|
| + bool can_use_lcd_text) {
|
| + bool uses_separate_msaa_backing_store =
|
| + msaa_sample_count_ > 0 &&
|
| + !worker_context_provider_->ContextCapabilities()
|
| + .multisampled_render_to_texture &&
|
| + !worker_context_provider_->ContextCapabilities()
|
| + .chromium_framebuffer_mixed_samples;
|
| + 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(worker_context_provider_->GrContext(),
|
| + 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(worker_context_provider_->GrContext(), false,
|
| + false, 0);
|
| + SkSurface* target_surface = write_lock->sk_surface();
|
| + if (!target_surface)
|
| + return;
|
| + msaa_surface_->draw(target_surface->getCanvas(), 0, 0, nullptr);
|
| + }
|
| + 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);
|
| +
|
| + msaa_surface_ = SkSurface::MakeRenderTarget(
|
| + worker_context_provider_->GrContext(), 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
|
|
|