| 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 1f2e8802e7d5485cb954eca9dd9c3ce84d4fccd7..4b79a7c532464d2461eb62f429dc9bc67693b780 100644
|
| --- a/cc/raster/gpu_raster_buffer_provider.cc
|
| +++ b/cc/raster/gpu_raster_buffer_provider.cc
|
| @@ -20,14 +20,50 @@
|
| #include "cc/resources/resource.h"
|
| #include "gpu/command_buffer/client/context_support.h"
|
| #include "gpu/command_buffer/client/gles2_interface.h"
|
| +#include "skia/ext/texture_handle.h"
|
| +#include "third_party/skia/include/core/SkCanvas.h"
|
| #include "third_party/skia/include/core/SkMultiPictureDraw.h"
|
| #include "third_party/skia/include/core/SkPictureRecorder.h"
|
| #include "third_party/skia/include/core/SkSurface.h"
|
| #include "third_party/skia/include/gpu/GrContext.h"
|
| +#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
|
|
|
| namespace cc {
|
| namespace {
|
|
|
| +static sk_sp<SkSurface> CreateSkSurface(GrContext* gr_context,
|
| + unsigned texture_id,
|
| + GLenum target,
|
| + const gfx::Size& size,
|
| + ResourceFormat format,
|
| + bool use_distance_field_text,
|
| + bool can_use_lcd_text,
|
| + int msaa_sample_count) {
|
| + GrGLTextureInfo texture_info;
|
| + texture_info.fID = texture_id;
|
| + texture_info.fTarget = target;
|
| + GrBackendTextureDesc desc;
|
| + desc.fFlags = kRenderTarget_GrBackendTextureFlag;
|
| + desc.fWidth = size.width();
|
| + desc.fHeight = size.height();
|
| + desc.fConfig = ToGrPixelConfig(format);
|
| + desc.fOrigin = kTopLeft_GrSurfaceOrigin;
|
| + desc.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(texture_info);
|
| + desc.fSampleCnt = msaa_sample_count;
|
| +
|
| + uint32_t flags =
|
| + use_distance_field_text ? SkSurfaceProps::kUseDistanceFieldFonts_Flag : 0;
|
| + // Use unknown pixel geometry to disable LCD text.
|
| + SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry);
|
| + if (can_use_lcd_text) {
|
| + // LegacyFontHost will get LCD text and skia figures out what type to use.
|
| + surface_props =
|
| + SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType);
|
| + }
|
| + return SkSurface::MakeFromBackendTextureAsRenderTarget(
|
| + gr_context, desc, nullptr, &surface_props);
|
| +}
|
| +
|
| static void RasterizeSource(
|
| const RasterSource* raster_source,
|
| bool resource_has_previous_content,
|
| @@ -43,11 +79,17 @@ static void RasterizeSource(
|
| int msaa_sample_count) {
|
| ScopedGpuRaster gpu_raster(context_provider);
|
|
|
| - ResourceProvider::ScopedSkSurfaceProvider scoped_surface(
|
| - context_provider, resource_lock, async_worker_context_enabled,
|
| - use_distance_field_text, raster_source->CanUseLCDText(),
|
| - msaa_sample_count);
|
| - SkSurface* sk_surface = scoped_surface.sk_surface();
|
| + gpu::gles2::GLES2Interface* gl = context_provider->ContextGL();
|
| +
|
| + unsigned texture_id = resource_lock->texture_id();
|
| + if (async_worker_context_enabled)
|
| + texture_id = resource_lock->ConsumeTexture(gl);
|
| +
|
| + sk_sp<SkSurface> sk_surface = CreateSkSurface(
|
| + context_provider->GrContext(), texture_id, resource_lock->target(),
|
| + resource_lock->size(), resource_lock->format(), use_distance_field_text,
|
| + raster_source->CanUseLCDText(), msaa_sample_count);
|
| +
|
| // Allocating an SkSurface will fail after a lost context. Pretend we
|
| // rasterized, as the contents of the resource don't matter anymore.
|
| if (!sk_surface) {
|
| @@ -80,6 +122,11 @@ static void RasterizeSource(
|
| raster_source->PlaybackToCanvas(
|
| sk_surface->getCanvas(), resource_lock->color_space_for_raster(),
|
| raster_full_rect, playback_rect, transform, playback_settings);
|
| +
|
| + sk_surface->prepareForExternalIO();
|
| +
|
| + if (async_worker_context_enabled)
|
| + gl->DeleteTextures(1, &texture_id);
|
| }
|
|
|
| } // namespace
|
| @@ -265,14 +312,17 @@ void GpuRasterBufferProvider::PlaybackOnWorkerThread(
|
| const gfx::AxisTransform2d& transform,
|
| const RasterSource::PlaybackSettings& playback_settings) {
|
| ContextProvider::ScopedContextLock scoped_context(worker_context_provider_);
|
| +
|
| gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL();
|
| DCHECK(gl);
|
|
|
| if (async_worker_context_enabled_) {
|
| // Early out if sync token is invalid. This happens if the compositor
|
| // context was lost before ScheduleTasks was called.
|
| - if (!sync_token.HasData())
|
| + if (!sync_token.HasData()) {
|
| + DLOG(ERROR) << "Context destroyed while scheduling raster tasks";
|
| return;
|
| + }
|
| // Synchronize with compositor.
|
| gl->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
|
| }
|
| @@ -292,7 +342,6 @@ void GpuRasterBufferProvider::PlaybackOnWorkerThread(
|
| gpu::SyncToken resource_sync_token;
|
| gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, resource_sync_token.GetData());
|
| resource_lock->set_sync_token(resource_sync_token);
|
| - resource_lock->set_synchronized(!async_worker_context_enabled_);
|
| }
|
|
|
| } // namespace cc
|
|
|