summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/android/content_view_render_view.cc23
-rw-r--r--content/browser/android/content_view_render_view.h9
-rw-r--r--content/browser/renderer_host/compositor_impl_android.cc131
-rw-r--r--content/browser/renderer_host/compositor_impl_android.h43
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.cc1
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java15
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java90
-rw-r--r--content/public/browser/android/compositor.h5
-rw-r--r--content/public/browser/android/compositor_client.h9
-rw-r--r--ui/android/java/src/org/chromium/ui/base/WindowAndroid.java33
-rw-r--r--ui/base/android/window_android.cc5
-rw-r--r--ui/base/android/window_android_compositor.h2
12 files changed, 189 insertions, 177 deletions
diff --git a/content/browser/android/content_view_render_view.cc b/content/browser/android/content_view_render_view.cc
index 9f5ed31..4a39885 100644
--- a/content/browser/android/content_view_render_view.cc
+++ b/content/browser/android/content_view_render_view.cc
@@ -53,8 +53,7 @@ bool ContentViewRenderView::RegisterContentViewRenderView(JNIEnv* env) {
ContentViewRenderView::ContentViewRenderView(JNIEnv* env,
jobject obj,
gfx::NativeWindow root_window)
- : buffers_swapped_during_composite_(false),
- layer_tree_build_helper_(new LayerTreeBuildHelperImpl()),
+ : layer_tree_build_helper_(new LayerTreeBuildHelperImpl()),
root_window_(root_window),
current_surface_format_(0) {
java_obj_.Reset(env, obj);
@@ -118,15 +117,6 @@ void ContentViewRenderView::SurfaceChanged(JNIEnv* env, jobject obj,
compositor_->SetWindowBounds(gfx::Size(width, height));
}
-jboolean ContentViewRenderView::Composite(JNIEnv* env, jobject obj) {
- if (!compositor_)
- return false;
-
- buffers_swapped_during_composite_ = false;
- compositor_->Composite();
- return buffers_swapped_during_composite_;
-}
-
jboolean ContentViewRenderView::CompositeToBitmap(JNIEnv* env, jobject obj,
jobject java_bitmap) {
gfx::JavaBitmap bitmap(java_bitmap);
@@ -139,19 +129,14 @@ jboolean ContentViewRenderView::CompositeToBitmap(JNIEnv* env, jobject obj,
void ContentViewRenderView::SetOverlayVideoMode(
JNIEnv* env, jobject obj, bool enabled) {
compositor_->SetHasTransparentBackground(enabled);
- Java_ContentViewRenderView_requestRender(env, obj);
}
-void ContentViewRenderView::ScheduleComposite() {
+void ContentViewRenderView::Layout() {
JNIEnv* env = base::android::AttachCurrentThread();
- Java_ContentViewRenderView_requestRender(env, java_obj_.obj());
-}
-
-void ContentViewRenderView::OnSwapBuffersPosted() {
- buffers_swapped_during_composite_ = true;
+ Java_ContentViewRenderView_onCompositorLayout(env, java_obj_.obj());
}
-void ContentViewRenderView::OnSwapBuffersCompleted() {
+void ContentViewRenderView::OnSwapBuffersCompleted(int pending_swap_buffers) {
JNIEnv* env = base::android::AttachCurrentThread();
Java_ContentViewRenderView_onSwapBuffersCompleted(env, java_obj_.obj());
}
diff --git a/content/browser/android/content_view_render_view.h b/content/browser/android/content_view_render_view.h
index 8f14456..cbdb1f1 100644
--- a/content/browser/android/content_view_render_view.h
+++ b/content/browser/android/content_view_render_view.h
@@ -43,18 +43,15 @@ class ContentViewRenderView : public CompositorClient {
jboolean CompositeToBitmap(JNIEnv* env, jobject obj, jobject java_bitmap);
void SetOverlayVideoMode(JNIEnv* env, jobject obj, bool enabled);
- // CompositorClient ---------------------------------------------------------
- virtual void ScheduleComposite() OVERRIDE;
- virtual void OnSwapBuffersPosted() OVERRIDE;
- virtual void OnSwapBuffersCompleted() OVERRIDE;
+ // CompositorClient implementation
+ virtual void Layout() OVERRIDE;
+ virtual void OnSwapBuffersCompleted(int pending_swap_buffers) OVERRIDE;
private:
virtual ~ContentViewRenderView();
void InitCompositor();
- bool buffers_swapped_during_composite_;
-
base::android::ScopedJavaGlobalRef<jobject> java_obj_;
scoped_ptr<LayerTreeBuildHelper> layer_tree_build_helper_;
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 2e8e882..fcd0a7b3 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -238,7 +238,14 @@ CompositorImpl::CompositorImpl(CompositorClient* client,
window_(NULL),
surface_id_(0),
client_(client),
- root_window_(root_window) {
+ root_window_(root_window),
+ did_post_swapbuffers_(false),
+ ignore_schedule_composite_(false),
+ needs_composite_(false),
+ should_composite_on_vsync_(false),
+ did_composite_this_frame_(false),
+ pending_swapbuffers_(0U),
+ weak_factory_(this) {
DCHECK(client);
DCHECK(root_window);
ImageTransportFactoryAndroid::AddObserver(this);
@@ -252,9 +259,69 @@ CompositorImpl::~CompositorImpl() {
SetSurface(NULL);
}
-void CompositorImpl::Composite() {
- if (host_)
- host_->Composite(gfx::FrameTime::Now());
+void CompositorImpl::PostComposite(base::TimeDelta delay) {
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&CompositorImpl::Composite,
+ weak_factory_.GetWeakPtr(),
+ COMPOSITE_IMMEDIATELY),
+ delay);
+}
+
+void CompositorImpl::Composite(CompositingTrigger trigger) {
+ if (!host_)
+ return;
+
+ if (!needs_composite_)
+ return;
+
+ if (trigger != COMPOSITE_ON_VSYNC && should_composite_on_vsync_) {
+ TRACE_EVENT0("compositor", "CompositorImpl_DeferCompositeToVSync");
+ root_window_->RequestVSyncUpdate();
+ return;
+ }
+
+ // Don't Composite more than once in between vsync ticks.
+ if (did_composite_this_frame_) {
+ TRACE_EVENT0("compositor", "CompositorImpl_ThrottleComposite");
+ if (should_composite_on_vsync_)
+ root_window_->RequestVSyncUpdate();
+ else
+ PostComposite(vsync_period_);
+ return;
+ }
+
+ const unsigned int kMaxSwapBuffers = 2U;
+ DCHECK_LE(pending_swapbuffers_, kMaxSwapBuffers);
+ if (pending_swapbuffers_ == kMaxSwapBuffers) {
+ TRACE_EVENT0("compositor", "CompositorImpl_SwapLimit");
+ if (should_composite_on_vsync_)
+ root_window_->RequestVSyncUpdate();
+ else
+ PostComposite(vsync_period_);
+ return;
+ }
+
+ // Reset state before Layout+Composite since that might create more
+ // requests to Composite that we need to respect.
+ needs_composite_ = false;
+ should_composite_on_vsync_ = false;
+
+ // Ignore ScheduleComposite() from layer tree changes during Layout.
+ ignore_schedule_composite_ = true;
+ client_->Layout();
+ ignore_schedule_composite_ = false;
+
+ did_post_swapbuffers_ = false;
+ host_->Composite(gfx::FrameTime::Now());
+ if (did_post_swapbuffers_)
+ pending_swapbuffers_++;
+
+ if (trigger != COMPOSITE_ON_VSYNC) {
+ // Need to track vsync to avoid compositing more than once per frame.
+ root_window_->RequestVSyncUpdate();
+ }
+ did_composite_this_frame_ = true;
}
void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) {
@@ -316,6 +383,10 @@ void CompositorImpl::SetVisible(bool visible) {
host_.reset();
client_->UIResourcesAreInvalid();
} else if (!host_) {
+ needs_composite_ = false;
+ did_composite_this_frame_ = false;
+ should_composite_on_vsync_ = false;
+ pending_swapbuffers_ = 0;
cc::LayerTreeSettings settings;
settings.refresh_rate = 60.0;
settings.impl_side_painting = false;
@@ -374,6 +445,17 @@ bool CompositorImpl::CompositeAndReadback(void *pixels, const gfx::Rect& rect) {
return false;
}
+void CompositorImpl::SetNeedsComposite() {
+ if (!host_.get() || needs_composite_)
+ return;
+
+ needs_composite_ = true;
+
+ // For explicit requests we try to composite regularly on vsync.
+ should_composite_on_vsync_ = true;
+ root_window_->RequestVSyncUpdate();
+}
+
cc::UIResourceId CompositorImpl::GenerateUIResourceFromUIResourceBitmap(
const cc::UIResourceBitmap& bitmap,
bool is_transient) {
@@ -468,6 +550,13 @@ CreateGpuProcessViewContext(
NULL));
}
+void CompositorImpl::Layout() {
+ // TODO: If we get this callback from the SingleThreadProxy, we need
+ // to stop calling it ourselves in CompositorImpl::Composite().
+ NOTREACHED();
+ client_->Layout();
+}
+
scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface(
bool fallback) {
blink::WebGraphicsContext3D::Attributes attrs;
@@ -493,12 +582,16 @@ void CompositorImpl::OnLostResources() {
client_->DidLoseResources();
}
-void CompositorImpl::DidCompleteSwapBuffers() {
- client_->OnSwapBuffersCompleted();
-}
-
void CompositorImpl::ScheduleComposite() {
- client_->ScheduleComposite();
+ if (needs_composite_ || ignore_schedule_composite_)
+ return;
+
+ needs_composite_ = true;
+
+ // We currently expect layer tree invalidations at most once per frame
+ // during normal operation and therefore try to composite immediately
+ // to minimize latency.
+ PostComposite(base::TimeDelta());
}
void CompositorImpl::ScheduleAnimation() {
@@ -507,12 +600,19 @@ void CompositorImpl::ScheduleAnimation() {
void CompositorImpl::DidPostSwapBuffers() {
TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers");
- client_->OnSwapBuffersPosted();
+ did_post_swapbuffers_ = true;
+}
+
+void CompositorImpl::DidCompleteSwapBuffers() {
+ TRACE_EVENT0("compositor", "CompositorImpl::DidCompleteSwapBuffers");
+ DCHECK_GT(pending_swapbuffers_, 0U);
+ client_->OnSwapBuffersCompleted(pending_swapbuffers_--);
}
void CompositorImpl::DidAbortSwapBuffers() {
TRACE_EVENT0("compositor", "CompositorImpl::DidAbortSwapBuffers");
- client_->OnSwapBuffersCompleted();
+ DCHECK_GT(pending_swapbuffers_, 0U);
+ client_->OnSwapBuffersCompleted(pending_swapbuffers_--);
}
void CompositorImpl::DidCommit() {
@@ -523,4 +623,13 @@ void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) {
root_layer_->AddChild(layer);
}
+void CompositorImpl::OnVSync(base::TimeTicks frame_time,
+ base::TimeDelta vsync_period) {
+ vsync_period_ = vsync_period;
+ did_composite_this_frame_ = false;
+
+ if (should_composite_on_vsync_)
+ Composite(COMPOSITE_ON_VSYNC);
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h
index 969b114..8fd65ad 100644
--- a/content/browser/renderer_host/compositor_impl_android.h
+++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "base/containers/scoped_ptr_hash_map.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "cc/resources/ui_resource_client.h"
#include "cc/trees/layer_tree_host_client.h"
#include "cc/trees/layer_tree_host_single_thread_client.h"
@@ -53,6 +54,7 @@ class CONTENT_EXPORT CompositorImpl
// Destroy all surface textures associated with |child_process_id|.
static void DestroyAllSurfaceTextures(int child_process_id);
+ private:
// Compositor implementation.
virtual void SetRootLayer(scoped_refptr<cc::Layer> root) OVERRIDE;
virtual void SetWindowSurface(ANativeWindow* window) OVERRIDE;
@@ -63,7 +65,7 @@ class CONTENT_EXPORT CompositorImpl
virtual void SetHasTransparentBackground(bool flag) OVERRIDE;
virtual bool CompositeAndReadback(
void *pixels, const gfx::Rect& rect) OVERRIDE;
- virtual void Composite() OVERRIDE;
+ virtual void SetNeedsComposite() OVERRIDE;
virtual cc::UIResourceId GenerateUIResource(const SkBitmap& bitmap,
bool is_transient) OVERRIDE;
virtual cc::UIResourceId GenerateCompressedUIResource(const gfx::Size& size,
@@ -76,7 +78,7 @@ class CONTENT_EXPORT CompositorImpl
virtual void WillBeginMainFrame(int frame_id) OVERRIDE {}
virtual void DidBeginMainFrame() OVERRIDE {}
virtual void Animate(base::TimeTicks frame_begin_time) OVERRIDE {}
- virtual void Layout() OVERRIDE {}
+ virtual void Layout() OVERRIDE;
virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
float page_scale) OVERRIDE {}
virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface(bool fallback)
@@ -98,8 +100,15 @@ class CONTENT_EXPORT CompositorImpl
// WindowAndroidCompositor implementation.
virtual void AttachLayerForReadback(scoped_refptr<cc::Layer> layer) OVERRIDE;
-
- private:
+ virtual void OnVSync(base::TimeTicks frame_time,
+ base::TimeDelta vsync_period) OVERRIDE;
+
+ void PostComposite(base::TimeDelta delay);
+ enum CompositingTrigger {
+ COMPOSITE_IMMEDIATELY,
+ COMPOSITE_ON_VSYNC
+ };
+ void Composite(CompositingTrigger trigger);
cc::UIResourceId GenerateUIResourceFromUIResourceBitmap(
const cc::UIResourceBitmap& bitmap,
bool is_transient);
@@ -122,6 +131,32 @@ class CONTENT_EXPORT CompositorImpl
gfx::NativeWindow root_window_;
+ // Used locally to track whether a call to LTH::Composite() did result in
+ // a posted SwapBuffers().
+ bool did_post_swapbuffers_;
+
+ // Used locally to inhibit ScheduleComposite() during Layout().
+ bool ignore_schedule_composite_;
+
+ // Whether we need to composite in general because of any invalidation or
+ // explicit request.
+ bool needs_composite_;
+
+ // When SetNeedsComposite() is getting called, we will try to schedule
+ // regularly during vsync.
+ bool should_composite_on_vsync_;
+
+ // Whether we composited already in the current vsync interval.
+ bool did_composite_this_frame_;
+
+ // The number of SwapBuffer calls that have not returned and ACK'd from
+ // the GPU thread.
+ unsigned int pending_swapbuffers_;
+
+ base::TimeDelta vsync_period_;
+
+ base::WeakPtrFactory<CompositorImpl> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(CompositorImpl);
};
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 0dbb0d8..a33443c 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -255,6 +255,7 @@ void RenderWidgetHostViewAndroid::WasShown() {
if (content_view_core_ && !using_synchronous_compositor_) {
content_view_core_->GetWindowAndroid()->AddObserver(this);
+ content_view_core_->GetWindowAndroid()->RequestVSyncUpdate();
observing_root_window_ = true;
}
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index 149b7862..ce58221 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -301,9 +301,6 @@ public class ContentViewCore
// because the OSK was just brought up.
private final Rect mFocusPreOSKViewportRect = new Rect();
- // Whether we received a new frame since consumePendingRendererFrame() was last called.
- private boolean mPendingRendererFrame = false;
-
// On single tap this will store the x, y coordinates of the touch.
private int mSingleTapX;
private int mSingleTapY;
@@ -880,17 +877,6 @@ public class ContentViewCore
}
/**
- * Mark any new frames that have arrived since this function was last called as non-pending.
- *
- * @return Whether there was a pending frame from the renderer.
- */
- public boolean consumePendingRendererFrame() {
- boolean hadPendingFrame = mPendingRendererFrame;
- mPendingRendererFrame = false;
- return hadPendingFrame;
- }
-
- /**
* @return Viewport width in physical pixels as set from onSizeChanged.
*/
@CalledByNative
@@ -2286,7 +2272,6 @@ public class ContentViewCore
getContentViewClient().onOffsetsForFullscreenChanged(
controlsOffsetPix, contentOffsetYPix, overdrawBottomHeightPix);
- mPendingRendererFrame = true;
if (mBrowserAccessibilityManager != null) {
mBrowserAccessibilityManager.notifyFrameInfoInitialized();
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java
index 6c11209..709d574 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java
@@ -9,7 +9,6 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PixelFormat;
-import android.os.Handler;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
@@ -17,7 +16,6 @@ import android.widget.FrameLayout;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
-import org.chromium.base.TraceEvent;
import org.chromium.ui.base.WindowAndroid;
/***
@@ -27,31 +25,16 @@ import org.chromium.ui.base.WindowAndroid;
* Note that only one ContentViewCore can be shown at a time.
*/
@JNINamespace("content")
-public class ContentViewRenderView extends FrameLayout implements WindowAndroid.VSyncClient {
- private static final int MAX_SWAP_BUFFER_COUNT = 2;
-
+public class ContentViewRenderView extends FrameLayout {
// The native side of this object.
private long mNativeContentViewRenderView;
private final SurfaceHolder.Callback mSurfaceCallback;
private final SurfaceView mSurfaceView;
- private final WindowAndroid mRootWindow;
-
- private int mPendingRenders;
- private int mPendingSwapBuffers;
- private boolean mNeedToRender;
-
protected ContentViewCore mContentViewCore;
private ContentReadbackHandler mContentReadbackHandler;
- private final Runnable mRenderRunnable = new Runnable() {
- @Override
- public void run() {
- render();
- }
- };
-
/**
* Constructs a new ContentViewRenderView that should be can to a view hierarchy.
* Native code should add/remove the layers to be rendered through the ContentViewLayerRenderer.
@@ -63,8 +46,6 @@ public class ContentViewRenderView extends FrameLayout implements WindowAndroid.
mNativeContentViewRenderView = nativeInit(rootWindow.getNativePointer());
assert mNativeContentViewRenderView != 0;
- mRootWindow = rootWindow;
- rootWindow.setVSyncClient(this);
mSurfaceView = createSurfaceView(getContext());
mSurfaceView.setZOrderMediaOverlay(true);
mSurfaceCallback = new SurfaceHolder.Callback() {
@@ -86,9 +67,6 @@ public class ContentViewRenderView extends FrameLayout implements WindowAndroid.
assert mNativeContentViewRenderView != 0;
nativeSurfaceCreated(mNativeContentViewRenderView);
- mPendingSwapBuffers = 0;
- mPendingRenders = 0;
-
onReadyToRender();
}
@@ -114,19 +92,6 @@ public class ContentViewRenderView extends FrameLayout implements WindowAndroid.
mContentReadbackHandler.initNativeContentReadbackHandler();
}
- @Override
- public void onVSync(long vsyncTimeMicros) {
- if (mNeedToRender) {
- if (mPendingSwapBuffers + mPendingRenders <= MAX_SWAP_BUFFER_COUNT) {
- mNeedToRender = false;
- mPendingRenders++;
- render();
- } else {
- TraceEvent.instant("ContentViewRenderView:bail");
- }
- }
- }
-
/**
* @return The content readback handler.
*/
@@ -153,7 +118,6 @@ public class ContentViewRenderView extends FrameLayout implements WindowAndroid.
public void destroy() {
mContentReadbackHandler.destroy();
mContentReadbackHandler = null;
- mRootWindow.setVSyncClient(null);
mSurfaceView.getHolder().removeCallback(mSurfaceCallback);
nativeDestroy(mNativeContentViewRenderView);
mNativeContentViewRenderView = 0;
@@ -226,54 +190,17 @@ public class ContentViewRenderView extends FrameLayout implements WindowAndroid.
}
@CalledByNative
- private void requestRender() {
- boolean rendererHasFrame =
- mContentViewCore != null && mContentViewCore.consumePendingRendererFrame();
-
- if (rendererHasFrame && mPendingSwapBuffers + mPendingRenders < MAX_SWAP_BUFFER_COUNT) {
- TraceEvent.instant("requestRender:now");
- mNeedToRender = false;
- mPendingRenders++;
-
- // The handler can be null if we are detached from the window. Calling
- // {@link View#post(Runnable)} properly handles this case, but we lose the front of
- // queue behavior. That is okay for this edge case.
- Handler handler = getHandler();
- if (handler != null) {
- handler.postAtFrontOfQueue(mRenderRunnable);
- } else {
- post(mRenderRunnable);
- }
- } else if (mPendingRenders <= 0) {
- assert mPendingRenders == 0;
- TraceEvent.instant("requestRender:later");
- mNeedToRender = true;
- mRootWindow.requestVSyncUpdate();
- }
+ protected void onCompositorLayout() {
}
@CalledByNative
private void onSwapBuffersCompleted() {
- TraceEvent.instant("onSwapBuffersCompleted");
-
- if (mPendingSwapBuffers == MAX_SWAP_BUFFER_COUNT && mNeedToRender) requestRender();
- if (mPendingSwapBuffers > 0) mPendingSwapBuffers--;
- }
-
- protected void render() {
- if (mPendingRenders > 0) mPendingRenders--;
-
- boolean didDraw = nativeComposite(mNativeContentViewRenderView);
- if (didDraw) {
- mPendingSwapBuffers++;
- if (mSurfaceView.getBackground() != null) {
- post(new Runnable() {
- @Override
- public void run() {
- mSurfaceView.setBackgroundResource(0);
- }
- });
- }
+ if (mSurfaceView.getBackground() != null) {
+ post(new Runnable() {
+ @Override public void run() {
+ mSurfaceView.setBackgroundResource(0);
+ }
+ });
}
}
@@ -287,7 +214,6 @@ public class ContentViewRenderView extends FrameLayout implements WindowAndroid.
private native void nativeSurfaceDestroyed(long nativeContentViewRenderView);
private native void nativeSurfaceChanged(long nativeContentViewRenderView,
int format, int width, int height, Surface surface);
- private native boolean nativeComposite(long nativeContentViewRenderView);
private native boolean nativeCompositeToBitmap(long nativeContentViewRenderView, Bitmap bitmap);
private native void nativeSetOverlayVideoMode(long nativeContentViewRenderView,
boolean enabled);
diff --git a/content/public/browser/android/compositor.h b/content/public/browser/android/compositor.h
index 7cb73e2..236a90d 100644
--- a/content/public/browser/android/compositor.h
+++ b/content/public/browser/android/compositor.h
@@ -69,8 +69,9 @@ class CONTENT_EXPORT Compositor {
// The buffer is not modified if false is returned.
virtual bool CompositeAndReadback(void *pixels, const gfx::Rect& rect) = 0;
- // Composite immediately. Used in single-threaded mode.
- virtual void Composite() = 0;
+ // Request layout and draw. You only need to call this if you need to trigger
+ // Composite *without* having modified the layer tree.
+ virtual void SetNeedsComposite() = 0;
// Generates a UIResource and returns a UIResourceId. |is_transient|
// indicates whether or not to release the resource once the bitmap
diff --git a/content/public/browser/android/compositor_client.h b/content/public/browser/android/compositor_client.h
index d835de1..09a12e5 100644
--- a/content/public/browser/android/compositor_client.h
+++ b/content/public/browser/android/compositor_client.h
@@ -11,14 +11,11 @@ namespace content {
class CONTENT_EXPORT CompositorClient {
public:
- // Tells the client that it should schedule a composite.
- virtual void ScheduleComposite() = 0;
+ // Gives the client a chance for layout changes before compositing.
+ virtual void Layout() {}
// The compositor has completed swapping a frame.
- virtual void OnSwapBuffersCompleted() {}
-
- // The compositor will eventually swap a frame.
- virtual void OnSwapBuffersPosted() {}
+ virtual void OnSwapBuffersCompleted(int pending_swap_buffers) {}
// Tells the client that GL resources were lost and need to be reinitialized.
virtual void DidLoseResources() {}
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
index 8be2dd0..4a68dea 100644
--- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -32,7 +32,6 @@ public class WindowAndroid {
// Native pointer to the c++ WindowAndroid object.
private long mNativeWindowAndroid = 0;
private final VSyncMonitor mVSyncMonitor;
- private VSyncClient mVSyncClient = null;
// A string used as a key to store intent errors in a bundle
static final String WINDOW_CALLBACK_ERRORS = "window_callback_errors";
@@ -51,9 +50,6 @@ public class WindowAndroid {
private final VSyncMonitor.Listener mVSyncListener = new VSyncMonitor.Listener() {
@Override
public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros) {
- if (mVSyncClient != null) {
- mVSyncClient.onVSync(vsyncTimeMicros);
- }
if (mNativeWindowAndroid != 0) {
nativeOnVSync(mNativeWindowAndroid, vsyncTimeMicros);
}
@@ -231,34 +227,9 @@ public class WindowAndroid {
return false;
}
- /**
- * An interface to receive VSync notifications from the window.
- * The one and only client is set with setVSyncClient(client).
- */
- public interface VSyncClient {
- /**
- * Called very soon after the start of the display's vertical sync period.
- * @param vsyncTimeMicros Absolute frame time in microseconds.
- */
- void onVSync(long vsyncTimeMicros);
- }
-
- /**
- * Sets the VSyncClient.
- * @param client The client receiving VSync notifications.
- */
- public void setVSyncClient(VSyncClient client) {
- assert mVSyncClient == null || client == null;
- mVSyncClient = client;
- }
-
- /**
- * Request a VSync callback.
- * VSyncClient.onVSync() will be called at least once.
- */
@CalledByNative
- public void requestVSyncUpdate() {
- mVSyncMonitor.requestUpdate();
+ private void requestVSyncUpdate() {
+ mVSyncMonitor.requestUpdate();
}
/**
diff --git a/ui/base/android/window_android.cc b/ui/base/android/window_android.cc
index bbacf9c..3dd3e6e 100644
--- a/ui/base/android/window_android.cc
+++ b/ui/base/android/window_android.cc
@@ -96,10 +96,13 @@ void WindowAndroid::RequestVSyncUpdate() {
}
void WindowAndroid::OnVSync(JNIEnv* env, jobject obj, jlong time_micros) {
+ base::TimeTicks frame_time(base::TimeTicks::FromInternalValue(time_micros));
FOR_EACH_OBSERVER(
WindowAndroidObserver,
observer_list_,
- OnVSync(base::TimeTicks::FromInternalValue(time_micros), vsync_period_));
+ OnVSync(frame_time, vsync_period_));
+ if (compositor_)
+ compositor_->OnVSync(frame_time, vsync_period_);
}
// ----------------------------------------------------------------------------
diff --git a/ui/base/android/window_android_compositor.h b/ui/base/android/window_android_compositor.h
index 8f219fa..1c2fefc 100644
--- a/ui/base/android/window_android_compositor.h
+++ b/ui/base/android/window_android_compositor.h
@@ -19,6 +19,8 @@ class UI_BASE_EXPORT WindowAndroidCompositor {
virtual ~WindowAndroidCompositor() {}
virtual void AttachLayerForReadback(scoped_refptr<cc::Layer> layer) = 0;
+ virtual void OnVSync(base::TimeTicks frame_time,
+ base::TimeDelta vsync_period) = 0;
};
} // namespace ui