Commit 86f12052 authored by jamesr@chromium.org's avatar jamesr@chromium.org

Remove RequestAnimationFrame from mojo, add delayed tasks to RunLoop

Having a RequestAnimationFrame API on CommandBuffer makes no sense - the
context itself has nothing to do with scheduling and may not even be
swapping onscreen.  The spinning cube app was using this API as a way to
get delayed tasks without depending on base - basically
posttask-via-mojo-message. This adds basic delayed task support to the
public RunLoop and uses that instead. This only supports posting tasks
from the thread that owns the runloop. We can expand as needed. The mojo
RunLoop attempts to interleave delayed tasks with handle handlers, like
base's MessageLoop.

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285560 0039d316-1c4b-4281-b951-d872f2087c98
parent b77c7ce4
......@@ -157,7 +157,6 @@ Context::Context(v8::Isolate* isolate,
context_ = MojoGLES2CreateContext(
handle.value(),
&ContextLostThunk,
NULL,
this);
MojoGLES2MakeCurrent(context_);
}
......
......@@ -19,7 +19,6 @@ bool ContextProviderMojo::BindToCurrentThread() {
context_ = MojoGLES2CreateContext(
command_buffer_handle_.release().value(),
&ContextLostThunk,
NULL,
this);
return !!context_;
}
......
......@@ -28,7 +28,6 @@ Graphics3DResource::Graphics3DResource(PP_Instance instance)
ScopedMessagePipeHandle pipe = MojoPpapiGlobals::Get()->CreateGLES2Context();
context_ = MojoGLES2CreateContext(pipe.release().value(),
&ContextLostThunk,
&DrawAnimationFrameThunk,
this);
}
......@@ -154,10 +153,6 @@ void Graphics3DResource::ContextLostThunk(void* closure) {
static_cast<Graphics3DResource*>(closure)->ContextLost();
}
void Graphics3DResource::DrawAnimationFrameThunk(void* closure) {
// TODO(yzshen): Use this notification to drive the SwapBuffers() callback.
}
void Graphics3DResource::ContextLost() {
PluginInstance* plugin_instance =
MojoPpapiGlobals::Get()->GetInstance(pp_instance());
......
......@@ -61,7 +61,6 @@ class Graphics3DResource : public ppapi::Resource,
virtual ~Graphics3DResource();
static void ContextLostThunk(void* closure);
static void DrawAnimationFrameThunk(void* closure);
void ContextLost();
MojoGLES2Context context_;
......
......@@ -10,6 +10,7 @@
#include <stdlib.h>
#include "mojo/public/c/gles2/gles2.h"
#include "mojo/public/cpp/utility/run_loop.h"
namespace examples {
namespace {
......@@ -26,11 +27,10 @@ float GetRandomColor() {
}
GLES2ClientImpl::GLES2ClientImpl(mojo::CommandBufferPtr command_buffer)
: getting_animation_frames_(false) {
: last_time_(mojo::GetTimeTicksNow()), waiting_to_draw_(false) {
context_ = MojoGLES2CreateContext(
command_buffer.PassMessagePipe().release().value(),
&ContextLostThunk,
&DrawAnimationFrameThunk,
this);
MojoGLES2MakeCurrent(context_);
}
......@@ -44,7 +44,7 @@ void GLES2ClientImpl::SetSize(const mojo::Size& size) {
if (size_.width == 0 || size_.height == 0)
return;
cube_.Init(size_.width, size_.height);
RequestAnimationFrames();
WantToDraw();
}
void GLES2ClientImpl::HandleInputEvent(const mojo::Event& event) {
......@@ -53,27 +53,26 @@ void GLES2ClientImpl::HandleInputEvent(const mojo::Event& event) {
case mojo::EVENT_TYPE_TOUCH_PRESSED:
if (event.flags & mojo::EVENT_FLAGS_RIGHT_MOUSE_BUTTON)
break;
CancelAnimationFrames();
capture_point_ = *event.location;
last_drag_point_ = capture_point_;
drag_start_time_ = mojo::GetTimeTicksNow();
break;
case mojo::EVENT_TYPE_MOUSE_DRAGGED:
case mojo::EVENT_TYPE_TOUCH_MOVED:
case mojo::EVENT_TYPE_TOUCH_MOVED: {
if (event.flags & mojo::EVENT_FLAGS_RIGHT_MOUSE_BUTTON)
break;
if (!getting_animation_frames_) {
int direction = event.location->y < last_drag_point_.y ||
event.location->x > last_drag_point_.x ? 1 : -1;
cube_.set_direction(direction);
cube_.UpdateForDragDistance(
CalculateDragDistance(last_drag_point_, *event.location));
cube_.Draw();
MojoGLES2SwapBuffers();
last_drag_point_ = *event.location;
}
int direction = event.location->y < last_drag_point_.y ||
event.location->x > last_drag_point_.x
? 1
: -1;
cube_.set_direction(direction);
cube_.UpdateForDragDistance(
CalculateDragDistance(last_drag_point_, *event.location));
WantToDraw();
last_drag_point_ = *event.location;
break;
}
case mojo::EVENT_TYPE_MOUSE_RELEASED:
case mojo::EVENT_TYPE_TOUCH_RELEASED: {
if (event.flags & mojo::EVENT_FLAGS_RIGHT_MOUSE_BUTTON) {
......@@ -87,7 +86,7 @@ void GLES2ClientImpl::HandleInputEvent(const mojo::Event& event) {
delta);
capture_point_ = last_drag_point_ = mojo::Point();
RequestAnimationFrames();
WantToDraw();
break;
}
default:
......@@ -96,14 +95,31 @@ void GLES2ClientImpl::HandleInputEvent(const mojo::Event& event) {
}
void GLES2ClientImpl::ContextLost() {
CancelAnimationFrames();
}
void GLES2ClientImpl::ContextLostThunk(void* closure) {
static_cast<GLES2ClientImpl*>(closure)->ContextLost();
}
void GLES2ClientImpl::DrawAnimationFrame() {
struct DrawRunnable {
explicit DrawRunnable(GLES2ClientImpl* impl) : impl(impl) {}
virtual ~DrawRunnable() {}
void Run() const { impl->Draw(); }
GLES2ClientImpl* impl;
};
void GLES2ClientImpl::WantToDraw() {
if (waiting_to_draw_)
return;
waiting_to_draw_ = true;
mojo::RunLoop::current()->PostDelayedTask(mojo::Closure(DrawRunnable(this)),
MojoTimeTicks(16667));
}
void GLES2ClientImpl::Draw() {
waiting_to_draw_ = false;
MojoTimeTicks now = mojo::GetTimeTicksNow();
MojoTimeTicks offset = now - last_time_;
float delta = static_cast<float>(offset) / 1000000.;
......@@ -112,21 +128,7 @@ void GLES2ClientImpl::DrawAnimationFrame() {
cube_.Draw();
MojoGLES2SwapBuffers();
}
void GLES2ClientImpl::DrawAnimationFrameThunk(void* closure) {
static_cast<GLES2ClientImpl*>(closure)->DrawAnimationFrame();
}
void GLES2ClientImpl::RequestAnimationFrames() {
getting_animation_frames_ = true;
MojoGLES2RequestAnimationFrames(context_);
last_time_ = mojo::GetTimeTicksNow();
}
void GLES2ClientImpl::CancelAnimationFrames() {
getting_animation_frames_ = false;
MojoGLES2CancelAnimationFrames(context_);
WantToDraw();
}
} // namespace examples
......@@ -19,15 +19,12 @@ class GLES2ClientImpl {
void SetSize(const mojo::Size& size);
void HandleInputEvent(const mojo::Event& event);
void Draw();
private:
void ContextLost();
static void ContextLostThunk(void* closure);
void DrawAnimationFrame();
static void DrawAnimationFrameThunk(void* closure);
void RequestAnimationFrames();
void CancelAnimationFrames();
void WantToDraw();
MojoTimeTicks last_time_;
mojo::Size size_;
......@@ -35,7 +32,7 @@ class GLES2ClientImpl {
mojo::Point capture_point_;
mojo::Point last_drag_point_;
MojoTimeTicks drag_start_time_;
bool getting_animation_frames_;
bool waiting_to_draw_;
MojoGLES2Context context_;
......
......@@ -44,7 +44,6 @@ bool CreateMapAndDupSharedBuffer(size_t size,
CommandBufferDelegate::~CommandBufferDelegate() {}
void CommandBufferDelegate::ContextLost() {}
void CommandBufferDelegate::DrawAnimationFrame() {}
class CommandBufferClientImpl::SyncClientImpl
: public InterfaceImpl<CommandBufferSyncClient> {
......@@ -252,14 +251,6 @@ uint32 CommandBufferClientImpl::CreateStreamTexture(uint32 texture_id) {
return 0;
}
void CommandBufferClientImpl::RequestAnimationFrames() {
command_buffer_->RequestAnimationFrames();
}
void CommandBufferClientImpl::CancelAnimationFrames() {
command_buffer_->CancelAnimationFrames();
}
void CommandBufferClientImpl::DidDestroy() {
LostContext(gpu::error::kUnknown);
}
......@@ -271,10 +262,6 @@ void CommandBufferClientImpl::LostContext(int32_t lost_reason) {
delegate_->ContextLost();
}
void CommandBufferClientImpl::DrawAnimationFrame() {
delegate_->DrawAnimationFrame();
}
void CommandBufferClientImpl::OnConnectionError() {
LostContext(gpu::error::kUnknown);
}
......
......@@ -27,7 +27,6 @@ class CommandBufferDelegate {
public:
virtual ~CommandBufferDelegate();
virtual void ContextLost();
virtual void DrawAnimationFrame();
};
class CommandBufferClientImpl : public CommandBufferClient,
......@@ -72,16 +71,12 @@ class CommandBufferClientImpl : public CommandBufferClient,
virtual void Echo(const base::Closure& callback) OVERRIDE;
virtual uint32 CreateStreamTexture(uint32 texture_id) OVERRIDE;
void RequestAnimationFrames();
void CancelAnimationFrames();
private:
class SyncClientImpl;
// CommandBufferClient implementation:
virtual void DidDestroy() OVERRIDE;
virtual void LostContext(int32_t lost_reason) OVERRIDE;
virtual void DrawAnimationFrame() OVERRIDE;
// ErrorHandler implementation:
virtual void OnConnectionError() OVERRIDE;
......
......@@ -23,11 +23,9 @@ const size_t kDefaultMaxTransferBufferSize = 16 * 1024 * 1024;
GLES2Context::GLES2Context(const MojoAsyncWaiter* async_waiter,
ScopedMessagePipeHandle command_buffer_handle,
MojoGLES2ContextLost lost_callback,
MojoGLES2DrawAnimationFrame animation_callback,
void* closure)
: command_buffer_(this, async_waiter, command_buffer_handle.Pass()),
lost_callback_(lost_callback),
animation_callback_(animation_callback),
closure_(closure) {}
GLES2Context::~GLES2Context() {}
......@@ -57,17 +55,7 @@ bool GLES2Context::Initialize() {
gpu::gles2::GLES2Implementation::kNoLimit);
}
void GLES2Context::RequestAnimationFrames() {
command_buffer_.RequestAnimationFrames();
}
void GLES2Context::CancelAnimationFrames() {
command_buffer_.CancelAnimationFrames();
}
void GLES2Context::ContextLost() { lost_callback_(closure_); }
void GLES2Context::DrawAnimationFrame() { animation_callback_(closure_); }
} // namespace gles2
} // namespace mojo
......@@ -30,7 +30,6 @@ class GLES2Context : public CommandBufferDelegate,
explicit GLES2Context(const MojoAsyncWaiter* async_waiter,
ScopedMessagePipeHandle command_buffer_handle,
MojoGLES2ContextLost lost_callback,
MojoGLES2DrawAnimationFrame animation_callback,
void* closure);
virtual ~GLES2Context();
bool Initialize();
......@@ -39,19 +38,15 @@ class GLES2Context : public CommandBufferDelegate,
return implementation_.get();
}
gpu::ContextSupport* context_support() const { return implementation_.get(); }
void RequestAnimationFrames();
void CancelAnimationFrames();
private:
virtual void ContextLost() OVERRIDE;
virtual void DrawAnimationFrame() OVERRIDE;
CommandBufferClientImpl command_buffer_;
scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_;
scoped_ptr<gpu::TransferBuffer> transfer_buffer_;
scoped_ptr<gpu::gles2::GLES2Implementation> implementation_;
MojoGLES2ContextLost lost_callback_;
MojoGLES2DrawAnimationFrame animation_callback_;
void* closure_;
MOJO_DISALLOW_COPY_AND_ASSIGN(GLES2Context);
......
......@@ -61,13 +61,11 @@ void GLES2SupportImpl::Terminate() {
MojoGLES2Context GLES2SupportImpl::CreateContext(
MessagePipeHandle handle,
MojoGLES2ContextLost lost_callback,
MojoGLES2DrawAnimationFrame animation_callback,
void* closure) {
ScopedMessagePipeHandle scoped_handle(handle);
scoped_ptr<GLES2Context> client(new GLES2Context(async_waiter_,
scoped_handle.Pass(),
lost_callback,
animation_callback,
closure));
if (!client->Initialize())
client.reset();
......@@ -92,14 +90,6 @@ void GLES2SupportImpl::SwapBuffers() {
g_gles2_interface.Get().gpu_interface()->SwapBuffers();
}
void GLES2SupportImpl::RequestAnimationFrames(MojoGLES2Context context) {
static_cast<GLES2Context*>(context)->RequestAnimationFrames();
}
void GLES2SupportImpl::CancelAnimationFrames(MojoGLES2Context context) {
static_cast<GLES2Context*>(context)->CancelAnimationFrames();
}
void* GLES2SupportImpl::GetGLES2Interface(MojoGLES2Context context) {
return static_cast<GLES2Context*>(context)->interface();
}
......
......@@ -23,13 +23,10 @@ class MOJO_GLES2_IMPL_EXPORT GLES2SupportImpl : public GLES2Support {
virtual MojoGLES2Context CreateContext(
MessagePipeHandle handle,
MojoGLES2ContextLost lost_callback,
MojoGLES2DrawAnimationFrame animation_callback,
void* closure) OVERRIDE;
virtual void DestroyContext(MojoGLES2Context context) OVERRIDE;
virtual void MakeCurrent(MojoGLES2Context context) OVERRIDE;
virtual void SwapBuffers() OVERRIDE;
virtual void RequestAnimationFrames(MojoGLES2Context context) OVERRIDE;
virtual void CancelAnimationFrames(MojoGLES2Context context) OVERRIDE;
virtual void* GetGLES2Interface(MojoGLES2Context context) OVERRIDE;
virtual void* GetContextSupport(MojoGLES2Context context) OVERRIDE;
virtual GLES2Interface* GetGLES2InterfaceForCurrentContext() OVERRIDE;
......
......@@ -24,15 +24,10 @@ MOJO_GLES2_EXPORT void MojoGLES2Terminate(void);
MOJO_GLES2_EXPORT MojoGLES2Context MojoGLES2CreateContext(
MojoHandle handle,
MojoGLES2ContextLost lost_callback,
MojoGLES2DrawAnimationFrame animation_callback,
void* closure);
MOJO_GLES2_EXPORT void MojoGLES2DestroyContext(MojoGLES2Context context);
MOJO_GLES2_EXPORT void MojoGLES2MakeCurrent(MojoGLES2Context context);
MOJO_GLES2_EXPORT void MojoGLES2SwapBuffers(void);
// TODO(piman): this doesn't belong here.
MOJO_GLES2_EXPORT void MojoGLES2RequestAnimationFrames(
MojoGLES2Context context);
MOJO_GLES2_EXPORT void MojoGLES2CancelAnimationFrames(MojoGLES2Context context);
// TODO(piman): We shouldn't have to leak those 2 interfaces, especially in a
// type-unsafe way.
......
......@@ -17,7 +17,6 @@ extern "C" {
typedef struct MojoGLES2ContextPrivate* MojoGLES2Context;
typedef void (*MojoGLES2ContextLost)(void* closure);
typedef void (*MojoGLES2DrawAnimationFrame)(void* closure);
#ifdef __cplusplus
} // extern "C"
......
......@@ -486,6 +486,8 @@ class Callback<void(A1, A2, A3, A4, A5, A6, A7)> {
internal::SharedPtr<Runnable> sink_;
};
typedef Callback<void()> Closure;
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_
......@@ -84,6 +84,8 @@ class Callback<void($for ARG , [[A$(ARG)]])> {
]] $$ for ARITY
typedef Callback<void()> Closure;
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_
include_rules = [
"+mojo/public/cpp/bindings/callback.h"
]
......@@ -36,7 +36,8 @@ struct RunLoop::RunState {
bool should_quit;
};
RunLoop::RunLoop() : run_state_(NULL), next_handler_id_(0) {
RunLoop::RunLoop()
: run_state_(NULL), next_handler_id_(0), next_sequence_number_(0) {
assert(!current());
current_run_loop.Set(this);
}
......@@ -95,8 +96,10 @@ void RunLoop::Run() {
RunState* old_state = run_state_;
RunState run_state;
run_state_ = &run_state;
while (!run_state.should_quit)
while (!run_state.should_quit) {
DoDelayedWork();
Wait(false);
}
run_state_ = old_state;
}
......@@ -106,21 +109,37 @@ void RunLoop::RunUntilIdle() {
RunState run_state;
run_state_ = &run_state;
while (!run_state.should_quit) {
if (!Wait(true))
DoDelayedWork();
if (!Wait(true) && delayed_tasks_.empty())
break;
}
run_state_ = old_state;
}
void RunLoop::DoDelayedWork() {
MojoTimeTicks now = GetTimeTicksNow();
if (!delayed_tasks_.empty() && delayed_tasks_.top().run_time <= now) {
PendingTask task = delayed_tasks_.top();
delayed_tasks_.pop();
task.task.Run();
}
}
void RunLoop::Quit() {
assert(current() == this);
if (run_state_)
run_state_->should_quit = true;
}
void RunLoop::PostDelayedTask(const Closure& task, MojoTimeTicks delay) {
assert(current() == this);
MojoTimeTicks run_time = delay + GetTimeTicksNow();
delayed_tasks_.push(PendingTask(task, run_time, next_sequence_number_++));
}
bool RunLoop::Wait(bool non_blocking) {
const WaitState wait_state = GetWaitState(non_blocking);
if (wait_state.handles.empty()) {
if (wait_state.handles.empty() && delayed_tasks_.empty()) {
Quit();
return false;
}
......@@ -206,6 +225,13 @@ RunLoop::WaitState RunLoop::GetWaitState(bool non_blocking) const {
min_time = i->second.deadline;
}
}
if (!delayed_tasks_.empty()) {
MojoTimeTicks delayed_min_time = delayed_tasks_.top().run_time;
if (min_time == kInvalidTimeTicks)
min_time = delayed_min_time;
else
min_time = std::min(min_time, delayed_min_time);
}
if (non_blocking) {
wait_state.deadline = static_cast<MojoDeadline>(0);
} else if (min_time != kInvalidTimeTicks) {
......@@ -218,4 +244,24 @@ RunLoop::WaitState RunLoop::GetWaitState(bool non_blocking) const {
return wait_state;
}
RunLoop::PendingTask::PendingTask(const Closure& task,
MojoTimeTicks run_time,
uint64_t sequence_number)
: task(task), run_time(run_time), sequence_number(sequence_number) {
}
RunLoop::PendingTask::~PendingTask() {
}
bool RunLoop::PendingTask::operator<(const RunLoop::PendingTask& other) const {
if (run_time != other.run_time) {
// std::priority_queue<> puts the least element at the end of the queue. We
// want the soonest eligible task to be at the head of the queue, so
// run_times further in the future are considered lesser.
return run_time > other.run_time;
}
return sequence_number > other.sequence_number;
}
} // namespace mojo
......@@ -6,7 +6,9 @@
#define MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_
#include <map>
#include <queue>
#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/public/cpp/system/core.h"
namespace mojo {
......@@ -49,6 +51,10 @@ class RunLoop {
void Quit();
// Adds a task to be performed after delay has elapsed. Must be posted to the
// current thread's RunLoop.
void PostDelayedTask(const Closure& task, MojoTimeTicks delay);
private:
struct RunState;
struct WaitState;
......@@ -70,6 +76,9 @@ class RunLoop {
typedef std::map<Handle, HandlerData> HandleToHandlerData;
// Do one unit of delayed work, if eligible.
void DoDelayedWork();
// Waits for a handle to be ready. Returns after servicing at least one
// handle (or there are no more handles) unless |non_blocking| is true,
// in which case it will also return if servicing at least one handle
......@@ -100,6 +109,24 @@ class RunLoop {
// notify it.
int next_handler_id_;
struct PendingTask {
PendingTask(const Closure& task,
MojoTimeTicks runtime,
uint64_t sequence_number);
~PendingTask();
bool operator<(const PendingTask& other) const;
Closure task;
MojoTimeTicks run_time;
uint64_t sequence_number;
};
// An ever increasing sequence number attached to each pending task in order
// to preserve relative order of tasks posted at the 'same' time.
uint64_t next_sequence_number_;
typedef std::priority_queue<PendingTask> DelayedTaskQueue;
DelayedTaskQueue delayed_tasks_;
MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoop);
};
......
......@@ -284,5 +284,28 @@ TEST_F(RunLoopTest, NestedRun) {
EXPECT_EQ(handler.last_error_result(), MOJO_RESULT_DEADLINE_EXCEEDED);
}
struct Task {
Task(int num, std::vector<int>* sequence) : num(num), sequence(sequence) {}
void Run() const { sequence->push_back(num); }
int num;
std::vector<int>* sequence;
};
TEST_F(RunLoopTest, DelayedTaskOrder) {
std::vector<int> sequence;
RunLoop run_loop;
run_loop.PostDelayedTask(Closure(Task(1, &sequence)), 0);
run_loop.PostDelayedTask(Closure(Task(2, &sequence)), 0);
run_loop.PostDelayedTask(Closure(Task(3, &sequence)), 0);
run_loop.RunUntilIdle();
ASSERT_EQ(3u, sequence.size());
EXPECT_EQ(1, sequence[0]);
EXPECT_EQ(2, sequence[1]);
EXPECT_EQ(3, sequence[2]);
}
} // namespace
} // namespace mojo
......@@ -28,11 +28,9 @@ void MojoGLES2Terminate() {
MojoGLES2Context MojoGLES2CreateContext(
MojoHandle handle,
MojoGLES2ContextLost lost_callback,
MojoGLES2DrawAnimationFrame animation_callback,
void* closure) {
return g_gles2_support->CreateContext(mojo::MessagePipeHandle(handle),
lost_callback,
animation_callback,
closure);
}
......@@ -51,16 +49,6 @@ void MojoGLES2SwapBuffers() {
return g_gles2_support->SwapBuffers();
}
void MojoGLES2RequestAnimationFrames(MojoGLES2Context context) {
assert(g_gles2_support);
return g_gles2_support->RequestAnimationFrames(context);
}
void MojoGLES2CancelAnimationFrames(MojoGLES2Context context) {
assert(g_gles2_support);
return g_gles2_support->CancelAnimationFrames(context);
}
void* MojoGLES2GetGLES2Interface(MojoGLES2Context context) {
assert(g_gles2_support);
return g_gles2_support->GetGLES2Interface(context);
......
......@@ -29,13 +29,10 @@ class MOJO_GLES2_EXPORT GLES2Support {
virtual MojoGLES2Context CreateContext(
MessagePipeHandle handle,
MojoGLES2ContextLost lost_callback,
MojoGLES2DrawAnimationFrame animation_callback,
void* closure) = 0;
virtual void DestroyContext(MojoGLES2Context context) = 0;
virtual void MakeCurrent(MojoGLES2Context context) = 0;
virtual void SwapBuffers() = 0;
virtual void RequestAnimationFrames(MojoGLES2Context context) = 0;
virtual void CancelAnimationFrames(MojoGLES2Context context) = 0;
virtual void* GetGLES2Interface(MojoGLES2Context context) = 0;
virtual void* GetContextSupport(MojoGLES2Context context) = 0;
virtual GLES2Interface* GetGLES2InterfaceForCurrentContext() = 0;
......
......@@ -31,19 +31,12 @@ interface CommandBuffer {
DestroyTransferBuffer(int32 id);
Echo() => ();
// TODO(piman): move to somewhere else (native_viewport?).
RequestAnimationFrames();
CancelAnimationFrames();
// TODO(piman): sync points
};
interface CommandBufferClient {
DidDestroy();
LostContext(int32 lost_reason); // TODO(piman): enum
// TODO(piman): move to somewhere else (native_viewport?).
DrawAnimationFrame();
};
}
......@@ -170,22 +170,11 @@ void CommandBufferImpl::Echo(const Callback<void()>& callback) {
callback.Run();
}
void CommandBufferImpl::RequestAnimationFrames() {
timer_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(16),
this,
&CommandBufferImpl::DrawAnimationFrame);
}
void CommandBufferImpl::CancelAnimationFrames() { timer_.Stop(); }
void CommandBufferImpl::OnParseError() {
gpu::CommandBuffer::State state = command_buffer_->GetLastState();
client()->LostContext(state.context_lost_reason);
}
void CommandBufferImpl::DrawAnimationFrame() { client()->DrawAnimationFrame(); }
void CommandBufferImpl::OnResize(gfx::Size size, float scale_factor) {
surface_->Resize(size);
}
......
......@@ -46,9 +46,6 @@ class CommandBufferImpl : public InterfaceImpl<CommandBuffer> {
virtual void DestroyTransferBuffer(int32_t id) OVERRIDE;
virtual void Echo(const Callback<void()>& callback) OVERRIDE;
virtual void RequestAnimationFrames() OVERRIDE;
virtual void CancelAnimationFrames() OVERRIDE;
private:
bool DoInitialize(mojo::ScopedSharedBufferHandle shared_state);
......@@ -56,8 +53,6 @@ class CommandBufferImpl : public InterfaceImpl<CommandBuffer> {
void OnParseError();
void DrawAnimationFrame();
CommandBufferSyncClientPtr sync_client_;
gfx::AcceleratedWidget widget_;
......@@ -66,7 +61,6 @@ class CommandBufferImpl : public InterfaceImpl<CommandBuffer> {
scoped_ptr<gpu::gles2::GLES2Decoder> decoder_;
scoped_ptr<gpu::GpuScheduler> scheduler_;
scoped_refptr<gfx::GLSurface> surface_;
base::RepeatingTimer<CommandBufferImpl> timer_;
DISALLOW_COPY_AND_ASSIGN(CommandBufferImpl);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment