Skip to content

Commit

Permalink
Revert 205750 "cc: Emulate BeginFrame in OutputSurfaces that don..."
Browse files Browse the repository at this point in the history
> cc: Emulate BeginFrame in OutputSurfaces that don't support it natively
> 
> This will allow us to avoid having two different code paths
> in the Scheduler. It also allows us to more easily remove the
> VSyncTimeSource and FrameRateController from the Scheduler.
> 
> This patch instantiates the FrameRateController inside of
> OutputSurface for now, but the FrameRateController could be
> removed in future patches.
> 
> BUG=245920
> BUG=243497
> 
> Review URL: https://chromiumcodereview.appspot.com/15836005

TBR=brianderson@chromium.org

Review URL: https://codereview.chromium.org/16679010

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@205838 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
skaslev@chromium.org committed Jun 12, 2013
1 parent 8426f3a commit c7480af
Show file tree
Hide file tree
Showing 42 changed files with 825 additions and 717 deletions.
2 changes: 2 additions & 0 deletions cc/cc.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@
'scheduler/texture_uploader.cc',
'scheduler/texture_uploader.h',
'scheduler/time_source.h',
'scheduler/vsync_time_source.cc',
'scheduler/vsync_time_source.h',
'trees/damage_tracker.cc',
'trees/damage_tracker.h',
'trees/layer_sorter.cc',
Expand Down
1 change: 1 addition & 0 deletions cc/cc_tests.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
'scheduler/scheduler_state_machine_unittest.cc',
'scheduler/scheduler_unittest.cc',
'scheduler/texture_uploader_unittest.cc',
'scheduler/vsync_time_source_unittest.cc',
'test/fake_web_graphics_context_3d_unittest.cc',
'trees/damage_tracker_unittest.cc',
'trees/layer_sorter_unittest.cc',
Expand Down
149 changes: 23 additions & 126 deletions cc/output/output_surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@
#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"
Expand All @@ -34,7 +32,7 @@ class OutputSurfaceCallbacks
WebGraphicsSwapBuffersCompleteCallbackCHROMIUM,
public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback {
public:
explicit OutputSurfaceCallbacks(OutputSurface* client)
explicit OutputSurfaceCallbacks(OutputSurfaceClient* client)
: client_(client) {
DCHECK(client_);
}
Expand All @@ -46,155 +44,50 @@ class OutputSurfaceCallbacks
virtual void onContextLost() { client_->DidLoseOutputSurface(); }

private:
OutputSurface* client_;
OutputSurfaceClient* client_;
};

OutputSurface::OutputSurface(
scoped_ptr<WebKit::WebGraphicsContext3D> context3d)
: context3d_(context3d.Pass()),
: client_(NULL),
context3d_(context3d.Pass()),
has_gl_discard_backbuffer_(false),
has_swap_buffers_complete_callback_(false),
device_scale_factor_(-1),
weak_ptr_factory_(this),
max_frames_pending_(0),
pending_swap_buffers_(0),
begin_frame_pending_(false),
client_(NULL) {
weak_ptr_factory_(this) {
}

OutputSurface::OutputSurface(
scoped_ptr<cc::SoftwareOutputDevice> software_device)
: software_device_(software_device.Pass()),
: client_(NULL),
software_device_(software_device.Pass()),
has_gl_discard_backbuffer_(false),
has_swap_buffers_complete_callback_(false),
device_scale_factor_(-1),
weak_ptr_factory_(this),
max_frames_pending_(0),
pending_swap_buffers_(0),
begin_frame_pending_(false),
client_(NULL) {
weak_ptr_factory_(this) {
}

OutputSurface::OutputSurface(
scoped_ptr<WebKit::WebGraphicsContext3D> context3d,
scoped_ptr<cc::SoftwareOutputDevice> software_device)
: context3d_(context3d.Pass()),
: client_(NULL),
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),
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);
weak_ptr_factory_(this) {
}

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;
Expand Down Expand Up @@ -250,7 +143,7 @@ void OutputSurface::SetContext3D(


context3d_ = context3d.Pass();
callbacks_.reset(new OutputSurfaceCallbacks(this));
callbacks_.reset(new OutputSurfaceCallbacks(client_));
context3d_->setSwapBuffersCompleteCallbackCHROMIUM(callbacks_.get());
context3d_->setContextLostCallback(callbacks_.get());
}
Expand Down Expand Up @@ -313,16 +206,20 @@ 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::OnSwapBuffersComplete,
weak_ptr_factory_.GetWeakPtr(),
static_cast<CompositorFrameAck*>(NULL)));
base::Bind(&OutputSurface::SwapBuffersComplete,
weak_ptr_factory_.GetWeakPtr()));
}

