summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorjoth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-21 07:24:24 +0000
committerjoth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-21 07:24:24 +0000
commitfbe89f77b847566e6ca80f5667df5bb7b3cccc53 (patch)
tree52ce8a300c3921097972530ace4b4ad2b29d722c /cc
parentf71e84058d13cbc3198e72433c9933fd0e56d3b5 (diff)
downloadchromium_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.cc2
-rw-r--r--cc/output/output_surface.h4
-rw-r--r--cc/test/fake_output_surface.cc6
-rw-r--r--cc/test/fake_output_surface.h14
-rw-r--r--cc/trees/layer_tree_host_impl.cc79
-rw-r--r--cc/trees/layer_tree_host_impl.h5
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc40
-rw-r--r--cc/trees/thread_proxy.cc57
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) {