Chromium Code Reviews| Index: cc/output/output_surface.cc |
| diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc |
| index fe2b074ee46d033f7900054ccb164dc3b3992cae..9cc4a8619cf40e482fc6389d49ae0885e1246c7f 100644 |
| --- a/cc/output/output_surface.cc |
| +++ b/cc/output/output_surface.cc |
| @@ -8,10 +8,12 @@ |
| #include <string> |
| #include <vector> |
| +#include "base/debug/trace_event.h" |
| #include "base/logging.h" |
| #include "base/string_util.h" |
| #include "base/strings/string_split.h" |
| #include "cc/output/output_surface_client.h" |
| +#include "cc/scheduler/delay_based_time_source.h" |
| #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" |
| #include "third_party/khronos/GLES2/gl2.h" |
| #include "third_party/khronos/GLES2/gl2ext.h" |
| @@ -29,7 +31,7 @@ class OutputSurfaceCallbacks |
| WebGraphicsSwapBuffersCompleteCallbackCHROMIUM, |
| public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback { |
| public: |
| - explicit OutputSurfaceCallbacks(OutputSurfaceClient* client) |
| + explicit OutputSurfaceCallbacks(OutputSurface* client) |
| : client_(client) {} |
| // WK:WGC3D::WGSwapBuffersCompleteCallbackCHROMIUM implementation. |
| @@ -39,21 +41,23 @@ class OutputSurfaceCallbacks |
| virtual void onContextLost() { client_->DidLoseOutputSurface(); } |
| private: |
| - OutputSurfaceClient* client_; |
| + OutputSurface* client_; |
| }; |
| OutputSurface::OutputSurface( |
| scoped_ptr<WebKit::WebGraphicsContext3D> context3d) |
| : client_(NULL), |
| context3d_(context3d.Pass()), |
| - has_gl_discard_backbuffer_(false) { |
| + has_gl_discard_backbuffer_(false), |
| + pending_begin_frames_(0) { |
| } |
| OutputSurface::OutputSurface( |
| scoped_ptr<cc::SoftwareOutputDevice> software_device) |
| : client_(NULL), |
| software_device_(software_device.Pass()), |
| - has_gl_discard_backbuffer_(false) { |
| + has_gl_discard_backbuffer_(false), |
| + pending_begin_frames_(0) { |
| } |
| OutputSurface::OutputSurface( |
| @@ -62,18 +66,94 @@ OutputSurface::OutputSurface( |
| : client_(NULL), |
| context3d_(context3d.Pass()), |
| software_device_(software_device.Pass()), |
| - has_gl_discard_backbuffer_(false) { |
| + has_gl_discard_backbuffer_(false), |
| + pending_begin_frames_(0) { |
| +} |
| + |
| +void OutputSurface::InitializeBeginFrameEmulation( |
| + Thread* thread, |
| + bool throttle_frame_production, |
| + base::TimeDelta interval, |
| + int max_frames_pending, |
| + bool swap_buffers_complete_supported) { |
| + DCHECK(!frame_rate_controller_); |
| + if (throttle_frame_production){ |
| + frame_rate_controller_.reset( |
| + new FrameRateController( |
| + DelayBasedTimeSource::Create(interval, thread))); |
| + } else { |
| + frame_rate_controller_.reset(new FrameRateController(thread)); |
| + } |
| + |
| + frame_rate_controller_->SetClient(this); |
| + frame_rate_controller_->SetSwapBuffersCompleteSupported( |
| + swap_buffers_complete_supported); |
| + frame_rate_controller_->SetMaxFramesPending(max_frames_pending); |
| +} |
| + |
| +void OutputSurface::OnVSyncParametersChanged(base::TimeTicks timebase, |
| + base::TimeDelta interval) { |
| + TRACE_EVENT2("cc", "OutputSurface::OnVSyncParametersChanged", |
| + "timebase", (timebase - base::TimeTicks()).InSecondsF(), |
| + "interval", interval.InSecondsF()); |
| + frame_rate_controller_->SetTimebaseAndInterval(timebase, interval); |
| +} |
| + |
| +void OutputSurface::FrameRateControllerTick(bool throttled) { |
| + if (!throttled) |
| + BeginFrame(frame_rate_controller_->LastTickTime()); |
| +} |
| + |
| +// Forwarded to OutputSurfaceClient |
| +void OutputSurface::SetNeedsRedrawRect(gfx::Rect damage_rect) { |
| + TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect"); |
| + client_->SetNeedsRedrawRect(damage_rect); |
| +} |
| + |
| +void OutputSurface::SetNeedsBeginFrame(bool enable) { |
| + frame_rate_controller_->SetActive(enable); |
| +} |
| + |
| +void OutputSurface::BeginFrame(base::TimeTicks frame_time) { |
| + // TODO(brianderson): Remove this early return once Android has |
| + // Browser-side throttling. |
| + //if (pending_begin_frames_ >= frame_rate_controller_->MaxFramesPending()) |
|
brianderson
2013/06/01 04:30:29
This should be uncommented and tested on Android.
Sami
2013/06/03 17:30:33
Do you have an idea what we'd need in the browser
brianderson
2013/06/03 18:51:40
Daniel is working on a patch to do that here:
http
|
| + // return; |
| + TRACE_EVENT0("cc", "OutputSurface::BeginFrame"); |
| + pending_begin_frames_++; |
| + frame_rate_controller_->WillSwapBuffers(); |
| + client_->BeginFrame(frame_time); |
| +} |
| + |
| +void OutputSurface::OnSendFrameToParentCompositorAck( |
| + const CompositorFrameAck& ack) { |
| + TRACE_EVENT0("cc", "OutputSurface::OnSendFrameToParentCompositorAck"); |
| + client_->OnSendFrameToParentCompositorAck(ack); |
| +} |
| + |
| +void OutputSurface::OnSwapBuffersComplete() { |
| + TRACE_EVENT0("cc", "OutputSurface::OnSwapBuffersComplete"); |
| + pending_begin_frames_--; |
| + client_->OnSwapBuffersComplete(); |
| + frame_rate_controller_->DidSwapBuffersComplete(); |
| +} |
| + |
| +void OutputSurface::DidLoseOutputSurface() { |
| + TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface"); |
| + pending_begin_frames_ = 0; |
| + client_->DidLoseOutputSurface(); |
| } |
| OutputSurface::~OutputSurface() { |
| + if (frame_rate_controller_) |
| + frame_rate_controller_->SetActive(false); |
| } |
| bool OutputSurface::ForcedDrawToSoftwareDevice() const { |
| return false; |
| } |
| -bool OutputSurface::BindToClient( |
| - cc::OutputSurfaceClient* client) { |
| +bool OutputSurface::BindToClient(cc::OutputSurfaceClient* client) { |
| DCHECK(client); |
| if (context3d_ && !context3d_->makeContextCurrent()) |
| return false; |
| @@ -88,7 +168,7 @@ bool OutputSurface::BindToClient( |
| has_gl_discard_backbuffer_ = |
| extensions.count("GL_CHROMIUM_discard_backbuffer") > 0; |
| - callbacks_.reset(new OutputSurfaceCallbacks(client_)); |
| + callbacks_.reset(new OutputSurfaceCallbacks(this)); |
| context3d_->setSwapBuffersCompleteCallbackCHROMIUM(callbacks_.get()); |
| context3d_->setContextLostCallback(callbacks_.get()); |