diff options
author | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-21 07:24:24 +0000 |
---|---|---|
committer | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-21 07:24:24 +0000 |
commit | fbe89f77b847566e6ca80f5667df5bb7b3cccc53 (patch) | |
tree | 52ce8a300c3921097972530ace4b4ad2b29d722c /cc | |
parent | f71e84058d13cbc3198e72433c9933fd0e56d3b5 (diff) | |
download | chromium_src-fbe89f77b847566e6ca80f5667df5bb7b3cccc53.zip chromium_src-fbe89f77b847566e6ca80f5667df5bb7b3cccc53.tar.gz chromium_src-fbe89f77b847566e6ca80f5667df5bb7b3cccc53.tar.bz2 |
Makes the resource provider and tile manager optional in LayerTreeHostImpl.
This is used with ForcedDrawToSoftwareDevice / tile-free rendering, in the
android webview synchronous compositor, to enable just-in-time software
renderer and prepare way for lazy GL render initialization (crbug.com/230197)
(Inc. minor fix to tracing category used in SyncInputEventFilter)
BUG=230226
Review URL: https://chromiumcodereview.appspot.com/14918013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201247 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/layers/picture_layer_impl.cc | 2 | ||||
-rw-r--r-- | cc/output/output_surface.h | 4 | ||||
-rw-r--r-- | cc/test/fake_output_surface.cc | 6 | ||||
-rw-r--r-- | cc/test/fake_output_surface.h | 14 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 79 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.h | 5 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl_unittest.cc | 40 | ||||
-rw-r--r-- | cc/trees/thread_proxy.cc | 57 |
8 files changed, 152 insertions, 55 deletions
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 2151642..c7c9a7c 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -940,6 +940,8 @@ bool PictureLayerImpl::CanHaveTilings() const { return false; if (pile_->recorded_region().IsEmpty()) return false; + if (!layer_tree_impl()->tile_manager()) + return false; return true; } diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h index e8d6fe3..0be2e3b 100644 --- a/cc/output/output_surface.h +++ b/cc/output/output_surface.h @@ -44,10 +44,12 @@ class CC_EXPORT OutputSurface { struct Capabilities { Capabilities() : has_parent_compositor(false), - max_frames_pending(0) {} + max_frames_pending(0), + deferred_gl_initialization(false) {} bool has_parent_compositor; int max_frames_pending; + bool deferred_gl_initialization; }; const Capabilities& capabilities() const { diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc index f7819ba..1196419 100644 --- a/cc/test/fake_output_surface.cc +++ b/cc/test/fake_output_surface.cc @@ -16,6 +16,7 @@ FakeOutputSurface::FakeOutputSurface( : OutputSurface(context3d.Pass()), num_sent_frames_(0), vsync_notification_enabled_(false), + forced_draw_to_software_device_(false), weak_ptr_factory_(this) { capabilities_.has_parent_compositor = has_parent; } @@ -24,6 +25,7 @@ FakeOutputSurface::FakeOutputSurface( scoped_ptr<SoftwareOutputDevice> software_device, bool has_parent) : OutputSurface(software_device.Pass()), num_sent_frames_(0), + forced_draw_to_software_device_(false), weak_ptr_factory_(this) { capabilities_.has_parent_compositor = has_parent; } @@ -47,6 +49,10 @@ void FakeOutputSurface::DidVSync(base::TimeTicks frame_time) { client_->DidVSync(frame_time); } +bool FakeOutputSurface::ForcedDrawToSoftwareDevice() const { + return forced_draw_to_software_device_; +} + void FakeOutputSurface::SendFrameAck() { CompositorFrameAck ack; client_->OnSendFrameToParentCompositorAck(ack); diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h index f7ca21d..435756d 100644 --- a/cc/test/fake_output_surface.h +++ b/cc/test/fake_output_surface.h @@ -57,6 +57,14 @@ class FakeOutputSurface : public OutputSurface { new FakeOutputSurface(software_device.Pass(), true)); } + static scoped_ptr<FakeOutputSurface> CreateDeferredGL( + scoped_ptr<SoftwareOutputDevice> software_device) { + scoped_ptr<FakeOutputSurface> result( + new FakeOutputSurface(software_device.Pass(), false)); + result->capabilities_.deferred_gl_initialization = true; + return result.Pass(); + } + virtual void SendFrameToParentCompositor(CompositorFrame* frame) OVERRIDE; CompositorFrame& last_sent_frame() { return last_sent_frame_; } @@ -68,6 +76,11 @@ class FakeOutputSurface : public OutputSurface { } void DidVSync(base::TimeTicks frame_time); + void set_forced_draw_to_software_device(bool forced) { + forced_draw_to_software_device_ = forced; + } + virtual bool ForcedDrawToSoftwareDevice() const OVERRIDE; + private: FakeOutputSurface( scoped_ptr<WebKit::WebGraphicsContext3D> context3d, @@ -82,6 +95,7 @@ class FakeOutputSurface : public OutputSurface { CompositorFrame last_sent_frame_; size_t num_sent_frames_; bool vsync_notification_enabled_; + bool forced_draw_to_software_device_; base::WeakPtrFactory<FakeOutputSurface> weak_ptr_factory_; }; diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index b6e597e..0b87836 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -723,8 +723,10 @@ bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame); if (!output_surface_->ForcedDrawToSoftwareDevice()) renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes); - RemoveRenderPasses(CullRenderPassesWithCachedTextures(renderer_.get()), - frame); + if (renderer_) { + RemoveRenderPasses(CullRenderPassesWithCachedTextures(renderer_.get()), + frame); + } // If we're making a frame to draw, it better have at least one render pass. DCHECK(!frame->render_passes.empty()); @@ -804,6 +806,7 @@ static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id, bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures:: ShouldRemoveRenderPass(const RenderPassDrawQuad& quad, const FrameData& frame) const { + DCHECK(renderer_); bool quad_has_damage = !quad.contents_changed_since_last_frame.IsEmpty(); bool quad_has_cached_resource = renderer_->HaveCachedResourcesForRenderPassId(quad.render_pass_id); @@ -1155,7 +1158,8 @@ void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) { // Once all layers have been drawn, pending texture uploads should no // longer block future uploads. - resource_provider_->MarkPendingUploadsAsNonBlocking(); + if (resource_provider_) + resource_provider_->MarkPendingUploadsAsNonBlocking(); } void LayerTreeHostImpl::FinishAllRendering() { @@ -1287,7 +1291,7 @@ bool LayerTreeHostImpl::ActivatePendingTreeIfNeeded() { if (!pending_tree_) return false; - CHECK(tile_manager_); + CHECK(settings_.impl_side_painting); pending_tree_->UpdateDrawProperties(); @@ -1296,9 +1300,11 @@ bool LayerTreeHostImpl::ActivatePendingTreeIfNeeded() { "PendingTree", pending_tree_.get(), "activate", "state", TracedValue::FromValue(ActivationStateAsValue().release())); - // Activate once all visible resources in pending tree are ready. - if (!pending_tree_->AreVisibleResourcesReady()) - return false; + if (resource_provider_) { + // Activate once all visible resources in pending tree are ready. + if (!pending_tree_->AreVisibleResourcesReady()) + return false; + } ActivatePendingTree(); return true; @@ -1404,37 +1410,44 @@ bool LayerTreeHostImpl::InitializeRenderer( if (!output_surface->BindToClient(this)) return false; - scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create( - output_surface.get(), settings_.highp_threshold_min); - if (!resource_provider) - return false; + if (output_surface->capabilities().deferred_gl_initialization) { + // TODO(joth): Defer creating the Renderer too, until GL is initialized. + // See http://crbug.com/230197 + renderer_ = SoftwareRenderer::Create(this, output_surface.get(), NULL); + } else { + scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create( + output_surface.get(), settings_.highp_threshold_min); + if (!resource_provider) + return false; - if (settings_.impl_side_painting) { - tile_manager_ = TileManager::Create(this, - resource_provider.get(), - settings_.num_raster_threads, - settings_.use_color_estimator, - rendering_stats_instrumentation_); - UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy()); - } + if (settings_.impl_side_painting) { + tile_manager_ = TileManager::Create(this, + resource_provider.get(), + settings_.num_raster_threads, + settings_.use_color_estimator, + rendering_stats_instrumentation_); + UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy()); + } - if (output_surface->capabilities().has_parent_compositor) { - renderer_ = DelegatingRenderer::Create(this, output_surface.get(), + if (output_surface->capabilities().has_parent_compositor) { + renderer_ = DelegatingRenderer::Create(this, output_surface.get(), + resource_provider.get()); + } else if (output_surface->context3d()) { + renderer_ = GLRenderer::Create(this, + output_surface.get(), + resource_provider.get(), + settings_.highp_threshold_min); + } else if (output_surface->software_device()) { + renderer_ = SoftwareRenderer::Create(this, + output_surface.get(), resource_provider.get()); - } else if (output_surface->context3d()) { - renderer_ = GLRenderer::Create(this, - output_surface.get(), - resource_provider.get(), - settings_.highp_threshold_min); - } else if (output_surface->software_device()) { - renderer_ = SoftwareRenderer::Create(this, - output_surface.get(), - resource_provider.get()); + } + if (!renderer_) + return false; + + resource_provider_ = resource_provider.Pass(); } - if (!renderer_) - return false; - resource_provider_ = resource_provider.Pass(); output_surface_ = output_surface.Pass(); if (!visible_) diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 72b06b5..3aebeec 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -432,9 +432,12 @@ class CC_EXPORT LayerTreeHostImpl void StartScrollbarAnimationRecursive(LayerImpl* layer, base::TimeTicks time); scoped_ptr<OutputSurface> output_surface_; + + // |resource_provider_| and |tile_manager_| can be NULL, e.g. when using tile- + // free rendering - see OutputSurface::ForcedDrawToSoftwareDevice(). scoped_ptr<ResourceProvider> resource_provider_; - scoped_ptr<Renderer> renderer_; scoped_ptr<TileManager> tile_manager_; + scoped_ptr<Renderer> renderer_; // Tree currently being drawn. scoped_ptr<LayerTreeImpl> active_tree_; diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 866bfca..087a761 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -245,6 +245,10 @@ class LayerTreeHostImplTest : public testing::Test, void InitializeRendererAndDrawFrame() { host_impl_->InitializeRenderer(CreateOutputSurface()); + DrawFrame(); + } + + void DrawFrame() { LayerTreeHostImpl::FrameData frame; EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, base::TimeTicks::Now()); @@ -5660,5 +5664,41 @@ TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) { EXPECT_EQ(swap_buffers_complete_, 1); } +class CountingSoftwareDevice : public SoftwareOutputDevice { + public: + CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {} + + virtual SkCanvas* BeginPaint(gfx::Rect damage_rect) OVERRIDE { + ++frames_began_; + return SoftwareOutputDevice::BeginPaint(damage_rect); + } + virtual void EndPaint(SoftwareFrameData* frame_data) OVERRIDE { + ++frames_ended_; + SoftwareOutputDevice::EndPaint(frame_data); + } + + int frames_began_, frames_ended_; +}; + +TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceBasicRender) { + SetupScrollAndContentsLayers(gfx::Size(100, 100)); + host_impl_->SetViewportSize(gfx::Size(50, 50)); + CountingSoftwareDevice* software_device = new CountingSoftwareDevice(); + FakeOutputSurface* output_surface = FakeOutputSurface::CreateDeferredGL( + scoped_ptr<SoftwareOutputDevice>(software_device)).release(); + host_impl_->InitializeRenderer(scoped_ptr<OutputSurface>(output_surface)); + + output_surface->set_forced_draw_to_software_device(true); + EXPECT_TRUE(output_surface->ForcedDrawToSoftwareDevice()); + + EXPECT_EQ(0, software_device->frames_began_); + EXPECT_EQ(0, software_device->frames_ended_); + + DrawFrame(); + + EXPECT_EQ(1, software_device->frames_began_); + EXPECT_EQ(1, software_device->frames_ended_); +} + } // namespace } // namespace cc diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index c8b8cc4..05259c9 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -300,8 +300,12 @@ void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() { TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread"); if (!layer_tree_host_impl_->IsContextLost()) return; - if (cc::ContextProvider* offscreen_contexts = layer_tree_host_impl_-> - resource_provider()->offscreen_context_provider()) + cc::ContextProvider* offscreen_contexts = + layer_tree_host_impl_->resource_provider() ? + layer_tree_host_impl_->resource_provider()-> + offscreen_context_provider() : NULL; + + if (offscreen_contexts) offscreen_contexts->VerifyContexts(); scheduler_on_impl_thread_->DidLoseOutputSurface(); } @@ -404,6 +408,8 @@ bool ThreadProxy::ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes, if (!layer_tree_host_->contents_texture_manager()) return false; + if (!layer_tree_host_impl_->resource_provider()) + return false; bool reduce_result = layer_tree_host_->contents_texture_manager()-> ReduceMemoryOnImplThread(limit_bytes, @@ -426,6 +432,8 @@ void ThreadProxy::ReduceWastedContentsTextureMemoryOnImplThread() { if (!layer_tree_host_->contents_texture_manager()) return; + if (!layer_tree_host_impl_->resource_provider()) + return; layer_tree_host_->contents_texture_manager()->ReduceWastedMemoryOnImplThread( layer_tree_host_impl_->resource_provider()); @@ -777,8 +785,10 @@ void ThreadProxy::BeginFrameCompleteOnImplThread( if (offscreen_context_provider) offscreen_context_provider->BindToCurrentThread(); - layer_tree_host_impl_->resource_provider()-> - set_offscreen_context_provider(offscreen_context_provider); + if (layer_tree_host_impl_->resource_provider()) { + layer_tree_host_impl_->resource_provider()-> + set_offscreen_context_provider(offscreen_context_provider); + } if (layer_tree_host_->contents_texture_manager()-> LinkedEvictedBackingsExist()) { @@ -793,16 +803,22 @@ void ThreadProxy::BeginFrameCompleteOnImplThread( layer_tree_host_->contents_texture_manager()-> PushTexturePrioritiesToBackings(); - current_resource_update_controller_on_impl_thread_ = - ResourceUpdateController::Create( - this, - Proxy::ImplThread(), - queue.Pass(), - layer_tree_host_impl_->resource_provider()); - current_resource_update_controller_on_impl_thread_->PerformMoreUpdates( - scheduler_on_impl_thread_->AnticipatedDrawTime()); - commit_completion_event_on_impl_thread_ = completion; + if (layer_tree_host_impl_->resource_provider()) { + current_resource_update_controller_on_impl_thread_ = + ResourceUpdateController::Create( + this, + Proxy::ImplThread(), + queue.Pass(), + layer_tree_host_impl_->resource_provider()); + current_resource_update_controller_on_impl_thread_->PerformMoreUpdates( + scheduler_on_impl_thread_->AnticipatedDrawTime()); + } else { + // Normally the ResourceUpdateController notifies when begin frame has + // completed, but in tile-free software rendering there is no resource + // update step so jump straight to the notification. + scheduler_on_impl_thread_->BeginFrameComplete(); + } } void ThreadProxy::BeginFrameAbortedOnImplThread() { @@ -818,11 +834,11 @@ void ThreadProxy::ScheduledActionCommit() { TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionCommit"); DCHECK(IsImplThread()); DCHECK(commit_completion_event_on_impl_thread_); - DCHECK(current_resource_update_controller_on_impl_thread_); - - // Complete all remaining texture updates. - current_resource_update_controller_on_impl_thread_->Finalize(); - current_resource_update_controller_on_impl_thread_.reset(); + if (current_resource_update_controller_on_impl_thread_) { + // Complete all remaining texture updates. + current_resource_update_controller_on_impl_thread_->Finalize(); + current_resource_update_controller_on_impl_thread_.reset(); + } layer_tree_host_impl_->BeginCommit(); layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get()); @@ -1166,8 +1182,9 @@ void ThreadProxy::InitializeOutputSurfaceOnImplThread( scheduler_on_impl_thread_->SetMaxFramesPending(max_frames_pending); - layer_tree_host_impl_->resource_provider()-> - set_offscreen_context_provider(offscreen_context_provider); + if (layer_tree_host_impl_->resource_provider()) + layer_tree_host_impl_->resource_provider()-> + set_offscreen_context_provider(offscreen_context_provider); scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface(); } else if (offscreen_context_provider) { |