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

Unified Diff: cc/output/output_surface.cc

Issue 15836005: cc: Emulate BeginFrame in OutputSurfaces that don't support it natively (Closed) Base URL: http://git.chromium.org/chromium/src.git@nofrc
Patch Set: Ignore last patch set: bad upload. 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
Index: cc/output/output_surface.cc
diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc
index fe2b074ee46d033f7900054ccb164dc3b3992cae..4ffdc42cff590e9ea3166c28a34621d9bfa48b4b 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,27 @@ 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),
+ max_frames_pending_(0),
+ pending_swap_buffers_(0),
+ begin_frame_pending_(false) {
}
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),
+ max_frames_pending_(0),
+ pending_swap_buffers_(0),
+ begin_frame_pending_(false) {
}
OutputSurface::OutputSurface(
@@ -62,18 +70,115 @@ OutputSurface::OutputSurface(
: client_(NULL),
context3d_(context3d.Pass()),
software_device_(software_device.Pass()),
- has_gl_discard_backbuffer_(false) {
+ has_gl_discard_backbuffer_(false),
+ max_frames_pending_(0),
+ pending_swap_buffers_(0),
+ begin_frame_pending_(false) {
+}
+
+void OutputSurface::InitializeBeginFrameEmulation(
+ Thread* thread,
+ bool throttle_frame_production,
+ base::TimeDelta interval,
+ 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_->SetMaxSwapsPending(max_frames_pending_);
+}
+
+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) {
+ begin_frame_pending_ = false;
+ if (frame_rate_controller_)
+ 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 (begin_frame_pending_ || pending_swap_buffers_ >= max_frames_pending_)
+ return;
+ TRACE_EVENT0("cc", "OutputSurface::BeginFrame");
+ begin_frame_pending_ = true;
+ client_->BeginFrame(frame_time);
+}
+
+void OutputSurface::OnSendFrameToParentCompositorAck(
+ const CompositorFrameAck& ack) {
+ TRACE_EVENT0("cc", "OutputSurface::OnSendFrameToParentCompositorAck");
+ client_->OnSendFrameToParentCompositorAck(ack);
+}
+
+void OutputSurface::DidSwapBuffers() {
+ begin_frame_pending_ = false;
+ pending_swap_buffers_++;
+ if (frame_rate_controller_)
+ frame_rate_controller_->DidSwapBuffers();
+}
+
+void OutputSurface::OnSwapBuffersComplete() {
+ TRACE_EVENT0("cc", "OutputSurface::OnSwapBuffersComplete");
+ pending_swap_buffers_--;
+ client_->OnSwapBuffersComplete();
+ 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();
+ if (frame_rate_controller_)
+ frame_rate_controller_->DidAbortAllPendingFrames();
}
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 +193,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());
@@ -126,6 +231,7 @@ void OutputSurface::SwapBuffers(const ui::LatencyInfo& latency_info) {
// Note that currently this has the same effect as SwapBuffers; we should
// consider exposing a different entry point on WebGraphicsContext3D.
context3d_->prepareTexture();
+ DidSwapBuffers();
}
void OutputSurface::PostSubBuffer(gfx::Rect rect,
@@ -133,6 +239,7 @@ void OutputSurface::PostSubBuffer(gfx::Rect rect,
DCHECK(context3d_);
context3d_->postSubBufferCHROMIUM(
rect.x(), rect.y(), rect.width(), rect.height());
+ DidSwapBuffers();
}
} // namespace cc

Powered by Google App Engine
This is Rietveld 408576698