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 51d8898283651d8113effad512a9f4766316691f..fd3026821b99061e9080fb0a8ae0e7c66b68e581 100644 |
--- a/cc/raster/gpu_raster_buffer_provider.cc |
+++ b/cc/raster/gpu_raster_buffer_provider.cc |
@@ -26,15 +26,12 @@ namespace { |
class RasterBufferImpl : public RasterBuffer { |
public: |
- RasterBufferImpl(GpuRasterizer* rasterizer, |
- const Resource* resource, |
- uint64_t resource_content_id, |
- uint64_t previous_content_id) |
- : rasterizer_(rasterizer), |
- lock_(rasterizer->resource_provider(), resource->id()), |
- resource_has_previous_content_( |
- resource_content_id && resource_content_id == previous_content_id) { |
- } |
+ RasterBufferImpl(GpuRasterBufferProvider* client, |
+ std::unique_ptr<ResourceProvider::ScopedWriteLockGr> lock, |
+ bool resource_has_previous_content) |
+ : client_(client), |
+ lock_(std::move(lock)), |
+ resource_has_previous_content_(resource_has_previous_content) {} |
// Overridden from RasterBuffer: |
void Playback( |
@@ -45,42 +42,15 @@ class RasterBufferImpl : public RasterBuffer { |
float scale, |
const RasterSource::PlaybackSettings& playback_settings) override { |
TRACE_EVENT0("cc", "RasterBufferImpl::Playback"); |
- // GPU raster doesn't do low res tiles, so should always include images. |
- DCHECK(!playback_settings.skip_images); |
- ContextProvider* context_provider = rasterizer_->resource_provider() |
- ->output_surface() |
- ->worker_context_provider(); |
- DCHECK(context_provider); |
- |
- ContextProvider::ScopedContextLock scoped_context(context_provider); |
- |
- gfx::Rect playback_rect = raster_full_rect; |
- if (resource_has_previous_content_) { |
- playback_rect.Intersect(raster_dirty_rect); |
- } |
- DCHECK(!playback_rect.IsEmpty()) |
- << "Why are we rastering a tile that's not dirty?"; |
- |
- // TODO(danakj): Implement partial raster with raster_dirty_rect. |
- // Rasterize source into resource. |
- rasterizer_->RasterizeSource(&lock_, raster_source, raster_full_rect, |
- playback_rect, scale, playback_settings); |
- |
- gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); |
- const uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM(); |
- |
- // Barrier to sync worker context output to cc context. |
- gl->OrderingBarrierCHROMIUM(); |
- |
- // Generate sync token after the barrier for cross context synchronization. |
- gpu::SyncToken sync_token; |
- gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); |
- lock_.UpdateResourceSyncToken(sync_token); |
+ client_->PlaybackOnWorkerThread(lock_.get(), resource_has_previous_content_, |
+ raster_source, raster_full_rect, |
+ raster_dirty_rect, new_content_id, scale, |
+ playback_settings); |
} |
private: |
- GpuRasterizer* rasterizer_; |
- ResourceProvider::ScopedWriteLockGr lock_; |
+ GpuRasterBufferProvider* client_; |
+ std::unique_ptr<ResourceProvider::ScopedWriteLockGr> lock_; |
bool resource_has_previous_content_; |
DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl); |
@@ -93,21 +63,24 @@ std::unique_ptr<RasterBufferProvider> GpuRasterBufferProvider::Create( |
ContextProvider* context_provider, |
ResourceProvider* resource_provider, |
bool use_distance_field_text, |
- int gpu_rasterization_msaa_sample_count) { |
+ int gpu_rasterization_msaa_sample_count, |
+ bool async_worker_context_enabled) { |
return base::WrapUnique<RasterBufferProvider>(new GpuRasterBufferProvider( |
context_provider, resource_provider, use_distance_field_text, |
- gpu_rasterization_msaa_sample_count)); |
+ gpu_rasterization_msaa_sample_count, async_worker_context_enabled)); |
} |
GpuRasterBufferProvider::GpuRasterBufferProvider( |
ContextProvider* context_provider, |
ResourceProvider* resource_provider, |
bool use_distance_field_text, |
- int gpu_rasterization_msaa_sample_count) |
+ int gpu_rasterization_msaa_sample_count, |
+ bool async_worker_context_enabled) |
: rasterizer_(new GpuRasterizer(context_provider, |
resource_provider, |
use_distance_field_text, |
- gpu_rasterization_msaa_sample_count)) {} |
+ gpu_rasterization_msaa_sample_count)), |
+ async_worker_context_enabled_(async_worker_context_enabled) {} |
GpuRasterBufferProvider::~GpuRasterBufferProvider() {} |
@@ -115,8 +88,13 @@ std::unique_ptr<RasterBuffer> GpuRasterBufferProvider::AcquireBufferForRaster( |
const Resource* resource, |
uint64_t resource_content_id, |
uint64_t previous_content_id) { |
+ bool resource_has_previous_content = |
+ resource_content_id && resource_content_id == previous_content_id; |
return std::unique_ptr<RasterBuffer>(new RasterBufferImpl( |
- rasterizer_.get(), resource, resource_content_id, previous_content_id)); |
+ this, base::WrapUnique(new ResourceProvider::ScopedWriteLockGr( |
+ rasterizer_->resource_provider(), resource->id(), |
+ async_worker_context_enabled_)), |
+ resource_has_previous_content)); |
} |
void GpuRasterBufferProvider::ReleaseBufferForRaster( |
@@ -127,11 +105,15 @@ void GpuRasterBufferProvider::ReleaseBufferForRaster( |
void GpuRasterBufferProvider::OrderingBarrier() { |
TRACE_EVENT0("cc", "GpuRasterBufferProvider::OrderingBarrier"); |
- rasterizer_->resource_provider() |
- ->output_surface() |
- ->context_provider() |
- ->ContextGL() |
- ->OrderingBarrierCHROMIUM(); |
+ gpu::gles2::GLES2Interface* gl = rasterizer_->resource_provider() |
+ ->output_surface() |
+ ->context_provider() |
+ ->ContextGL(); |
+ |
+ // Synchronize with compositor. |
+ GLuint64 fence = gl->InsertFenceSyncCHROMIUM(); |
+ gl->OrderingBarrierCHROMIUM(); |
+ gl->GenUnverifiedSyncTokenCHROMIUM(fence, sync_token_.GetData()); |
} |
ResourceFormat GpuRasterBufferProvider::GetResourceFormat( |
@@ -147,4 +129,50 @@ bool GpuRasterBufferProvider::GetResourceRequiresSwizzle( |
void GpuRasterBufferProvider::Shutdown() {} |
+void GpuRasterBufferProvider::PlaybackOnWorkerThread( |
+ ResourceProvider::ScopedWriteLockGr* lock, |
+ bool resource_has_previous_content, |
+ const RasterSource* raster_source, |
+ const gfx::Rect& raster_full_rect, |
+ const gfx::Rect& raster_dirty_rect, |
+ uint64_t new_content_id, |
+ float scale, |
+ const RasterSource::PlaybackSettings& playback_settings) { |
+ // GPU raster doesn't do low res tiles, so should always include images. |
+ DCHECK(!playback_settings.skip_images); |
+ ContextProvider* context_provider = rasterizer_->resource_provider() |
+ ->output_surface() |
+ ->worker_context_provider(); |
+ DCHECK(context_provider); |
+ |
+ ContextProvider::ScopedContextLock scoped_context(context_provider); |
+ gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); |
+ |
+ gfx::Rect playback_rect = raster_full_rect; |
+ if (resource_has_previous_content) { |
+ playback_rect.Intersect(raster_dirty_rect); |
+ } |
+ DCHECK(!playback_rect.IsEmpty()) |
+ << "Why are we rastering a tile that's not dirty?"; |
+ |
+ // Synchronize with compositor if worker context is async. |
+ DCHECK(sync_token_.HasData()); |
+ gl->WaitSyncTokenCHROMIUM(sync_token_.GetData()); |
+ |
+ // TODO(danakj): Implement partial raster with raster_dirty_rect. |
+ // Rasterize source into resource. |
+ rasterizer_->RasterizeSource(lock, raster_source, raster_full_rect, |
+ playback_rect, scale, playback_settings); |
+ |
+ const uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM(); |
+ |
+ // Barrier to sync worker context output to cc context. |
+ gl->OrderingBarrierCHROMIUM(); |
+ |
+ // Generate sync token after the barrier for cross context synchronization. |
+ gpu::SyncToken sync_token; |
+ gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); |
+ lock->UpdateResourceSyncToken(sync_token); |
+} |
+ |
} // namespace cc |