summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkalyan.kondapally <kalyan.kondapally@intel.com>2014-12-23 18:02:02 -0800
committerCommit bot <commit-bot@chromium.org>2014-12-24 02:02:54 +0000
commitae4355c2148da9d549134da9d81d68fd1892724e (patch)
tree7f5364c9e1fb20462c73d5443b4ce8eb77932165
parent529e7f1c22bbb63fa91160b8d4fc5701c2a6415c (diff)
downloadchromium_src-ae4355c2148da9d549134da9d81d68fd1892724e.zip
chromium_src-ae4355c2148da9d549134da9d81d68fd1892724e.tar.gz
chromium_src-ae4355c2148da9d549134da9d81d68fd1892724e.tar.bz2
Add support to delay sending SwapbufferAck as needed.
On platforms (i.e. ChromeOS using Ozone) where Chromium is responsible for displaying the buffers, we want to delay SwapBufferAck till we know that the buffer is displayed on screen. Currently, we block the GPU main thread till that data is available. This patch introduces SwapBufferAsync apis, which are similar to current SwapBuffer calls except that it adds a callback function which can be used to delay sending SwapBufferAck as needed. BUG=443543,chrome-os-partner:34292 Review URL: https://codereview.chromium.org/797843005 Cr-Commit-Position: refs/heads/master@{#309602}
-rw-r--r--content/common/gpu/image_transport_surface.cc31
-rw-r--r--content/common/gpu/image_transport_surface.h2
-rw-r--r--ui/gl/gl_surface.cc28
-rw-r--r--ui/gl/gl_surface.h26
4 files changed, 75 insertions, 12 deletions
diff --git a/content/common/gpu/image_transport_surface.cc b/content/common/gpu/image_transport_surface.cc
index f0665f6..bb11dd8 100644
--- a/content/common/gpu/image_transport_surface.cc
+++ b/content/common/gpu/image_transport_surface.cc
@@ -188,7 +188,8 @@ PassThroughImageTransportSurface::PassThroughImageTransportSurface(
GpuCommandBufferStub* stub,
gfx::GLSurface* surface)
: GLSurfaceAdapter(surface),
- did_set_swap_interval_(false) {
+ did_set_swap_interval_(false),
+ weak_ptr_factory_(this) {
helper_.reset(new ImageTransportHelper(this,
manager,
stub,
@@ -214,21 +215,28 @@ bool PassThroughImageTransportSurface::SwapBuffers() {
// GetVsyncValues before SwapBuffers to work around Mali driver bug:
// crbug.com/223558.
SendVSyncUpdateIfAvailable();
- bool result = gfx::GLSurfaceAdapter::SwapBuffers();
- for (size_t i = 0; i < latency_info_.size(); i++) {
- latency_info_[i].AddLatencyNumber(
- ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0);
- }
-
- helper_->SwapBuffersCompleted(latency_info_);
- latency_info_.clear();
- return result;
+ // We use WeakPtr here to avoid manual management of life time of an instance
+ // of this class. Callback will not be called once the instance of this class
+ // is destroyed. However, this also means that the callback can be run on
+ // the calling thread only.
+ return gfx::GLSurfaceAdapter::SwapBuffersAsync(
+ base::Bind(&PassThroughImageTransportSurface::SwapBuffersCallBack,
+ weak_ptr_factory_.GetWeakPtr()));
}
bool PassThroughImageTransportSurface::PostSubBuffer(
int x, int y, int width, int height) {
SendVSyncUpdateIfAvailable();
- bool result = gfx::GLSurfaceAdapter::PostSubBuffer(x, y, width, height);
+ // We use WeakPtr here to avoid manual management of life time of an instance
+ // of this class. Callback will not be called once the instance of this class
+ // is destroyed. However, this also means that the callback can be run on
+ // the calling thread only.
+ return gfx::GLSurfaceAdapter::PostSubBufferAsync(x, y, width, height,
+ base::Bind(&PassThroughImageTransportSurface::SwapBuffersCallBack,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void PassThroughImageTransportSurface::SwapBuffersCallBack() {
for (size_t i = 0; i < latency_info_.size(); i++) {
latency_info_[i].AddLatencyNumber(
ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0);
@@ -236,7 +244,6 @@ bool PassThroughImageTransportSurface::PostSubBuffer(
helper_->SwapBuffersCompleted(latency_info_);
latency_info_.clear();
- return result;
}
bool PassThroughImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
diff --git a/content/common/gpu/image_transport_surface.h b/content/common/gpu/image_transport_surface.h
index 0c34e86..420690e 100644
--- a/content/common/gpu/image_transport_surface.h
+++ b/content/common/gpu/image_transport_surface.h
@@ -200,6 +200,7 @@ class PassThroughImageTransportSurface
// If updated vsync parameters can be determined, send this information to
// the browser.
virtual void SendVSyncUpdateIfAvailable();
+ void SwapBuffersCallBack();
ImageTransportHelper* GetHelper() { return helper_.get(); }
@@ -207,6 +208,7 @@ class PassThroughImageTransportSurface
scoped_ptr<ImageTransportHelper> helper_;
bool did_set_swap_interval_;
std::vector<ui::LatencyInfo> latency_info_;
+ base::WeakPtrFactory<PassThroughImageTransportSurface> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(PassThroughImageTransportSurface);
};
diff --git a/ui/gl/gl_surface.cc b/ui/gl/gl_surface.cc
index aaf12ac..e1369e5 100644
--- a/ui/gl/gl_surface.cc
+++ b/ui/gl/gl_surface.cc
@@ -192,10 +192,27 @@ unsigned int GLSurface::GetBackingFrameBufferObject() {
return 0;
}
+bool GLSurface::SwapBuffersAsync(const SwapCompletionCallback& callback) {
+ DCHECK(!IsSurfaceless());
+ bool success = SwapBuffers();
+ callback.Run();
+ return success;
+}
+
bool GLSurface::PostSubBuffer(int x, int y, int width, int height) {
return false;
}
+bool GLSurface::PostSubBufferAsync(int x,
+ int y,
+ int width,
+ int height,
+ const SwapCompletionCallback& callback) {
+ bool success = PostSubBuffer(x, y, width, height);
+ callback.Run();
+ return success;
+}
+
bool GLSurface::OnMakeCurrent(GLContext* context) {
return true;
}
@@ -303,10 +320,21 @@ bool GLSurfaceAdapter::SwapBuffers() {
return surface_->SwapBuffers();
}
+bool GLSurfaceAdapter::SwapBuffersAsync(
+ const SwapCompletionCallback& callback) {
+ return surface_->SwapBuffersAsync(callback);
+}
+
bool GLSurfaceAdapter::PostSubBuffer(int x, int y, int width, int height) {
return surface_->PostSubBuffer(x, y, width, height);
}
+bool GLSurfaceAdapter::PostSubBufferAsync(
+ int x, int y, int width, int height,
+ const SwapCompletionCallback& callback) {
+ return surface_->PostSubBufferAsync(x, y, width, height, callback);
+}
+
bool GLSurfaceAdapter::SupportsPostSubBuffer() {
return surface_->SupportsPostSubBuffer();
}
diff --git a/ui/gl/gl_surface.h b/ui/gl/gl_surface.h
index ec04c96..8993845 100644
--- a/ui/gl/gl_surface.h
+++ b/ui/gl/gl_surface.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "build/build_config.h"
#include "ui/gfx/native_widget_types.h"
@@ -72,9 +73,28 @@ class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> {
// FBO. Otherwise returns 0.
virtual unsigned int GetBackingFrameBufferObject();
+ typedef base::Callback<void()> SwapCompletionCallback;
+ // Swaps front and back buffers. This has no effect for off-screen
+ // contexts. On some platforms, we want to send SwapBufferAck only after the
+ // surface is displayed on screen. The callback can be used to delay sending
+ // SwapBufferAck till that data is available. The callback should be run on
+ // the calling thread (i.e. same thread SwapBuffersAsync is called)
+ virtual bool SwapBuffersAsync(const SwapCompletionCallback& callback);
+
// Copy part of the backbuffer to the frontbuffer.
virtual bool PostSubBuffer(int x, int y, int width, int height);
+ // Copy part of the backbuffer to the frontbuffer. On some platforms, we want
+ // to send SwapBufferAck only after the surface is displayed on screen. The
+ // callback can be used to delay sending SwapBufferAck till that data is
+ // available. The callback should be run on the calling thread (i.e. same
+ // thread PostSubBufferAsync is called)
+ virtual bool PostSubBufferAsync(int x,
+ int y,
+ int width,
+ int height,
+ const SwapCompletionCallback& callback);
+
// Initialize GL bindings.
static bool InitializeOneOff();
@@ -173,7 +193,13 @@ class GL_EXPORT GLSurfaceAdapter : public GLSurface {
bool DeferDraws() override;
bool IsOffscreen() override;
bool SwapBuffers() override;
+ bool SwapBuffersAsync(const SwapCompletionCallback& callback) override;
bool PostSubBuffer(int x, int y, int width, int height) override;
+ bool PostSubBufferAsync(int x,
+ int y,
+ int width,
+ int height,
+ const SwapCompletionCallback& callback) override;
bool SupportsPostSubBuffer() override;
gfx::Size GetSize() override;
void* GetHandle() override;