void OutputSurface::SwapBuffersComplete() {
if (!client_)
return;

client_->OnSwapBuffersComplete(NULL);
}

} // namespace cc
44 changes: 6 additions & 38 deletions cc/output/output_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,20 @@
#include "cc/base/cc_export.h"
#include "cc/output/context_provider.h"
#include "cc/output/software_output_device.h"
#include "cc/scheduler/frame_rate_controller.h"
#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"

namespace ui { struct LatencyInfo; }

namespace gfx {
class Rect;
class Size;
class Transform;
}

namespace cc {

class CompositorFrame;
class CompositorFrameAck;
class OutputSurfaceClient;
class OutputSurfaceCallbacks;
class Thread;

// Represents the output surface for a compositor. The compositor owns
// and manages its destruction. Its lifetime is:
Expand All @@ -38,7 +34,7 @@ class Thread;
// From here on, it will only be used on the compositor thread.
// 3. If the 3D context is lost, then the compositor will delete the output
// surface (on the compositor thread) and go back to step 1.
class CC_EXPORT OutputSurface : public FrameRateControllerClient {
class CC_EXPORT OutputSurface {
public:
explicit OutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D> context3d);

Expand Down Expand Up @@ -87,13 +83,6 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
// thread.
virtual bool BindToClient(OutputSurfaceClient* client);

void InitializeBeginFrameEmulation(
Thread* thread,
bool throttle_frame_production,
base::TimeDelta interval);

void SetMaxFramesPending(int max_frames_pending);

virtual void EnsureBackbuffer();
virtual void DiscardBackbuffer();

Expand All @@ -114,7 +103,7 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
// Requests a BeginFrame notification from the output surface. The
// notification will be delivered by calling
// OutputSurfaceClient::BeginFrame until the callback is disabled.
virtual void SetNeedsBeginFrame(bool enable);
virtual void SetNeedsBeginFrame(bool enable) {}

protected:
// Synchronously initialize context3d and enter hardware mode.
Expand All @@ -127,6 +116,7 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {

void PostSwapBuffersComplete();

OutputSurfaceClient* client_;
struct cc::OutputSurface::Capabilities capabilities_;
scoped_ptr<OutputSurfaceCallbacks> callbacks_;
scoped_ptr<WebKit::WebGraphicsContext3D> context3d_;
Expand All @@ -135,34 +125,12 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
bool has_swap_buffers_complete_callback_;
gfx::Size surface_size_;
float device_scale_factor_;
base::WeakPtrFactory<OutputSurface> weak_ptr_factory_;

// The FrameRateController is deprecated.
// Platforms should move to native BeginFrames instead.
void OnVSyncParametersChanged(base::TimeTicks timebase,
base::TimeDelta interval);
virtual void FrameRateControllerTick(bool throttled) OVERRIDE;
scoped_ptr<FrameRateController> frame_rate_controller_;
int max_frames_pending_;
int pending_swap_buffers_;
bool begin_frame_pending_;

// Forwarded to OutputSurfaceClient but threaded through OutputSurface
// first so OutputSurface has a chance to update the FrameRateController
bool HasClient() { return !!client_; }
void SetNeedsRedrawRect(gfx::Rect damage_rect);
void BeginFrame(base::TimeTicks frame_time);
void DidSwapBuffers();
void OnSwapBuffersComplete(const CompositorFrameAck* ack);
void DidLoseOutputSurface();
void SetExternalDrawConstraints(const gfx::Transform& transform,
gfx::Rect viewport);

private:
OutputSurfaceClient* client_;
friend class OutputSurfaceCallbacks;

void SetContext3D(scoped_ptr<WebKit::WebGraphicsContext3D> context3d);
void SwapBuffersComplete();

base::WeakPtrFactory<OutputSurface> weak_ptr_factory_;

DISALLOW_COPY_AND_ASSIGN(OutputSurface);
};
Expand Down
2 changes: 2 additions & 0 deletions cc/output/output_surface_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class CC_EXPORT OutputSurfaceClient {
virtual bool DeferredInitialize(
scoped_refptr<ContextProvider> offscreen_context_provider) = 0;
virtual void SetNeedsRedrawRect(gfx::Rect damage_rect) = 0;
virtual void OnVSyncParametersChanged(base::TimeTicks timebase,
base::TimeDelta interval) = 0;
virtual void BeginFrame(base::TimeTicks frame_time) = 0;
virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) = 0;
virtual void DidLoseOutputSurface() = 0;
Expand Down
Loading

0 comments on commit c7480af

Please sign in to comment.