Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3673)

Unified Diff: cc/output/output_surface.cc

Issue 16833003: cc: Emulate BeginFrame in OutputSurfaces that don't support it natively (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/output/output_surface.h ('k') | cc/output/output_surface_client.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/output/output_surface.cc
diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc
index 0889b96080623c0996779925122fa8b118f0d993..9d234e5229a18ccb1b1ee35e0baa91bb147a1f2b 100644
--- a/cc/output/output_surface.cc
+++ b/cc/output/output_surface.cc
@@ -9,12 +9,14 @@
#include <vector>
#include "base/bind.h"
+#include "base/debug/trace_event.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 "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"
@@ -32,7 +34,7 @@ class OutputSurfaceCallbacks
WebGraphicsSwapBuffersCompleteCallbackCHROMIUM,
public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback {
public:
- explicit OutputSurfaceCallbacks(OutputSurfaceClient* client)
+ explicit OutputSurfaceCallbacks(OutputSurface* client)
: client_(client) {
DCHECK(client_);
}
@@ -44,50 +46,155 @@ class OutputSurfaceCallbacks
virtual void onContextLost() { client_->DidLoseOutputSurface(); }
private:
- OutputSurfaceClient* client_;
+ OutputSurface* client_;
};
OutputSurface::OutputSurface(
scoped_ptr<WebKit::WebGraphicsContext3D> context3d)
- : client_(NULL),
- context3d_(context3d.Pass()),
+ : context3d_(context3d.Pass()),
has_gl_discard_backbuffer_(false),
has_swap_buffers_complete_callback_(false),
device_scale_factor_(-1),
- weak_ptr_factory_(this) {
+ weak_ptr_factory_(this),
+ max_frames_pending_(0),
+ pending_swap_buffers_(0),
+ begin_frame_pending_(false),
+ client_(NULL) {
}
OutputSurface::OutputSurface(
scoped_ptr<cc::SoftwareOutputDevice> software_device)
- : client_(NULL),
- software_device_(software_device.Pass()),
+ : software_device_(software_device.Pass()),
has_gl_discard_backbuffer_(false),
has_swap_buffers_complete_callback_(false),
device_scale_factor_(-1),
- weak_ptr_factory_(this) {
+ weak_ptr_factory_(this),
+ max_frames_pending_(0),
+ pending_swap_buffers_(0),
+ begin_frame_pending_(false),
+ client_(NULL) {
}
OutputSurface::OutputSurface(
scoped_ptr<WebKit::WebGraphicsContext3D> context3d,
scoped_ptr<cc::SoftwareOutputDevice> software_device)
- : client_(NULL),
- context3d_(context3d.Pass()),
+ : context3d_(context3d.Pass()),
software_device_(software_device.Pass()),
has_gl_discard_backbuffer_(false),
has_swap_buffers_complete_callback_(false),
device_scale_factor_(-1),
- weak_ptr_factory_(this) {
+ weak_ptr_factory_(this),
+ max_frames_pending_(0),
+ pending_swap_buffers_(0),
+ begin_frame_pending_(false),
+ client_(NULL) {
+}
+
+void OutputSurface::InitializeBeginFrameEmulation(
+ Thread* thread,
+ bool throttle_frame_production,
+ base::TimeDelta interval) {
+ 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_->SetMaxSwapsPending(max_frames_pending_);
+
+ // The new frame rate controller will consume the swap acks of the old
+ // frame rate controller, so we set that expectation up here.
+ for (int i = 0; i < pending_swap_buffers_; i++)
+ frame_rate_controller_->DidSwapBuffers();
+}
+
+void OutputSurface::SetMaxFramesPending(int max_frames_pending) {
+ if (frame_rate_controller_)
+ frame_rate_controller_->SetMaxSwapsPending(max_frames_pending);
+ max_frames_pending_ = 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());
+ if (frame_rate_controller_)
+ frame_rate_controller_->SetTimebaseAndInterval(timebase, interval);
+}
+
+void OutputSurface::FrameRateControllerTick(bool throttled) {
+ DCHECK(frame_rate_controller_);
+ 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) {
+ TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginFrame", "enable", enable);
+ begin_frame_pending_ = false;
+ if (frame_rate_controller_)
+ frame_rate_controller_->SetActive(enable);
+}
+
+void OutputSurface::BeginFrame(base::TimeTicks frame_time) {
+ if (begin_frame_pending_ ||
+ (pending_swap_buffers_ >= max_frames_pending_ && max_frames_pending_ > 0))
+ return;
+ TRACE_EVENT1("cc", "OutputSurface::BeginFrame",
+ "pending_swap_buffers_", pending_swap_buffers_);
+ begin_frame_pending_ = true;
+ client_->BeginFrame(frame_time);
+}
+
+void OutputSurface::DidSwapBuffers() {
+ begin_frame_pending_ = false;
+ pending_swap_buffers_++;
+ TRACE_EVENT1("cc", "OutputSurface::DidSwapBuffers",
+ "pending_swap_buffers_", pending_swap_buffers_);
+ if (frame_rate_controller_)
+ frame_rate_controller_->DidSwapBuffers();
+}
+
+void OutputSurface::OnSwapBuffersComplete(const CompositorFrameAck* ack) {
+ pending_swap_buffers_--;
+ TRACE_EVENT1("cc", "OutputSurface::OnSwapBuffersComplete",
+ "pending_swap_buffers_", pending_swap_buffers_);
+ client_->OnSwapBuffersComplete(ack);
+ if (frame_rate_controller_)
+ frame_rate_controller_->DidSwapBuffersComplete();
+}
+
+void OutputSurface::DidLoseOutputSurface() {
+ TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
+ begin_frame_pending_ = false;
+ pending_swap_buffers_ = 0;
+ client_->DidLoseOutputSurface();
+}
+
+void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform,
+ gfx::Rect viewport) {
+ client_->SetExternalDrawConstraints(transform, viewport);
}
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);
client_ = client;
bool success = true;
@@ -143,7 +250,7 @@ void OutputSurface::SetContext3D(
context3d_ = context3d.Pass();
- callbacks_.reset(new OutputSurfaceCallbacks(client_));
+ callbacks_.reset(new OutputSurfaceCallbacks(this));
context3d_->setSwapBuffersCompleteCallbackCHROMIUM(callbacks_.get());
context3d_->setContextLostCallback(callbacks_.get());
}
@@ -186,6 +293,7 @@ void OutputSurface::BindFramebuffer() {
void OutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
if (frame->software_frame_data) {
PostSwapBuffersComplete();
+ DidSwapBuffers();
return;
}
@@ -206,20 +314,16 @@ void OutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
if (!has_swap_buffers_complete_callback_)
PostSwapBuffersComplete();
+
+ DidSwapBuffers();
}
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);
+ base::Bind(&OutputSurface::OnSwapBuffersComplete,
+ weak_ptr_factory_.GetWeakPtr(),
+ static_cast<CompositorFrameAck*>(NULL)));
}
} // namespace cc
« no previous file with comments | « cc/output/output_surface.h ('k') | cc/output/output_surface_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698