Skip to content

Commit

Permalink
Teach SkyShell.apk to stop posting frames when not visible
Browse files Browse the repository at this point in the history
This listens to both surface destruction as well as activity
pause/unpause.

R=abarth@chromium.org, abarth@google.com

Review URL: https://codereview.chromium.org/1230073002 .
  • Loading branch information
Eric Seidel committed Jul 10, 2015
1 parent 896c97b commit 6f0c2d0
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 27 deletions.
3 changes: 3 additions & 0 deletions services/engine/sky_engine.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ struct ViewportMetrics {
};

interface SkyEngine {
OnActivityPaused();
OnActivityResumed();

OnViewportMetricsChanged(ViewportMetrics metrics);
OnInputEvent(InputEvent event);

Expand Down
22 changes: 4 additions & 18 deletions shell/android/org/domokit/sky/shell/PlatformViewAndroid.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ public void surfaceDestroyed(SurfaceHolder holder) {
KeyboardServiceImpl.setActiveView(this);
}

SkyEngine getEngine() {
return mSkyEngine;
}

@Override
protected void onDetachedFromWindow() {
getHolder().removeCallback(mSurfaceCallback);
Expand Down Expand Up @@ -199,24 +203,6 @@ public void onGestureEvent(InputEvent event) {
mSkyEngine.onInputEvent(event);
}

public void onBackPressed() {
InputEvent event = new InputEvent();
event.type = EventType.BACK;
mSkyEngine.onInputEvent(event);
}

public void loadSnapshot(String path) {
mSkyEngine.runFromSnapshot(path);
}

public void loadBundle(String path) {
mSkyEngine.runFromBundle(path);
}

public void loadUrl(String url) {
mSkyEngine.runFromNetwork(url);
}

private void attach() {
Core core = CoreImpl.getInstance();
Pair<SkyEngine.Proxy, InterfaceRequest<SkyEngine>> result =
Expand Down
32 changes: 25 additions & 7 deletions shell/android/org/domokit/sky/shell/SkyActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import android.view.WindowManager;

import org.chromium.base.PathUtils;
import org.chromium.mojom.sky.EventType;
import org.chromium.mojom.sky.InputEvent;

import org.domokit.activity.ActivityImpl;

Expand Down Expand Up @@ -64,33 +66,49 @@ protected void onDestroy() {
@Override
public void onBackPressed() {
if (mView != null) {
mView.onBackPressed();
// TODO(abarth): We should have some way to trigger the default
// back behavior.
InputEvent event = new InputEvent();
event.type = EventType.BACK;
mView.getEngine().onInputEvent(event);
return;
}
super.onBackPressed();
}

@Override
protected void onPause() {
super.onPause();
if (mView != null) {
mView.getEngine().onActivityPaused();
}
}

@Override
protected void onPostResume() {
super.onPostResume();
if (mView != null) {
mView.getEngine().onActivityResumed();
}
}

/**
* Override this function to customize startup behavior.
*/
protected void onSkyReady() {
File dataDir = new File(PathUtils.getDataDirectory(this));
File snapshot = new File(dataDir, SkyApplication.SNAPSHOT);
if (snapshot.exists()) {
mView.loadSnapshot(snapshot.getPath());
mView.getEngine().runFromSnapshot(snapshot.getPath());
return;
}
File appBundle = new File(dataDir, SkyApplication.APP_BUNDLE);
if (appBundle.exists()) {
mView.loadBundle(appBundle.getPath());
mView.getEngine().runFromBundle(appBundle.getPath());
return;
}
}

public void loadUrl(String url) {
mView.loadUrl(url);
mView.getEngine().runFromNetwork(url);
}

public boolean loadBundleByName(String name) {
Expand All @@ -99,7 +117,7 @@ public boolean loadBundleByName(String name) {
if (!bundle.exists()) {
return false;
}
mView.loadBundle(bundle.getPath());
mView.getEngine().runFromBundle(bundle.getPath());
return true;
}
}
12 changes: 11 additions & 1 deletion shell/ui/animator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Animator::Animator(const Engine::Config& config, Engine* engine)
engine_(engine),
engine_requested_frame_(false),
frame_in_progress_(false),
paused_(false),
weak_factory_(this) {
}

Expand All @@ -37,10 +38,16 @@ void Animator::RequestFrame() {
}
}

void Animator::CancelFrameRequest() {
void Animator::Stop() {
paused_ = true;
engine_requested_frame_ = false;
}

void Animator::Start() {
paused_ = false;
RequestFrame();
}

void Animator::BeginFrame() {
DCHECK(frame_in_progress_);
// There could be a request in the message loop at time of cancel.
Expand All @@ -62,6 +69,9 @@ void Animator::BeginFrame() {
void Animator::OnFrameComplete() {
DCHECK(frame_in_progress_);
frame_in_progress_ = false;
if (paused_)
return;

if (engine_requested_frame_) {
frame_in_progress_ = true;
BeginFrame();
Expand Down
5 changes: 4 additions & 1 deletion shell/ui/animator.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ class Animator {
~Animator();

void RequestFrame();
void CancelFrameRequest();

void Start();
void Stop();

private:
void BeginFrame();
Expand All @@ -27,6 +29,7 @@ class Animator {
Engine* engine_;
bool engine_requested_frame_;
bool frame_in_progress_;
bool paused_;

base::WeakPtrFactory<Animator> weak_factory_;

Expand Down
25 changes: 25 additions & 0 deletions shell/ui/engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ Engine::Engine(const Config& config)
: config_(config),
animator_(new Animator(config, this)),
binding_(this),
activity_running_(false),
have_surface_(false),
weak_factory_(this) {
}

Expand Down Expand Up @@ -118,11 +120,15 @@ void Engine::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) {
config_.gpu_task_runner->PostTask(
FROM_HERE, base::Bind(&GPUDelegate::OnAcceleratedWidgetAvailable,
config_.gpu_delegate, widget));
have_surface_ = true;
StartAnimatorIfPossible();
if (sky_view_)
ScheduleFrame();
}

void Engine::OnOutputSurfaceDestroyed() {
have_surface_ = false;
StopAnimator();
config_.gpu_task_runner->PostTask(
FROM_HERE,
base::Bind(&GPUDelegate::OnOutputSurfaceDestroyed, config_.gpu_delegate));
Expand Down Expand Up @@ -195,12 +201,31 @@ void Engine::RunFromBundle(const mojo::String& path) {
weak_factory_.GetWeakPtr(), path_str));
}

void Engine::OnActivityPaused() {
activity_running_ = false;
StopAnimator();
}

void Engine::OnActivityResumed() {
activity_running_ = true;
StartAnimatorIfPossible();
}

void Engine::DidCreateIsolate(Dart_Isolate isolate) {
Internals::Create(isolate,
CreateServiceProvider(config_.service_provider_context),
root_bundle_.Pass());
}

void Engine::StopAnimator() {
animator_->Stop();
}

void Engine::StartAnimatorIfPossible() {
if (activity_running_ && have_surface_)
animator_->Start();
}

void Engine::ScheduleFrame() {
animator_->RequestFrame();
}
Expand Down
10 changes: 10 additions & 0 deletions shell/ui/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ class Engine : public UIDelegate,
void RunFromSnapshot(const mojo::String& path) override;
void RunFromBundle(const mojo::String& path) override;

void OnActivityPaused() override;
void OnActivityResumed() override;

// SkyViewClient methods:
void ScheduleFrame() override;
void DidCreateIsolate(Dart_Isolate isolate) override;
Expand All @@ -88,6 +91,9 @@ class Engine : public UIDelegate,
void RunFromSnapshotStream(const std::string& name,
mojo::ScopedDataPipeConsumerHandle snapshot);

void StopAnimator();
void StartAnimatorIfPossible();

Config config_;
scoped_ptr<Animator> animator_;

Expand All @@ -99,6 +105,10 @@ class Engine : public UIDelegate,
blink::SkyDisplayMetrics display_metrics_;
mojo::Binding<SkyEngine> binding_;

// TODO(eseidel): This should move into an AnimatorStateMachine.
bool activity_running_;
bool have_surface_;

base::WeakPtrFactory<Engine> weak_factory_;

DISALLOW_COPY_AND_ASSIGN(Engine);
Expand Down

0 comments on commit 6f0c2d0

Please sign in to comment.