diff options
45 files changed, 355 insertions, 389 deletions
diff --git a/cc/output/delegating_renderer.cc b/cc/output/delegating_renderer.cc index ba2c4ec..3cb6b4f 100644 --- a/cc/output/delegating_renderer.cc +++ b/cc/output/delegating_renderer.cc @@ -53,8 +53,6 @@ bool DelegatingRenderer::Initialize() { capabilities_.using_partial_swap = false; // TODO(danakj): Throttling - we may want to only allow 1 outstanding frame, // but the parent compositor may pipeline for us. - // TODO(danakj): Can we use this in single-thread mode? - capabilities_.using_swap_complete_callback = true; capabilities_.max_texture_size = resource_provider_->max_texture_size(); capabilities_.best_texture_format = resource_provider_->best_texture_format(); capabilities_.allow_partial_texture_updates = false; @@ -156,10 +154,10 @@ void DelegatingRenderer::DrawFrame( resource_provider_->PrepareSendToParent(resources, &out_data.resource_list); } -void DelegatingRenderer::SwapBuffers(const ui::LatencyInfo& latency_info) { +void DelegatingRenderer::SwapBuffers() { TRACE_EVENT0("cc", "DelegatingRenderer::SwapBuffers"); - output_surface_->SendFrameToParentCompositor(&frame_for_swap_buffers_); + output_surface_->SwapBuffers(&frame_for_swap_buffers_); frame_for_swap_buffers_.delegated_frame_data.reset(); } @@ -167,7 +165,7 @@ void DelegatingRenderer::GetFramebufferPixels(void* pixels, gfx::Rect rect) { NOTREACHED(); } -void DelegatingRenderer::ReceiveCompositorFrameAck( +void DelegatingRenderer::ReceiveSwapBuffersAck( const CompositorFrameAck& ack) { resource_provider_->ReceiveFromParent(ack.resources); } diff --git a/cc/output/delegating_renderer.h b/cc/output/delegating_renderer.h index 20aa3f6..eb7e68f 100644 --- a/cc/output/delegating_renderer.h +++ b/cc/output/delegating_renderer.h @@ -32,12 +32,11 @@ class CC_EXPORT DelegatingRenderer : public Renderer { virtual void Finish() OVERRIDE {} - virtual void SwapBuffers(const ui::LatencyInfo& latency_info) OVERRIDE; + virtual void SwapBuffers() OVERRIDE; + virtual void ReceiveSwapBuffersAck(const CompositorFrameAck&) OVERRIDE; virtual void GetFramebufferPixels(void* pixels, gfx::Rect rect) OVERRIDE; - virtual void ReceiveCompositorFrameAck(const CompositorFrameAck&) OVERRIDE; - virtual bool IsContextLost() OVERRIDE; virtual void SetVisible(bool visible) OVERRIDE; diff --git a/cc/output/gl_frame_data.cc b/cc/output/gl_frame_data.cc index b5b5721..06cf3f4 100644 --- a/cc/output/gl_frame_data.cc +++ b/cc/output/gl_frame_data.cc @@ -7,7 +7,8 @@ namespace cc { GLFrameData::GLFrameData() - : sync_point(0) { + : sync_point(0), + partial_swap_allowed(false) { } GLFrameData::~GLFrameData() {} diff --git a/cc/output/gl_frame_data.h b/cc/output/gl_frame_data.h index e6d227f..b8ec5ec 100644 --- a/cc/output/gl_frame_data.h +++ b/cc/output/gl_frame_data.h @@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "cc/base/cc_export.h" #include "gpu/command_buffer/common/mailbox.h" +#include "ui/gfx/rect.h" #include "ui/gfx/size.h" namespace cc { @@ -22,6 +23,8 @@ class CC_EXPORT GLFrameData { gpu::Mailbox mailbox; uint32 sync_point; gfx::Size size; + gfx::Rect sub_buffer_rect; + bool partial_swap_allowed; }; } // namespace cc diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 6470ef20..1a19d28 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -157,11 +157,6 @@ bool GLRenderer::Initialize() { Settings().partial_swap_enabled && extensions.count("GL_CHROMIUM_post_sub_buffer"); - // Use the SwapBuffers callback only with the threaded proxy. - if (client_->HasImplThread()) - capabilities_.using_swap_complete_callback = - extensions.count("GL_CHROMIUM_swapbuffers_complete_callback") > 0; - capabilities_.using_set_visibility = extensions.count("GL_CHROMIUM_set_visibility") > 0; @@ -1859,12 +1854,6 @@ void GLRenderer::FinishDrawingFrame(DrawingFrame* frame) { GLC(context_, context_->disable(GL_BLEND)); blend_shadow_ = false; - - if (Settings().compositor_frame_message) { - CompositorFrame compositor_frame; - compositor_frame.metadata = client_->MakeCompositorFrameMetadata(); - output_surface_->SendFrameToParentCompositor(&compositor_frame); - } } void GLRenderer::FinishDrawingQuadList() { FlushTextureQuadCache(); } @@ -1984,13 +1973,17 @@ void GLRenderer::Finish() { context_->finish(); } -void GLRenderer::SwapBuffers(const ui::LatencyInfo& latency_info) { +void GLRenderer::SwapBuffers() { DCHECK(visible_); DCHECK(!is_backbuffer_discarded_); TRACE_EVENT0("cc", "GLRenderer::SwapBuffers"); // We're done! Time to swapbuffers! + CompositorFrame compositor_frame; + compositor_frame.metadata = client_->MakeCompositorFrameMetadata(); + compositor_frame.gl_frame_data = make_scoped_ptr(new GLFrameData); + compositor_frame.gl_frame_data->size = output_surface_->SurfaceSize(); if (capabilities_.using_partial_swap && client_->AllowPartialSwap()) { // If supported, we can save significant bandwidth by only swapping the // damaged/scissored region (clamped to the viewport) @@ -1998,14 +1991,18 @@ void GLRenderer::SwapBuffers(const ui::LatencyInfo& latency_info) { int flipped_y_pos_of_rect_bottom = client_->DeviceViewport().height() - swap_buffer_rect_.y() - swap_buffer_rect_.height(); - output_surface_->PostSubBuffer(gfx::Rect(swap_buffer_rect_.x(), - flipped_y_pos_of_rect_bottom, - swap_buffer_rect_.width(), - swap_buffer_rect_.height()), - latency_info); + compositor_frame.gl_frame_data->sub_buffer_rect = + gfx::Rect(swap_buffer_rect_.x(), + flipped_y_pos_of_rect_bottom, + swap_buffer_rect_.width(), + swap_buffer_rect_.height()); + compositor_frame.gl_frame_data->partial_swap_allowed = true; } else { - output_surface_->SwapBuffers(latency_info); + compositor_frame.gl_frame_data->sub_buffer_rect = + gfx::Rect(output_surface_->SurfaceSize()); + compositor_frame.gl_frame_data->partial_swap_allowed = false; } + output_surface_->SwapBuffers(&compositor_frame); swap_buffer_rect_ = gfx::Rect(); diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h index e693777..12eb8f7 100644 --- a/cc/output/gl_renderer.h +++ b/cc/output/gl_renderer.h @@ -60,8 +60,7 @@ class CC_EXPORT GLRenderer virtual void Finish() OVERRIDE; virtual void DoNoOp() OVERRIDE; - // Puts backbuffer onscreen. - virtual void SwapBuffers(const ui::LatencyInfo& latency_info) OVERRIDE; + virtual void SwapBuffers() OVERRIDE; virtual void GetFramebufferPixels(void* pixels, gfx::Rect rect) OVERRIDE; diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc index c1c8842..73ba45c 100644 --- a/cc/output/gl_renderer_unittest.cc +++ b/cc/output/gl_renderer_unittest.cc @@ -264,7 +264,7 @@ class GLRendererTest : public testing::Test { virtual void SetUp() { renderer_.Initialize(); } - void SwapBuffers() { renderer_.SwapBuffers(ui::LatencyInfo()); } + void SwapBuffers() { renderer_.SwapBuffers(); } FrameCountingMemoryAllocationSettingContext* Context() { return static_cast<FrameCountingMemoryAllocationSettingContext*>( @@ -1552,13 +1552,11 @@ class MockOutputSurface : public OutputSurface { } virtual ~MockOutputSurface() {} - MOCK_METHOD1(SendFrameToParentCompositor, void(CompositorFrame* frame)); MOCK_METHOD0(EnsureBackbuffer, void()); MOCK_METHOD0(DiscardBackbuffer, void()); MOCK_METHOD2(Reshape, void(gfx::Size size, float scale_factor)); MOCK_METHOD0(BindFramebuffer, void()); - MOCK_METHOD2(PostSubBuffer, void(gfx::Rect rect, const ui::LatencyInfo&)); - MOCK_METHOD1(SwapBuffers, void(const ui::LatencyInfo&)); + MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame)); }; class MockOutputSurfaceTest : public testing::Test, public FakeRendererClient { @@ -1569,7 +1567,7 @@ class MockOutputSurfaceTest : public testing::Test, public FakeRendererClient { virtual void SetUp() { EXPECT_TRUE(renderer_.Initialize()); } - void SwapBuffers() { renderer_.SwapBuffers(ui::LatencyInfo()); } + void SwapBuffers() { renderer_.SwapBuffers(); } void DrawFrame() { gfx::Rect viewport_rect(DeviceViewport()); @@ -1608,62 +1606,31 @@ TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) { DrawFrame(); EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); - renderer_.SwapBuffers(ui::LatencyInfo()); + renderer_.SwapBuffers(); } TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) { DrawFrame(); EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); - renderer_.SwapBuffers(ui::LatencyInfo()); + renderer_.SwapBuffers(); set_viewport_and_scale(gfx::Size(2, 2), 2.f); renderer_.ViewportChanged(); DrawFrame(); EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); - renderer_.SwapBuffers(ui::LatencyInfo()); + renderer_.SwapBuffers(); DrawFrame(); EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); - renderer_.SwapBuffers(ui::LatencyInfo()); + renderer_.SwapBuffers(); set_viewport_and_scale(gfx::Size(1, 1), 1.f); renderer_.ViewportChanged(); DrawFrame(); EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); - renderer_.SwapBuffers(ui::LatencyInfo()); -} - -class MockOutputSurfaceTestWithPartialSwap : public MockOutputSurfaceTest { - public: - virtual const LayerTreeSettings& Settings() const OVERRIDE { - static LayerTreeSettings fake_settings; - fake_settings.partial_swap_enabled = true; - return fake_settings; - } -}; - -TEST_F(MockOutputSurfaceTestWithPartialSwap, DrawFrameAndSwap) { - DrawFrame(); - - EXPECT_CALL(output_surface_, PostSubBuffer(_, _)).Times(1); - renderer_.SwapBuffers(ui::LatencyInfo()); -} - -class MockOutputSurfaceTestWithSendCompositorFrame - : public MockOutputSurfaceTest { - public: - virtual const LayerTreeSettings& Settings() const OVERRIDE { - static LayerTreeSettings fake_settings; - fake_settings.compositor_frame_message = true; - return fake_settings; - } -}; - -TEST_F(MockOutputSurfaceTestWithSendCompositorFrame, DrawFrame) { - EXPECT_CALL(output_surface_, SendFrameToParentCompositor(_)).Times(1); - DrawFrame(); + renderer_.SwapBuffers(); } class GLRendererTestSyncPoint : public GLRendererPixelTest { diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc index 3442f0d..0889b96 100644 --- a/cc/output/output_surface.cc +++ b/cc/output/output_surface.cc @@ -8,9 +8,12 @@ #include <string> #include <vector> +#include "base/bind.h" #include "base/logging.h" +#include "base/message_loop.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" +#include "cc/output/compositor_frame.h" #include "cc/output/output_surface_client.h" #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" #include "third_party/khronos/GLES2/gl2.h" @@ -35,7 +38,7 @@ class OutputSurfaceCallbacks } // WK:WGC3D::WGSwapBuffersCompleteCallbackCHROMIUM implementation. - virtual void onSwapBuffersComplete() { client_->OnSwapBuffersComplete(); } + virtual void onSwapBuffersComplete() { client_->OnSwapBuffersComplete(NULL); } // WK:WGC3D::WGContextLostCallback implementation. virtual void onContextLost() { client_->DidLoseOutputSurface(); } @@ -49,7 +52,9 @@ OutputSurface::OutputSurface( : client_(NULL), context3d_(context3d.Pass()), has_gl_discard_backbuffer_(false), - device_scale_factor_(-1) { + has_swap_buffers_complete_callback_(false), + device_scale_factor_(-1), + weak_ptr_factory_(this) { } OutputSurface::OutputSurface( @@ -57,7 +62,9 @@ OutputSurface::OutputSurface( : client_(NULL), software_device_(software_device.Pass()), has_gl_discard_backbuffer_(false), - device_scale_factor_(-1) { + has_swap_buffers_complete_callback_(false), + device_scale_factor_(-1), + weak_ptr_factory_(this) { } OutputSurface::OutputSurface( @@ -67,7 +74,9 @@ OutputSurface::OutputSurface( context3d_(context3d.Pass()), software_device_(software_device.Pass()), has_gl_discard_backbuffer_(false), - device_scale_factor_(-1) { + has_swap_buffers_complete_callback_(false), + device_scale_factor_(-1), + weak_ptr_factory_(this) { } OutputSurface::~OutputSurface() { @@ -129,6 +138,9 @@ void OutputSurface::SetContext3D( set<string> extensions(extensions_list.begin(), extensions_list.end()); has_gl_discard_backbuffer_ = extensions.count("GL_CHROMIUM_discard_backbuffer") > 0; + has_swap_buffers_complete_callback_ = + extensions.count("GL_CHROMIUM_swapbuffers_complete_callback") > 0; + context3d_ = context3d.Pass(); callbacks_.reset(new OutputSurfaceCallbacks(client_)); @@ -136,10 +148,6 @@ void OutputSurface::SetContext3D( context3d_->setContextLostCallback(callbacks_.get()); } -void OutputSurface::SendFrameToParentCompositor(CompositorFrame* frame) { - NOTIMPLEMENTED(); -} - void OutputSurface::EnsureBackbuffer() { DCHECK(context3d_); if (has_gl_discard_backbuffer_) @@ -162,6 +170,8 @@ void OutputSurface::Reshape(gfx::Size size, float scale_factor) { context3d_->reshapeWithScaleFactor( size.width(), size.height(), scale_factor); } + if (software_device_) + software_device_->Resize(size); } gfx::Size OutputSurface::SurfaceSize() const { @@ -173,18 +183,43 @@ void OutputSurface::BindFramebuffer() { context3d_->bindFramebuffer(GL_FRAMEBUFFER, 0); } -void OutputSurface::SwapBuffers(const ui::LatencyInfo& latency_info) { +void OutputSurface::SwapBuffers(cc::CompositorFrame* frame) { + if (frame->software_frame_data) { + PostSwapBuffersComplete(); + return; + } + DCHECK(context3d_); - // Note that currently this has the same effect as SwapBuffers; we should - // consider exposing a different entry point on WebGraphicsContext3D. - context3d_->prepareTexture(); + DCHECK(frame->gl_frame_data); + + if (frame->gl_frame_data->partial_swap_allowed) { + gfx::Rect sub_buffer_rect = frame->gl_frame_data->sub_buffer_rect; + context3d()->postSubBufferCHROMIUM(sub_buffer_rect.x(), + sub_buffer_rect.y(), + sub_buffer_rect.width(), + sub_buffer_rect.height()); + } else { + // Note that currently this has the same effect as SwapBuffers; we should + // consider exposing a different entry point on WebGraphicsContext3D. + context3d()->prepareTexture(); + } + + if (!has_swap_buffers_complete_callback_) + PostSwapBuffersComplete(); } -void OutputSurface::PostSubBuffer(gfx::Rect rect, - const ui::LatencyInfo& latency_info) { - DCHECK(context3d_); - context3d_->postSubBufferCHROMIUM( - rect.x(), rect.y(), rect.width(), rect.height()); +void OutputSurface::PostSwapBuffersComplete() { + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&OutputSurface::SwapBuffersComplete, + weak_ptr_factory_.GetWeakPtr())); +} + +void OutputSurface::SwapBuffersComplete() { + if (!client_) + return; + + client_->OnSwapBuffersComplete(NULL); } } // namespace cc diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h index fb93eb7..d263d3a 100644 --- a/cc/output/output_surface.h +++ b/cc/output/output_surface.h @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" #include "cc/base/cc_export.h" #include "cc/output/context_provider.h" #include "cc/output/software_output_device.h" @@ -46,11 +47,11 @@ class CC_EXPORT OutputSurface { struct Capabilities { Capabilities() - : has_parent_compositor(false), + : delegated_rendering(false), max_frames_pending(0), deferred_gl_initialization(false) {} - bool has_parent_compositor; + bool delegated_rendering; int max_frames_pending; bool deferred_gl_initialization; }; @@ -82,11 +83,6 @@ class CC_EXPORT OutputSurface { // thread. virtual bool BindToClient(OutputSurfaceClient* client); - // Sends frame data to the parent compositor. This should only be called when - // capabilities().has_parent_compositor. The implementation may destroy or - // steal the contents of the CompositorFrame passed in. - virtual void SendFrameToParentCompositor(CompositorFrame* frame); - virtual void EnsureBackbuffer(); virtual void DiscardBackbuffer(); @@ -95,8 +91,10 @@ class CC_EXPORT OutputSurface { virtual void BindFramebuffer(); - virtual void PostSubBuffer(gfx::Rect rect, const ui::LatencyInfo&); - virtual void SwapBuffers(const ui::LatencyInfo&); + // The implementation may destroy or steal the contents of the CompositorFrame + // passed in (though it will not take ownership of the CompositorFrame + // itself). + virtual void SwapBuffers(CompositorFrame* frame); // Notifies frame-rate smoothness preference. If true, all non-critical // processing should be stopped, or lowered in priority. @@ -116,17 +114,24 @@ class CC_EXPORT OutputSurface { scoped_ptr<WebKit::WebGraphicsContext3D> context3d, scoped_refptr<ContextProvider> offscreen_context_provider); + void PostSwapBuffersComplete(); + OutputSurfaceClient* client_; struct cc::OutputSurface::Capabilities capabilities_; scoped_ptr<OutputSurfaceCallbacks> callbacks_; scoped_ptr<WebKit::WebGraphicsContext3D> context3d_; scoped_ptr<cc::SoftwareOutputDevice> software_device_; bool has_gl_discard_backbuffer_; + bool has_swap_buffers_complete_callback_; gfx::Size surface_size_; float device_scale_factor_; private: void SetContext3D(scoped_ptr<WebKit::WebGraphicsContext3D> context3d); + void SwapBuffersComplete(); + + base::WeakPtrFactory<OutputSurface> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(OutputSurface); }; diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h index dc68e96..f5999c3 100644 --- a/cc/output/output_surface_client.h +++ b/cc/output/output_surface_client.h @@ -30,9 +30,7 @@ class CC_EXPORT OutputSurfaceClient { virtual void OnVSyncParametersChanged(base::TimeTicks timebase, base::TimeDelta interval) = 0; virtual void BeginFrame(base::TimeTicks frame_time) = 0; - virtual void OnSendFrameToParentCompositorAck( - const CompositorFrameAck& ack) = 0; - virtual void OnSwapBuffersComplete() = 0; + virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) = 0; virtual void DidLoseOutputSurface() = 0; virtual void SetExternalDrawConstraints(const gfx::Transform& transform, gfx::Rect viewport) = 0; diff --git a/cc/output/output_surface_unittest.cc b/cc/output/output_surface_unittest.cc index 72bf0a4..ebc018f 100644 --- a/cc/output/output_surface_unittest.cc +++ b/cc/output/output_surface_unittest.cc @@ -50,9 +50,7 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient { virtual void OnVSyncParametersChanged(base::TimeTicks timebase, base::TimeDelta interval) OVERRIDE {} virtual void BeginFrame(base::TimeTicks frame_time) OVERRIDE {} - virtual void OnSendFrameToParentCompositorAck(const CompositorFrameAck& ack) - OVERRIDE {} - virtual void OnSwapBuffersComplete() OVERRIDE {} + virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE {} virtual void DidLoseOutputSurface() OVERRIDE { did_lose_output_surface_called_ = true; } diff --git a/cc/output/renderer.h b/cc/output/renderer.h index a905d4c..efb1dfc 100644 --- a/cc/output/renderer.h +++ b/cc/output/renderer.h @@ -10,7 +10,6 @@ #include "cc/quads/render_pass.h" #include "cc/resources/managed_memory_policy.h" #include "cc/trees/layer_tree_host.h" -#include "ui/base/latency_info.h" namespace cc { @@ -49,7 +48,6 @@ class CC_EXPORT Renderer { const LayerTreeSettings& Settings() const { return client_->Settings(); } virtual void ViewportChanged() {} - virtual void ReceiveCompositorFrameAck(const CompositorFrameAck& ack) {} virtual bool CanReadPixels() const = 0; @@ -67,7 +65,8 @@ class CC_EXPORT Renderer { virtual void DoNoOp() {} // Puts backbuffer onscreen. - virtual void SwapBuffers(const ui::LatencyInfo& latency_info) = 0; + virtual void SwapBuffers() = 0; + virtual void ReceiveSwapBuffersAck(const CompositorFrameAck& ack) {} virtual void GetFramebufferPixels(void* pixels, gfx::Rect rect) = 0; diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc index d6c598a..87bc129 100644 --- a/cc/output/software_renderer.cc +++ b/cc/output/software_renderer.cc @@ -56,7 +56,6 @@ SoftwareRenderer::SoftwareRenderer(RendererClient* client, : DirectRenderer(client, output_surface, resource_provider), visible_(true), is_scissor_enabled_(false), - is_viewport_changed_(true), output_device_(output_surface->software_device()), current_canvas_(NULL) { if (resource_provider_) { @@ -68,9 +67,6 @@ SoftwareRenderer::SoftwareRenderer(RendererClient* client, // The updater can access bitmaps while the SoftwareRenderer is using them. capabilities_.allow_partial_texture_updates = true; capabilities_.using_partial_swap = true; - if (Settings().compositor_frame_message && client_->HasImplThread()) - capabilities_.using_swap_complete_callback = true; - compositor_frame_.software_frame_data.reset(new SoftwareFrameData()); } SoftwareRenderer::~SoftwareRenderer() {} @@ -79,16 +75,8 @@ const RendererCapabilities& SoftwareRenderer::Capabilities() const { return capabilities_; } -void SoftwareRenderer::ViewportChanged() { - is_viewport_changed_ = true; -} - void SoftwareRenderer::BeginDrawingFrame(DrawingFrame* frame) { TRACE_EVENT0("cc", "SoftwareRenderer::BeginDrawingFrame"); - if (is_viewport_changed_) { - is_viewport_changed_ = false; - output_device_->Resize(client_->DeviceViewport().size()); - } root_canvas_ = output_device_->BeginPaint( gfx::ToEnclosingRect(frame->root_damage_rect)); } @@ -98,21 +86,19 @@ void SoftwareRenderer::FinishDrawingFrame(DrawingFrame* frame) { current_framebuffer_lock_.reset(); current_canvas_ = NULL; root_canvas_ = NULL; - if (Settings().compositor_frame_message) { - compositor_frame_.metadata = client_->MakeCompositorFrameMetadata(); - output_device_->EndPaint(compositor_frame_.software_frame_data.get()); - } else { - output_device_->EndPaint(NULL); - } + + current_frame_data_.reset(new SoftwareFrameData); + output_device_->EndPaint(current_frame_data_.get()); } -void SoftwareRenderer::SwapBuffers(const ui::LatencyInfo& latency_info) { - if (Settings().compositor_frame_message) - output_surface_->SendFrameToParentCompositor(&compositor_frame_); +void SoftwareRenderer::SwapBuffers() { + CompositorFrame compositor_frame; + compositor_frame.metadata = client_->MakeCompositorFrameMetadata(); + compositor_frame.software_frame_data = current_frame_data_.Pass(); + output_surface_->SwapBuffers(&compositor_frame); } -void SoftwareRenderer::ReceiveCompositorFrameAck( - const CompositorFrameAck& ack) { +void SoftwareRenderer::ReceiveSwapBuffersAck(const CompositorFrameAck& ack) { output_device_->ReclaimSoftwareFrame(ack.last_software_frame_id); } diff --git a/cc/output/software_renderer.h b/cc/output/software_renderer.h index 8eb9c0e..079ee1e 100644 --- a/cc/output/software_renderer.h +++ b/cc/output/software_renderer.h @@ -33,16 +33,15 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer { virtual ~SoftwareRenderer(); virtual const RendererCapabilities& Capabilities() const OVERRIDE; - virtual void ViewportChanged() OVERRIDE; virtual void Finish() OVERRIDE; - virtual void SwapBuffers(const ui::LatencyInfo& latency_info) OVERRIDE; + virtual void SwapBuffers() OVERRIDE; virtual void GetFramebufferPixels(void* pixels, gfx::Rect rect) OVERRIDE; virtual void SetVisible(bool visible) OVERRIDE; virtual void SendManagedMemoryStats( size_t bytes_visible, size_t bytes_visible_and_nearby, size_t bytes_allocated) OVERRIDE {} - virtual void ReceiveCompositorFrameAck( + virtual void ReceiveSwapBuffersAck( const CompositorFrameAck& ack) OVERRIDE; protected: @@ -92,7 +91,6 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer { RendererCapabilities capabilities_; bool visible_; bool is_scissor_enabled_; - bool is_viewport_changed_; gfx::Rect scissor_rect_; SoftwareOutputDevice* output_device_; @@ -101,7 +99,7 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer { SkPaint current_paint_; scoped_ptr<ResourceProvider::ScopedWriteLockSoftware> current_framebuffer_lock_; - CompositorFrame compositor_frame_; + scoped_ptr<SoftwareFrameData> current_frame_data_; DISALLOW_COPY_AND_ASSIGN(SoftwareRenderer); }; diff --git a/cc/scheduler/frame_rate_controller.cc b/cc/scheduler/frame_rate_controller.cc index bcb12d2..b4f1272 100644 --- a/cc/scheduler/frame_rate_controller.cc +++ b/cc/scheduler/frame_rate_controller.cc @@ -37,7 +37,6 @@ FrameRateController::FrameRateController(scoped_refptr<TimeSource> timer) max_frames_pending_(0), time_source_(timer), active_(false), - swap_buffers_complete_supported_(true), is_time_source_throttling_(true), weak_factory_(this), thread_(NULL) { @@ -51,7 +50,6 @@ FrameRateController::FrameRateController(Thread* thread) num_frames_pending_(0), max_frames_pending_(0), active_(false), - swap_buffers_complete_supported_(true), is_time_source_throttling_(false), weak_factory_(this), thread_(thread) {} @@ -88,14 +86,6 @@ void FrameRateController::SetTimebaseAndInterval(base::TimeTicks timebase, time_source_->SetTimebaseAndInterval(timebase, interval); } -bool FrameRateController::swap_buffers_complete_supported() const { - return swap_buffers_complete_supported_; -} - -void FrameRateController::SetSwapBuffersCompleteSupported(bool supported) { - swap_buffers_complete_supported_ = supported; -} - void FrameRateController::OnTimerTick() { DCHECK(active_); @@ -107,8 +97,7 @@ void FrameRateController::OnTimerTick() { if (client_) client_->BeginFrame(throttled); - if (swap_buffers_complete_supported_ && !is_time_source_throttling_ && - !throttled) + if (!is_time_source_throttling_ && !throttled) PostManualTick(); } @@ -122,15 +111,10 @@ void FrameRateController::PostManualTick() { void FrameRateController::ManualTick() { OnTimerTick(); } void FrameRateController::DidSwapBuffers() { - if (swap_buffers_complete_supported_) - num_frames_pending_++; - else if (!is_time_source_throttling_) - PostManualTick(); + num_frames_pending_++; } void FrameRateController::DidSwapBuffersComplete() { - DCHECK(swap_buffers_complete_supported_); - DCHECK_GT(num_frames_pending_, 0); num_frames_pending_--; if (!is_time_source_throttling_) diff --git a/cc/scheduler/frame_rate_controller.h b/cc/scheduler/frame_rate_controller.h index 339578a..070c26a 100644 --- a/cc/scheduler/frame_rate_controller.h +++ b/cc/scheduler/frame_rate_controller.h @@ -63,8 +63,6 @@ class CC_EXPORT FrameRateController { void SetTimebaseAndInterval(base::TimeTicks timebase, base::TimeDelta interval); - bool swap_buffers_complete_supported() const; - void SetSwapBuffersCompleteSupported(bool supported); protected: friend class FrameRateControllerTimeSourceAdapter; @@ -79,7 +77,6 @@ class CC_EXPORT FrameRateController { scoped_refptr<TimeSource> time_source_; scoped_ptr<FrameRateControllerTimeSourceAdapter> time_source_client_adapter_; bool active_; - bool swap_buffers_complete_supported_; // Members for unthrottled frame-rate. bool is_time_source_throttling_; diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc index e34e6d5..d308b0d 100644 --- a/cc/scheduler/scheduler.cc +++ b/cc/scheduler/scheduler.cc @@ -100,14 +100,6 @@ int Scheduler::NumFramesPendingForTesting() const { return frame_rate_controller_->NumFramesPendingForTesting(); } -bool Scheduler::swap_buffers_complete_supported() const { - return frame_rate_controller_->swap_buffers_complete_supported(); -} - -void Scheduler::SetSwapBuffersCompleteSupported(bool supported) { - frame_rate_controller_->SetSwapBuffersCompleteSupported(supported); -} - void Scheduler::DidSwapBuffersComplete() { TRACE_EVENT0("cc", "Scheduler::DidSwapBuffersComplete"); frame_rate_controller_->DidSwapBuffersComplete(); @@ -178,18 +170,20 @@ void Scheduler::ProcessScheduledActions() { client_->ScheduledActionActivatePendingTreeIfNeeded(); break; case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE: { + frame_rate_controller_->DidSwapBuffers(); ScheduledActionDrawAndSwapResult result = client_->ScheduledActionDrawAndSwapIfPossible(); state_machine_.DidDrawIfPossibleCompleted(result.did_draw); - if (result.did_swap) - frame_rate_controller_->DidSwapBuffers(); + if (!result.did_swap) + frame_rate_controller_->DidSwapBuffersComplete(); break; } case SchedulerStateMachine::ACTION_DRAW_FORCED: { + frame_rate_controller_->DidSwapBuffers(); ScheduledActionDrawAndSwapResult result = client_->ScheduledActionDrawAndSwapForced(); - if (result.did_swap) - frame_rate_controller_->DidSwapBuffers(); + if (!result.did_swap) + frame_rate_controller_->DidSwapBuffersComplete(); break; } case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h index 5bdb186..6ecd889 100644 --- a/cc/scheduler/scheduler.h +++ b/cc/scheduler/scheduler.h @@ -90,8 +90,6 @@ class CC_EXPORT Scheduler : FrameRateControllerClient { int MaxFramesPending() const; int NumFramesPendingForTesting() const; - bool swap_buffers_complete_supported() const; - void SetSwapBuffersCompleteSupported(bool supported); void DidSwapBuffersComplete(); void DidLoseOutputSurface(); diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc index d393ba0..c3f3e1a 100644 --- a/cc/test/fake_output_surface.cc +++ b/cc/test/fake_output_surface.cc @@ -12,44 +12,55 @@ namespace cc { FakeOutputSurface::FakeOutputSurface( - scoped_ptr<WebKit::WebGraphicsContext3D> context3d, bool has_parent) + scoped_ptr<WebKit::WebGraphicsContext3D> context3d, + bool delegated_rendering) : OutputSurface(context3d.Pass()), num_sent_frames_(0), needs_begin_frame_(false), - forced_draw_to_software_device_(false), - weak_ptr_factory_(this) { - capabilities_.has_parent_compositor = has_parent; + forced_draw_to_software_device_(false) { + if (delegated_rendering) { + capabilities_.delegated_rendering = true; + capabilities_.max_frames_pending = 1; + } } FakeOutputSurface::FakeOutputSurface( - scoped_ptr<SoftwareOutputDevice> software_device, bool has_parent) + scoped_ptr<SoftwareOutputDevice> software_device, bool delegated_rendering) : OutputSurface(software_device.Pass()), num_sent_frames_(0), - forced_draw_to_software_device_(false), - weak_ptr_factory_(this) { - capabilities_.has_parent_compositor = has_parent; + forced_draw_to_software_device_(false) { + if (delegated_rendering) { + capabilities_.delegated_rendering = true; + capabilities_.max_frames_pending = 1; + } } FakeOutputSurface::FakeOutputSurface( scoped_ptr<WebKit::WebGraphicsContext3D> context3d, scoped_ptr<SoftwareOutputDevice> software_device, - bool has_parent) + bool delegated_rendering) : OutputSurface(context3d.Pass(), software_device.Pass()), num_sent_frames_(0), - forced_draw_to_software_device_(false), - weak_ptr_factory_(this) { - capabilities_.has_parent_compositor = has_parent; + forced_draw_to_software_device_(false) { + if (delegated_rendering) { + capabilities_.delegated_rendering = true; + capabilities_.max_frames_pending = 1; + } } FakeOutputSurface::~FakeOutputSurface() {} -void FakeOutputSurface::SendFrameToParentCompositor( - CompositorFrame* frame) { - frame->AssignTo(&last_sent_frame_); - ++num_sent_frames_; - base::MessageLoop::current()->PostTask( - FROM_HERE, base::Bind(&FakeOutputSurface::SendFrameAck, - weak_ptr_factory_.GetWeakPtr())); +void FakeOutputSurface::SwapBuffers(CompositorFrame* frame) { + if (frame->software_frame_data || frame->delegated_frame_data || + !context3d()) { + frame->AssignTo(&last_sent_frame_); + ++num_sent_frames_; + PostSwapBuffersComplete(); + } else { + OutputSurface::SwapBuffers(frame); + frame->AssignTo(&last_sent_frame_); + ++num_sent_frames_; + } } void FakeOutputSurface::SetNeedsBeginFrame(bool enable) { @@ -64,9 +75,4 @@ bool FakeOutputSurface::ForcedDrawToSoftwareDevice() const { return forced_draw_to_software_device_; } -void FakeOutputSurface::SendFrameAck() { - CompositorFrameAck ack; - client_->OnSendFrameToParentCompositorAck(ack); -} - } // namespace cc diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h index 7460f93..d54ffd3 100644 --- a/cc/test/fake_output_surface.h +++ b/cc/test/fake_output_surface.h @@ -5,7 +5,6 @@ #ifndef CC_TEST_FAKE_OUTPUT_SURFACE_H_ #define CC_TEST_FAKE_OUTPUT_SURFACE_H_ -#include "base/memory/weak_ptr.h" #include "base/time.h" #include "cc/output/compositor_frame.h" #include "cc/output/output_surface.h" @@ -66,11 +65,11 @@ class FakeOutputSurface : public OutputSurface { return result.Pass(); } - virtual void SendFrameToParentCompositor(CompositorFrame* frame) OVERRIDE; - CompositorFrame& last_sent_frame() { return last_sent_frame_; } size_t num_sent_frames() { return num_sent_frames_; } + virtual void SwapBuffers(CompositorFrame* frame) OVERRIDE; + virtual void SetNeedsBeginFrame(bool enable) OVERRIDE; bool needs_begin_frame() const { return needs_begin_frame_; @@ -85,24 +84,21 @@ class FakeOutputSurface : public OutputSurface { protected: FakeOutputSurface( scoped_ptr<WebKit::WebGraphicsContext3D> context3d, - bool has_parent); + bool delegated_rendering); FakeOutputSurface( scoped_ptr<SoftwareOutputDevice> software_device, - bool has_parent); + bool delegated_rendering); FakeOutputSurface( scoped_ptr<WebKit::WebGraphicsContext3D> context3d, scoped_ptr<SoftwareOutputDevice> software_device, - bool has_parent); - - void SendFrameAck(); + bool delegated_rendering); CompositorFrame last_sent_frame_; size_t num_sent_frames_; bool needs_begin_frame_; bool forced_draw_to_software_device_; - base::WeakPtrFactory<FakeOutputSurface> weak_ptr_factory_; }; static inline scoped_ptr<cc::OutputSurface> CreateFakeOutputSurface() { diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 4ae5248..477a4ee 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc @@ -104,8 +104,8 @@ class LayerTreeHostImplForTesting : public LayerTreeHostImpl { return result; } - virtual void OnSwapBuffersComplete() OVERRIDE { - LayerTreeHostImpl::OnSwapBuffersComplete(); + virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE { + LayerTreeHostImpl::OnSwapBuffersComplete(ack); test_hooks_->SwapBuffersCompleteOnThread(this); } diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 999a7c6..5e19eb3 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc @@ -48,7 +48,6 @@ RendererCapabilities::RendererCapabilities() : best_texture_format(0), using_partial_swap(false), using_set_visibility(false), - using_swap_complete_callback(false), using_gpu_memory_manager(false), using_egl_image(false), allow_partial_texture_updates(false), diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index 35a97c7..28beb1f 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h @@ -74,7 +74,6 @@ struct CC_EXPORT RendererCapabilities { unsigned best_texture_format; bool using_partial_swap; bool using_set_visibility; - bool using_swap_complete_callback; bool using_gpu_memory_manager; bool using_egl_image; bool allow_partial_texture_updates; diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 492df4d..ec59dae 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -933,8 +933,6 @@ bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame, if (!CalculateRenderPasses(frame)) return false; - frame->latency_info = active_tree_->GetLatencyInfo(); - // If we return true, then we expect DrawLayers() to be called before this // function is called again. return true; @@ -1068,17 +1066,14 @@ void LayerTreeHostImpl::BeginFrame(base::TimeTicks frame_time) { client_->BeginFrameOnImplThread(frame_time); } -void LayerTreeHostImpl::OnSendFrameToParentCompositorAck( - const CompositorFrameAck& ack) { - if (!renderer_) - return; - +void LayerTreeHostImpl::OnSwapBuffersComplete( + const CompositorFrameAck* ack) { // TODO(piman): We may need to do some validation on this ack before // processing it. - renderer_->ReceiveCompositorFrameAck(ack); + if (ack && renderer_) + renderer_->ReceiveSwapBuffersAck(*ack); - // When using compositor frame data, the ack doubles as a swap complete ack. - OnSwapBuffersComplete(); + client_->OnSwapBuffersCompleteOnImplThread(); } void LayerTreeHostImpl::OnCanDrawStateChangedForTree() { @@ -1230,7 +1225,7 @@ const RendererCapabilities& LayerTreeHostImpl::GetRendererCapabilities() const { bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) { if (frame.has_no_damage) return false; - renderer_->SwapBuffers(frame.latency_info); + renderer_->SwapBuffers(); active_tree_->ClearLatencyInfo(); return true; } @@ -1273,10 +1268,6 @@ void LayerTreeHostImpl::DidLoseOutputSurface() { client_->DidLoseOutputSurfaceOnImplThread(); } -void LayerTreeHostImpl::OnSwapBuffersComplete() { - client_->OnSwapBuffersCompleteOnImplThread(); -} - void LayerTreeHostImpl::Readback(void* pixels, gfx::Rect rect_in_device_viewport) { DCHECK(renderer_); @@ -1483,7 +1474,7 @@ bool LayerTreeHostImpl::DoInitializeRenderer( if (!resource_provider) return false; - if (output_surface->capabilities().has_parent_compositor) { + if (output_surface->capabilities().delegated_rendering) { renderer_ = DelegatingRenderer::Create(this, output_surface.get(), resource_provider.get()); } else if (output_surface->context3d()) { diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 5bfbcfd..e05e45b 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -26,7 +26,6 @@ #include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkPicture.h" -#include "ui/base/latency_info.h" #include "ui/gfx/rect.h" namespace cc { @@ -146,7 +145,6 @@ class CC_EXPORT LayerTreeHostImpl LayerImplList will_draw_layers; bool contains_incomplete_tile; bool has_no_damage; - ui::LatencyInfo latency_info; // RenderPassSink implementation. virtual void AppendRenderPass(scoped_ptr<RenderPass> render_pass) OVERRIDE; @@ -186,7 +184,7 @@ class CC_EXPORT LayerTreeHostImpl virtual const LayerTreeSettings& Settings() const OVERRIDE; public: virtual void DidLoseOutputSurface() OVERRIDE; - virtual void OnSwapBuffersComplete() OVERRIDE; + virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE; virtual void SetFullRootLayerDamage() OVERRIDE; virtual void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy) OVERRIDE; @@ -210,8 +208,6 @@ class CC_EXPORT LayerTreeHostImpl base::TimeDelta interval) OVERRIDE; virtual void BeginFrame(base::TimeTicks frame_time) OVERRIDE; - virtual void OnSendFrameToParentCompositorAck(const CompositorFrameAck& ack) - OVERRIDE; virtual void SetExternalDrawConstraints(const gfx::Transform& transform, gfx::Rect viewport) OVERRIDE; diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 2518fa3..097244c 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -74,12 +74,9 @@ class LayerTreeHostImplTest : public testing::Test, media::InitializeMediaLibraryForTesting(); } - virtual void OverrideSettings(LayerTreeSettings* settings) {} - virtual void SetUp() OVERRIDE { LayerTreeSettings settings; settings.minimum_occlusion_tracking_size = gfx::Size(); - OverrideSettings(&settings); host_impl_ = LayerTreeHostImpl::Create(settings, this, @@ -5748,9 +5745,6 @@ class CompositorFrameMetadataTest : public LayerTreeHostImplTest { CompositorFrameMetadataTest() : swap_buffers_complete_(0) {} - virtual void OverrideSettings(LayerTreeSettings* settings) OVERRIDE { - settings->compositor_frame_message = true; - } virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE { swap_buffers_complete_++; } @@ -5767,7 +5761,7 @@ TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) { host_impl_->DidDrawAllLayers(frame); } CompositorFrameAck ack; - host_impl_->OnSendFrameToParentCompositorAck(ack); + host_impl_->OnSwapBuffersComplete(&ack); EXPECT_EQ(swap_buffers_complete_, 1); } diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc index 21e876f..b4cc8d0 100644 --- a/cc/trees/layer_tree_settings.cc +++ b/cc/trees/layer_tree_settings.cc @@ -13,8 +13,7 @@ namespace cc { LayerTreeSettings::LayerTreeSettings() - : compositor_frame_message(false), - impl_side_painting(false), + : impl_side_painting(false), throttle_frame_production(true), begin_frame_scheduling_enabled(false), using_synchronous_renderer_compositor(false), diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index 2f33f77..7f8455f 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h @@ -20,7 +20,6 @@ class CC_EXPORT LayerTreeSettings { LayerTreeSettings(); ~LayerTreeSettings(); - bool compositor_frame_message; bool impl_side_painting; bool throttle_frame_production; bool begin_frame_scheduling_enabled; diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index 5f92c61..98512468 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -1157,8 +1157,6 @@ void ThreadProxy::InitializeOutputSurfaceOnImplThread( if (*success) { *capabilities = layer_tree_host_impl_->GetRendererCapabilities(); - scheduler_on_impl_thread_->SetSwapBuffersCompleteSupported( - capabilities->using_swap_complete_callback); OutputSurface* output_surface_ptr = layer_tree_host_impl_->output_surface(); DCHECK(output_surface_ptr); @@ -1166,8 +1164,6 @@ void ThreadProxy::InitializeOutputSurfaceOnImplThread( output_surface_ptr->capabilities().max_frames_pending; if (max_frames_pending <= 0) max_frames_pending = FrameRateController::DEFAULT_MAX_FRAMES_PENDING; - if (output_surface_ptr->capabilities().has_parent_compositor) - max_frames_pending = 1; scheduler_on_impl_thread_->SetMaxFramesPending(max_frames_pending); @@ -1189,9 +1185,6 @@ void ThreadProxy::DidTryInitializeRendererOnImplThread( offscreen_context_provider->BindToCurrentThread(); if (success) { - DCHECK_EQ(layer_tree_host_impl_->GetRendererCapabilities() - .using_swap_complete_callback, - scheduler_on_impl_thread_->swap_buffers_complete_supported()); if (layer_tree_host_impl_->resource_provider()) { layer_tree_host_impl_->resource_provider()-> set_offscreen_context_provider(offscreen_context_provider); diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.cc b/content/browser/android/in_process/synchronous_compositor_output_surface.cc index 8d25082..7613168 100644 --- a/content/browser/android/in_process/synchronous_compositor_output_surface.cc +++ b/content/browser/android/in_process/synchronous_compositor_output_surface.cc @@ -59,13 +59,15 @@ class SynchronousCompositorOutputSurface::SoftwareDevice // Intentional no-op: canvas size is controlled by the embedder. } virtual SkCanvas* BeginPaint(gfx::Rect damage_rect) OVERRIDE { - DCHECK(surface_->current_sw_canvas_); - if (surface_->current_sw_canvas_) - return surface_->current_sw_canvas_; - return &null_canvas_; + if (!surface_->current_sw_canvas_) { + NOTREACHED() << "BeginPaint with no canvas set"; + return &null_canvas_; + } + LOG_IF(WARNING, surface_->did_swap_buffer_) + << "Mutliple calls to BeginPaint per frame"; + return surface_->current_sw_canvas_; } virtual void EndPaint(cc::SoftwareFrameData* frame_data) OVERRIDE { - surface_->current_sw_canvas_ = NULL; } virtual void CopyToBitmap(gfx::Rect rect, SkBitmap* output) OVERRIDE { NOTIMPLEMENTED(); @@ -119,12 +121,6 @@ void SynchronousCompositorOutputSurface::Reshape( // Intentional no-op: surface size is controlled by the embedder. } -void SynchronousCompositorOutputSurface::SendFrameToParentCompositor( - cc::CompositorFrame* frame) { - NOTREACHED(); - // TODO(joth): Route page scale to the client, see http://crbug.com/237006 -} - void SynchronousCompositorOutputSurface::SetNeedsBeginFrame( bool enable) { DCHECK(CalledOnValidThread()); @@ -135,8 +131,12 @@ void SynchronousCompositorOutputSurface::SetNeedsBeginFrame( } void SynchronousCompositorOutputSurface::SwapBuffers( - const ui::LatencyInfo& info) { - context3d()->shallowFlushCHROMIUM(); + cc::CompositorFrame* frame) { + if (!ForcedDrawToSoftwareDevice()) { + DCHECK(context3d()); + context3d()->shallowFlushCHROMIUM(); + } + // TODO(joth): Route page scale to the client, see http://crbug.com/237006 did_swap_buffer_ = true; } @@ -174,8 +174,6 @@ bool SynchronousCompositorOutputSurface::DemandDrawHw( if (current_context) current_context->ReleaseCurrent(NULL); - did_swap_buffer_ = false; - gfx::Transform adjusted_transform = transform; AdjustTransformForClip(&adjusted_transform, clip); surface_size_ = surface_size; @@ -207,16 +205,19 @@ bool SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) { InvokeComposite(clip.size()); - bool finished_draw = current_sw_canvas_ == NULL; current_sw_canvas_ = NULL; - return finished_draw; + return did_swap_buffer_; } void SynchronousCompositorOutputSurface::InvokeComposite( gfx::Size damage_size) { + did_swap_buffer_ = false; client_->SetNeedsRedrawRect(gfx::Rect(damage_size)); if (needs_begin_frame_) client_->BeginFrame(base::TimeTicks::Now()); + + if (did_swap_buffer_) + client_->OnSwapBuffersComplete(NULL); } // Not using base::NonThreadSafe as we want to enforce a more exacting threading diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.h b/content/browser/android/in_process/synchronous_compositor_output_surface.h index a2434df..dabed4b 100644 --- a/content/browser/android/in_process/synchronous_compositor_output_surface.h +++ b/content/browser/android/in_process/synchronous_compositor_output_surface.h @@ -54,9 +54,8 @@ class SynchronousCompositorOutputSurface virtual bool ForcedDrawToSoftwareDevice() const OVERRIDE; virtual bool BindToClient(cc::OutputSurfaceClient* surface_client) OVERRIDE; virtual void Reshape(gfx::Size size, float scale_factor) OVERRIDE; - virtual void SendFrameToParentCompositor(cc::CompositorFrame* frame) OVERRIDE; virtual void SetNeedsBeginFrame(bool enable) OVERRIDE; - virtual void SwapBuffers(const ui::LatencyInfo& info) OVERRIDE; + virtual void SwapBuffers(cc::CompositorFrame* frame) OVERRIDE; // Partial SynchronousCompositor API implementation. bool InitializeHwDraw(); diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index ec1ae64..c80d73b9 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc @@ -48,9 +48,10 @@ class DirectOutputSurface : public cc::OutputSurface { DirectOutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D> context3d) : cc::OutputSurface(context3d.Pass()) {} - virtual void Reshape(gfx::Size size, float scale_factor) OVERRIDE {} - virtual void PostSubBuffer(gfx::Rect rect, const ui::LatencyInfo&) OVERRIDE {} - virtual void SwapBuffers(const ui::LatencyInfo&) OVERRIDE { + virtual void Reshape(gfx::Size size, float scale_factor) OVERRIDE { + surface_size_ = size; + } + virtual void SwapBuffers(cc::CompositorFrame*) OVERRIDE { context3d()->shallowFlushCHROMIUM(); } }; diff --git a/content/browser/renderer_host/image_transport_factory.cc b/content/browser/renderer_host/image_transport_factory.cc index 412d7c5..627d8cd 100644 --- a/content/browser/renderer_host/image_transport_factory.cc +++ b/content/browser/renderer_host/image_transport_factory.cc @@ -14,6 +14,7 @@ #include "base/observer_list.h" #include "base/strings/string_number_conversions.h" #include "base/threading/non_thread_safe.h" +#include "cc/output/compositor_frame.h" #include "cc/output/output_surface.h" #include "cc/output/output_surface_client.h" #include "content/browser/gpu/browser_gpu_channel_host_factory.h" @@ -539,35 +540,25 @@ class BrowserCompositorOutputSurface reflector_->OnReshape(size); } - virtual void SwapBuffers(const ui::LatencyInfo& latency_info) OVERRIDE { - WebGraphicsContext3DCommandBufferImpl* command_buffer = - static_cast<WebGraphicsContext3DCommandBufferImpl*>(context3d()); - CommandBufferProxyImpl* command_buffer_proxy = - command_buffer->GetCommandBufferProxy(); - DCHECK(command_buffer_proxy); - context3d()->shallowFlushCHROMIUM(); - command_buffer_proxy->SetLatencyInfo(latency_info); + virtual void SwapBuffers(cc::CompositorFrame* frame) OVERRIDE { + DCHECK(frame->gl_frame_data); - if (reflector_.get()) - reflector_->OnSwapBuffers(); - - OutputSurface::SwapBuffers(latency_info); - } - - virtual void PostSubBuffer(gfx::Rect rect, - const ui::LatencyInfo& latency_info) OVERRIDE { WebGraphicsContext3DCommandBufferImpl* command_buffer = static_cast<WebGraphicsContext3DCommandBufferImpl*>(context3d()); CommandBufferProxyImpl* command_buffer_proxy = command_buffer->GetCommandBufferProxy(); DCHECK(command_buffer_proxy); context3d()->shallowFlushCHROMIUM(); - command_buffer_proxy->SetLatencyInfo(latency_info); + command_buffer_proxy->SetLatencyInfo(frame->metadata.latency_info); - if (reflector_.get()) - reflector_->OnPostSubBuffer(rect); + if (reflector_.get()) { + if (frame->gl_frame_data->partial_swap_allowed) + reflector_->OnPostSubBuffer(frame->gl_frame_data->sub_buffer_rect); + else + reflector_->OnSwapBuffers(); + } - OutputSurface::PostSubBuffer(rect, latency_info); + OutputSurface::SwapBuffers(frame); } void SetReflector(ReflectorImpl* reflector) { diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 1f1a0d7..8c95171 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -107,6 +107,8 @@ 'renderer/gpu/compositor_output_surface.h', 'renderer/gpu/compositor_software_output_device.cc', 'renderer/gpu/compositor_software_output_device.h', + 'renderer/gpu/delegated_compositor_output_surface.cc', + 'renderer/gpu/delegated_compositor_output_surface.h', 'renderer/gpu/input_event_filter.cc', 'renderer/gpu/input_event_filter.h', 'renderer/gpu/input_handler_proxy.cc', diff --git a/content/renderer/gpu/compositor_output_surface.cc b/content/renderer/gpu/compositor_output_surface.cc index d49c7b8..c570f51 100644 --- a/content/renderer/gpu/compositor_output_surface.cc +++ b/content/renderer/gpu/compositor_output_surface.cc @@ -50,18 +50,17 @@ IPC::ForwardingMessageFilter* CompositorOutputSurface::CreateFilter( CompositorOutputSurface::CompositorOutputSurface( int32 routing_id, WebGraphicsContext3DCommandBufferImpl* context3D, - cc::SoftwareOutputDevice* software_device) + cc::SoftwareOutputDevice* software_device, + bool use_swap_compositor_frame_message) : OutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D>(context3D), make_scoped_ptr(software_device)), + use_swap_compositor_frame_message_(use_swap_compositor_frame_message), output_surface_filter_( RenderThreadImpl::current()->compositor_output_surface_filter()), routing_id_(routing_id), prefers_smoothness_(false), main_thread_handle_(base::PlatformThread::CurrentHandle()) { DCHECK(output_surface_filter_.get()); - CommandLine* command_line = CommandLine::ForCurrentProcess(); - capabilities_.has_parent_compositor = command_line->HasSwitch( - switches::kEnableDelegatedRenderer); DetachFromThread(); message_sender_ = RenderThreadImpl::current()->sync_message_filter(); DCHECK(message_sender_.get()); @@ -93,34 +92,23 @@ bool CompositorOutputSurface::BindToClient( return true; } -void CompositorOutputSurface::SendFrameToParentCompositor( - cc::CompositorFrame* frame) { - DCHECK(CalledOnValidThread()); - Send(new ViewHostMsg_SwapCompositorFrame(routing_id_, *frame)); -} +void CompositorOutputSurface::SwapBuffers(cc::CompositorFrame* frame) { + if (use_swap_compositor_frame_message_) { + Send(new ViewHostMsg_SwapCompositorFrame(routing_id_, *frame)); + return; + } -void CompositorOutputSurface::SwapBuffers( - const ui::LatencyInfo& latency_info) { - WebGraphicsContext3DCommandBufferImpl* command_buffer = - static_cast<WebGraphicsContext3DCommandBufferImpl*>(context3d()); - CommandBufferProxyImpl* command_buffer_proxy = - command_buffer->GetCommandBufferProxy(); - DCHECK(command_buffer_proxy); - context3d()->shallowFlushCHROMIUM(); - command_buffer_proxy->SetLatencyInfo(latency_info); - OutputSurface::SwapBuffers(latency_info); -} + if (frame->gl_frame_data) { + WebGraphicsContext3DCommandBufferImpl* command_buffer = + static_cast<WebGraphicsContext3DCommandBufferImpl*>(context3d()); + CommandBufferProxyImpl* command_buffer_proxy = + command_buffer->GetCommandBufferProxy(); + DCHECK(command_buffer_proxy); + context3d()->shallowFlushCHROMIUM(); + command_buffer_proxy->SetLatencyInfo(frame->metadata.latency_info); + } -void CompositorOutputSurface::PostSubBuffer( - gfx::Rect rect, const ui::LatencyInfo& latency_info) { - WebGraphicsContext3DCommandBufferImpl* command_buffer = - static_cast<WebGraphicsContext3DCommandBufferImpl*>(context3d()); - CommandBufferProxyImpl* command_buffer_proxy = - command_buffer->GetCommandBufferProxy(); - DCHECK(command_buffer_proxy); - context3d()->shallowFlushCHROMIUM(); - command_buffer_proxy->SetLatencyInfo(latency_info); - OutputSurface::PostSubBuffer(rect, latency_info); + OutputSurface::SwapBuffers(frame); } void CompositorOutputSurface::OnMessageReceived(const IPC::Message& message) { @@ -155,7 +143,7 @@ void CompositorOutputSurface::OnBeginFrame(base::TimeTicks frame_time) { #endif // defined(OS_ANDROID) void CompositorOutputSurface::OnSwapAck(const cc::CompositorFrameAck& ack) { - client_->OnSendFrameToParentCompositorAck(ack); + client_->OnSwapBuffersComplete(&ack); } bool CompositorOutputSurface::Send(IPC::Message* message) { diff --git a/content/renderer/gpu/compositor_output_surface.h b/content/renderer/gpu/compositor_output_surface.h index 7f13852..c1f9077 100644 --- a/content/renderer/gpu/compositor_output_surface.h +++ b/content/renderer/gpu/compositor_output_surface.h @@ -44,14 +44,13 @@ class CompositorOutputSurface CompositorOutputSurface(int32 routing_id, WebGraphicsContext3DCommandBufferImpl* context3d, - cc::SoftwareOutputDevice* software); + cc::SoftwareOutputDevice* software, + bool use_swap_compositor_frame_message); virtual ~CompositorOutputSurface(); // cc::OutputSurface implementation. virtual bool BindToClient(cc::OutputSurfaceClient* client) OVERRIDE; - virtual void SendFrameToParentCompositor(cc::CompositorFrame*) OVERRIDE; - virtual void PostSubBuffer(gfx::Rect rect, const ui::LatencyInfo&) OVERRIDE; - virtual void SwapBuffers(const ui::LatencyInfo&) OVERRIDE; + virtual void SwapBuffers(cc::CompositorFrame* frame) OVERRIDE; #if defined(OS_ANDROID) virtual void SetNeedsBeginFrame(bool enable) OVERRIDE; #endif @@ -92,6 +91,8 @@ class CompositorOutputSurface #endif bool Send(IPC::Message* message); + bool use_swap_compositor_frame_message_; + scoped_refptr<IPC::ForwardingMessageFilter> output_surface_filter_; scoped_refptr<CompositorOutputSurfaceProxy> output_surface_proxy_; scoped_refptr<IPC::SyncMessageFilter> message_sender_; diff --git a/content/renderer/gpu/delegated_compositor_output_surface.cc b/content/renderer/gpu/delegated_compositor_output_surface.cc new file mode 100644 index 0000000..f6949eb --- /dev/null +++ b/content/renderer/gpu/delegated_compositor_output_surface.cc @@ -0,0 +1,18 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/gpu/delegated_compositor_output_surface.h" + +namespace content { + +DelegatedCompositorOutputSurface::DelegatedCompositorOutputSurface( + int32 routing_id, + WebGraphicsContext3DCommandBufferImpl* context3d, + cc::SoftwareOutputDevice* software) + : CompositorOutputSurface(routing_id, context3d, software, true) { + capabilities_.delegated_rendering = true; + capabilities_.max_frames_pending = 1; +} + +} // namespace content diff --git a/content/renderer/gpu/delegated_compositor_output_surface.h b/content/renderer/gpu/delegated_compositor_output_surface.h new file mode 100644 index 0000000..774c4c9 --- /dev/null +++ b/content/renderer/gpu/delegated_compositor_output_surface.h @@ -0,0 +1,23 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_GPU_DELEGATED_COMPOSITOR_OUTPUT_SURFACE_H_ +#define CONTENT_RENDERER_GPU_DELEGATED_COMPOSITOR_OUTPUT_SURFACE_H_ + +#include "content/renderer/gpu/compositor_output_surface.h" + +namespace content { + +class DelegatedCompositorOutputSurface : public CompositorOutputSurface { + public: + DelegatedCompositorOutputSurface( + int32 routing_id, + WebGraphicsContext3DCommandBufferImpl* context3d, + cc::SoftwareOutputDevice* software); + virtual ~DelegatedCompositorOutputSurface() {} +}; + +} // namespace content + +#endif // CONTENT_RENDERER_GPU_DELEGATED_COMPOSITOR_OUTPUT_SURFACE_H_ diff --git a/content/renderer/gpu/mailbox_output_surface.cc b/content/renderer/gpu/mailbox_output_surface.cc index d7b13ce..80e7ed2 100644 --- a/content/renderer/gpu/mailbox_output_surface.cc +++ b/content/renderer/gpu/mailbox_output_surface.cc @@ -22,7 +22,7 @@ MailboxOutputSurface::MailboxOutputSurface( int32 routing_id, WebGraphicsContext3DCommandBufferImpl* context3D, cc::SoftwareOutputDevice* software_device) - : CompositorOutputSurface(routing_id, context3D, software_device), + : CompositorOutputSurface(routing_id, context3D, software_device, true), fbo_(0), is_backbuffer_discarded_(false) { pending_textures_.push_back(TransferableFrame()); @@ -123,24 +123,6 @@ void MailboxOutputSurface::BindFramebuffer() { current_backing_.texture_id, 0); } -void MailboxOutputSurface::SendFrameToParentCompositor( - cc::CompositorFrame* frame) { - frame->gl_frame_data.reset(new GLFrameData()); - - DCHECK(!surface_size_.IsEmpty()); - DCHECK(surface_size_ == current_backing_.size); - DCHECK(!current_backing_.mailbox.IsZero()); - - frame->gl_frame_data->mailbox = current_backing_.mailbox; - frame->gl_frame_data->size = current_backing_.size; - context3d_->flush(); - frame->gl_frame_data->sync_point = context3d_->insertSyncPoint(); - CompositorOutputSurface::SendFrameToParentCompositor(frame); - - pending_textures_.push_back(current_backing_); - current_backing_ = TransferableFrame(); -} - void MailboxOutputSurface::OnSwapAck(const cc::CompositorFrameAck& ack) { if (!ack.gl_frame_data->mailbox.IsZero()) { DCHECK(!ack.gl_frame_data->size.IsEmpty()); @@ -179,16 +161,24 @@ void MailboxOutputSurface::OnSwapAck(const cc::CompositorFrameAck& ack) { CompositorOutputSurface::OnSwapAck(ack); } -void MailboxOutputSurface::SwapBuffers(const ui::LatencyInfo&) { -} - -void MailboxOutputSurface::PostSubBuffer(gfx::Rect rect, - const ui::LatencyInfo&) { - NOTIMPLEMENTED() +void MailboxOutputSurface::SwapBuffers(cc::CompositorFrame* frame) { + DCHECK(frame->gl_frame_data); + DCHECK(frame->gl_frame_data->sub_buffer_rect.size() == + frame->gl_frame_data->size) << "Partial swap not supported with composite-to-mailbox yet."; - // The browser only copies damage correctly for two buffers in use. - DCHECK(GetNumAcksPending() < 2); + DCHECK(!surface_size_.IsEmpty()); + DCHECK(surface_size_ == current_backing_.size); + DCHECK(frame->gl_frame_data->size == current_backing_.size); + DCHECK(!current_backing_.mailbox.IsZero()); + + frame->gl_frame_data->mailbox = current_backing_.mailbox; + context3d_->flush(); + frame->gl_frame_data->sync_point = context3d_->insertSyncPoint(); + CompositorOutputSurface::SwapBuffers(frame); + + pending_textures_.push_back(current_backing_); + current_backing_ = TransferableFrame(); } size_t MailboxOutputSurface::GetNumAcksPending() { diff --git a/content/renderer/gpu/mailbox_output_surface.h b/content/renderer/gpu/mailbox_output_surface.h index 9133c9a..0be4712 100644 --- a/content/renderer/gpu/mailbox_output_surface.h +++ b/content/renderer/gpu/mailbox_output_surface.h @@ -29,13 +29,11 @@ class MailboxOutputSurface : public CompositorOutputSurface { virtual ~MailboxOutputSurface(); // cc::OutputSurface implementation. - virtual void SendFrameToParentCompositor(cc::CompositorFrame* frame) OVERRIDE; virtual void EnsureBackbuffer() OVERRIDE; virtual void DiscardBackbuffer() OVERRIDE; virtual void Reshape(gfx::Size size, float scale_factor) OVERRIDE; virtual void BindFramebuffer() OVERRIDE; - virtual void PostSubBuffer(gfx::Rect rect, const ui::LatencyInfo&) OVERRIDE; - virtual void SwapBuffers(const ui::LatencyInfo&) OVERRIDE; + virtual void SwapBuffers(cc::CompositorFrame* frame) OVERRIDE; private: // CompositorOutputSurface overrides. diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index cda27ae..69e3778 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc @@ -149,16 +149,10 @@ scoped_ptr<RenderWidgetCompositor> RenderWidgetCompositor::Create( settings.top_controls_height = controls_height; } - settings.compositor_frame_message = - cmd->HasSwitch(cc::switches::kEnableCompositorFrameMessage) || - cmd->HasSwitch(cc::switches::kCompositeToMailbox) || - cmd->HasSwitch(switches::kEnableSoftwareCompositingGLAdapter); - if (settings.calculate_top_controls_position && - (settings.top_controls_height <= 0 || - !settings.compositor_frame_message)) { - DCHECK(false) << "Top controls repositioning enabled without valid height " - "or compositor_frame_message set."; + settings.top_controls_height <= 0) { + DCHECK(false) + << "Top controls repositioning enabled without valid height set."; settings.calculate_top_controls_position = false; } diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 724b367..8b3e621 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc @@ -26,6 +26,7 @@ #include "content/public/common/content_switches.h" #include "content/renderer/gpu/compositor_output_surface.h" #include "content/renderer/gpu/compositor_software_output_device.h" +#include "content/renderer/gpu/delegated_compositor_output_surface.h" #include "content/renderer/gpu/input_handler_manager.h" #include "content/renderer/gpu/mailbox_output_surface.h" #include "content/renderer/gpu/render_widget_compositor.h" @@ -600,7 +601,7 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface() { if (command_line.HasSwitch(switches::kEnableSoftwareCompositingGLAdapter)) { return scoped_ptr<cc::OutputSurface>( new CompositorOutputSurface(routing_id(), NULL, - new CompositorSoftwareOutputDevice())); + new CompositorSoftwareOutputDevice(), true)); } // Explicitly disable antialiasing for the compositor. As of the time of @@ -626,14 +627,18 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface() { if (!context) return scoped_ptr<cc::OutputSurface>(); - bool composite_to_mailbox = - command_line.HasSwitch(cc::switches::kCompositeToMailbox) && - !command_line.HasSwitch(switches::kEnableDelegatedRenderer); - // No swap throttling yet when compositing on the main thread. - DCHECK(!composite_to_mailbox || is_threaded_compositing_enabled_); - return scoped_ptr<cc::OutputSurface>(composite_to_mailbox ? - new MailboxOutputSurface(routing_id(), context, NULL) : - new CompositorOutputSurface(routing_id(), context, NULL)); + if (command_line.HasSwitch(switches::kEnableDelegatedRenderer)) { + DCHECK(is_threaded_compositing_enabled_); + return scoped_ptr<cc::OutputSurface>( + new DelegatedCompositorOutputSurface(routing_id(), context, NULL)); + } + if (command_line.HasSwitch(cc::switches::kCompositeToMailbox)) { + DCHECK(is_threaded_compositing_enabled_); + return scoped_ptr<cc::OutputSurface>( + new MailboxOutputSurface(routing_id(), context, NULL)); + } + return scoped_ptr<cc::OutputSurface>( + new CompositorOutputSurface(routing_id(), context, NULL, false)); } void RenderWidget::OnViewContextSwapBuffersAborted() { diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index 2a2dd03..b4a51d6 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc @@ -359,6 +359,14 @@ void CompositorLock::CancelLock() { // static void DrawWaiterForTest::Wait(Compositor* compositor) { DrawWaiterForTest waiter; + waiter.wait_for_commit_ = false; + waiter.WaitImpl(compositor); +} + +// static +void DrawWaiterForTest::WaitForCommit(Compositor* compositor) { + DrawWaiterForTest waiter; + waiter.wait_for_commit_ = true; waiter.WaitImpl(compositor); } @@ -376,6 +384,8 @@ void DrawWaiterForTest::WaitImpl(Compositor* compositor) { } void DrawWaiterForTest::OnCompositingDidCommit(Compositor* compositor) { + if (wait_for_commit_) + wait_run_loop_->Quit(); } void DrawWaiterForTest::OnCompositingStarted(Compositor* compositor, @@ -383,7 +393,8 @@ void DrawWaiterForTest::OnCompositingStarted(Compositor* compositor, } void DrawWaiterForTest::OnCompositingEnded(Compositor* compositor) { - wait_run_loop_->Quit(); + if (!wait_for_commit_) + wait_run_loop_->Quit(); } void DrawWaiterForTest::OnCompositingAborted(Compositor* compositor) { @@ -758,11 +769,6 @@ void Compositor::DidCommitAndDrawFrame() { FOR_EACH_OBSERVER(CompositorObserver, observer_list_, OnCompositingStarted(this, start_time)); - // If we're threaded without a swap complete callback, we have to - // call DidCompleteSwapBuffersManually. - if (g_compositor_thread && - !host_->GetRendererCapabilities().using_swap_complete_callback) - DidCompleteSwapBuffers(); } void Compositor::DidCompleteSwapBuffers() { diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index 8e59b7e..908dd66 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h @@ -262,6 +262,9 @@ class COMPOSITOR_EXPORT DrawWaiterForTest : public ui::CompositorObserver { // not to draw. static void Wait(Compositor* compositor); + // Waits for a commit instead of a draw. + static void WaitForCommit(Compositor* compositor); + private: DrawWaiterForTest(); virtual ~DrawWaiterForTest(); @@ -281,6 +284,8 @@ class COMPOSITOR_EXPORT DrawWaiterForTest : public ui::CompositorObserver { scoped_ptr<base::RunLoop> wait_run_loop_; + bool wait_for_commit_; + DISALLOW_COPY_AND_ASSIGN(DrawWaiterForTest); }; diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc index 10edfba..c165a25 100644 --- a/ui/compositor/layer_unittest.cc +++ b/ui/compositor/layer_unittest.cc @@ -126,6 +126,10 @@ class LayerWithRealCompositorTest : public testing::Test { ui::DrawWaiterForTest::Wait(GetCompositor()); } + void WaitForCommit() { + ui::DrawWaiterForTest::WaitForCommit(GetCompositor()); + } + // Invalidates the entire contents of the layer. void SchedulePaintForLayer(Layer* layer) { layer->SchedulePaint( @@ -254,12 +258,14 @@ class NullLayerDelegate : public LayerDelegate { class TestCompositorObserver : public CompositorObserver { public: TestCompositorObserver() - : started_(false), ended_(false), aborted_(false) {} + : committed_(false), started_(false), ended_(false), aborted_(false) {} + bool committed() const { return committed_; } bool notified() const { return started_ && ended_; } bool aborted() const { return aborted_; } void Reset() { + committed_ = false; started_ = false; ended_ = false; aborted_ = false; @@ -267,6 +273,7 @@ class TestCompositorObserver : public CompositorObserver { private: virtual void OnCompositingDidCommit(Compositor* compositor) OVERRIDE { + committed_ = true; } virtual void OnCompositingStarted(Compositor* compositor, @@ -290,6 +297,7 @@ class TestCompositorObserver : public CompositorObserver { base::TimeDelta interval) OVERRIDE { } + bool committed_; bool started_; bool ended_; bool aborted_; @@ -418,6 +426,10 @@ class LayerWithDelegateTest : public testing::Test, public CompositorDelegate { DrawWaiterForTest::Wait(compositor()); } + void WaitForCommit() { + DrawWaiterForTest::WaitForCommit(compositor()); + } + // CompositorDelegate overrides. virtual void ScheduleDraw() OVERRIDE { DCHECK(!ui::Compositor::WasInitializedWithThread()); @@ -819,11 +831,11 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_CompositorObservers) { DrawTree(l1.get()); EXPECT_TRUE(observer.notified()); - // As should scheduling a draw and waiting. + // ScheduleDraw without any visible change should cause a commit. observer.Reset(); l1->ScheduleDraw(); - WaitForDraw(); - EXPECT_TRUE(observer.notified()); + WaitForCommit(); + EXPECT_TRUE(observer.committed()); // Moving, but not resizing, a layer should alert the observers. observer.Reset(); @@ -917,15 +929,15 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_ModifyHierarchy) { // WritePNGFile(bitmap, ref_img2); EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); - // l11 is already at the front, should have no effect. - l0->StackAtTop(l11.get()); + // should restore to original configuration + l0->StackAbove(l12.get(), l11.get()); DrawTree(l0.get()); ASSERT_TRUE(ReadPixels(&bitmap)); ASSERT_FALSE(bitmap.empty()); - EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); + EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); - // l11 is already at the front, should have no effect. - l0->StackAbove(l11.get(), l12.get()); + // l11 back to front + l0->StackAtTop(l11.get()); DrawTree(l0.get()); ASSERT_TRUE(ReadPixels(&bitmap)); ASSERT_FALSE(bitmap.empty()); @@ -937,6 +949,13 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_ModifyHierarchy) { ASSERT_TRUE(ReadPixels(&bitmap)); ASSERT_FALSE(bitmap.empty()); EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); + + // l11 back to front + l0->StackAbove(l11.get(), l12.get()); + DrawTree(l0.get()); + ASSERT_TRUE(ReadPixels(&bitmap)); + ASSERT_FALSE(bitmap.empty()); + EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); } // Opacity is rendered correctly. @@ -1033,18 +1052,17 @@ TEST_F(LayerWithDelegateTest, SchedulePaintFromOnPaintLayer) { SchedulePaintForLayer(root.get()); DrawTree(root.get()); child->SchedulePaint(gfx::Rect(0, 0, 20, 20)); - child_delegate.GetPaintCountAndClear(); + EXPECT_EQ(1, child_delegate.GetPaintCountAndClear()); // Set a rect so that when OnPaintLayer() is invoked SchedulePaint is invoked // again. child_delegate.SetSchedulePaintRect(gfx::Rect(10, 10, 30, 30)); - WaitForDraw(); - // |child| should have been painted once. + WaitForCommit(); EXPECT_EQ(1, child_delegate.GetPaintCountAndClear()); // Because SchedulePaint() was invoked from OnPaintLayer() |child| should // still need to be painted. - WaitForDraw(); + WaitForCommit(); EXPECT_EQ(1, child_delegate.GetPaintCountAndClear()); EXPECT_TRUE(child_delegate.last_clip_rect().Contains( gfx::Rect(10, 10, 30, 30))); @@ -1227,7 +1245,6 @@ TEST_F(LayerWithDelegateTest, SetBoundsWhenInvisible) { // Move layer. child->SetBounds(gfx::Rect(200, 200, 500, 500)); child->SetVisible(true); - WaitForDraw(); DrawTree(root.get()); EXPECT_FALSE(delegate.painted()); @@ -1239,7 +1256,6 @@ TEST_F(LayerWithDelegateTest, SetBoundsWhenInvisible) { // Resize layer. child->SetBounds(gfx::Rect(200, 200, 400, 400)); child->SetVisible(true); - WaitForDraw(); DrawTree(root.get()); EXPECT_TRUE(delegate.painted()); } |