summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/browser_plugin/browser_plugin_guest.cc4
-rw-r--r--content/browser/gpu/gpu_process_host.cc18
-rw-r--r--content/browser/gpu/gpu_process_host_ui_shim.cc23
-rw-r--r--content/browser/renderer_host/image_transport_factory.cc108
-rw-r--r--content/browser/renderer_host/image_transport_factory.h4
-rw-r--r--content/browser/renderer_host/image_transport_factory_android.cc47
-rw-r--r--content/browser/renderer_host/image_transport_factory_android.h6
-rw-r--r--content/browser/renderer_host/render_process_host_impl.cc2
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.cc18
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.h11
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.cc61
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.h14
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc322
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.h78
-rw-r--r--content/browser/renderer_host/render_widget_host_view_gtk.cc4
-rw-r--r--content/browser/renderer_host/render_widget_host_view_guest.cc8
-rw-r--r--content/browser/renderer_host/render_widget_host_view_guest.h3
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.mm2
-rw-r--r--content/browser/renderer_host/test_render_view_host.h6
-rw-r--r--content/common/gpu/client/gl_helper.cc27
-rw-r--r--content/common/gpu/client/gl_helper.h8
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.cc2
-rw-r--r--content/common/gpu/gpu_messages.h19
-rw-r--r--content/common/gpu/image_transport_surface.cc17
-rw-r--r--content/common/gpu/image_transport_surface.h10
-rw-r--r--content/common/gpu/image_transport_surface_android.cc1
-rw-r--r--content/common/gpu/image_transport_surface_mac.cc4
-rw-r--r--content/common/gpu/image_transport_surface_win.cc5
-rw-r--r--content/common/gpu/texture_image_transport_surface.cc449
-rw-r--r--content/common/gpu/texture_image_transport_surface.h69
-rw-r--r--content/port/browser/render_widget_host_view_port.h5
-rw-r--r--gpu/command_buffer/service/mailbox_manager.cc13
-rw-r--r--gpu/command_buffer/service/mailbox_manager.h3
-rw-r--r--gpu/command_buffer/service/texture_definition.cc12
-rw-r--r--gpu/command_buffer/service/texture_definition.h4
-rw-r--r--ui/compositor/compositor.cc4
-rw-r--r--ui/compositor/compositor.h5
-rw-r--r--ui/gfx/native_widget_types.h15
38 files changed, 712 insertions, 699 deletions
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
index fc1f4bf..f0e8326 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -363,10 +363,6 @@ void BrowserPluginGuest::SetCompositingBufferData(int gpu_process_id,
surface_handle_ = gfx::GLSurfaceHandle(gfx::kNullPluginWindow, true);
surface_handle_.parent_gpu_process_id = gpu_process_id;
surface_handle_.parent_client_id = client_id;
- surface_handle_.parent_context_id = context_id;
- surface_handle_.parent_texture_id[0] = texture_id_0;
- surface_handle_.parent_texture_id[1] = texture_id_1;
- surface_handle_.sync_point = sync_point;
}
bool BrowserPluginGuest::InAutoSizeBounds(const gfx::Size& size) const {
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 633f6d3..ac85420 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -100,7 +100,7 @@ void SendGpuProcessMessage(GpuProcessHost::GpuProcessKind kind,
void AcceleratedSurfaceBuffersSwappedCompletedForGPU(int host_id,
int route_id,
bool alive,
- bool did_swap) {
+ uint64 surface_handle) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO,
@@ -109,7 +109,7 @@ void AcceleratedSurfaceBuffersSwappedCompletedForGPU(int host_id,
host_id,
route_id,
alive,
- did_swap));
+ surface_handle));
return;
}
@@ -117,7 +117,7 @@ void AcceleratedSurfaceBuffersSwappedCompletedForGPU(int host_id,
if (host) {
if (alive)
host->Send(new AcceleratedSurfaceMsg_BufferPresented(
- route_id, did_swap, 0));
+ route_id, surface_handle, 0));
else
host->ForceShutdown();
}
@@ -159,11 +159,12 @@ void AcceleratedSurfaceBuffersSwappedCompletedForRenderer(
void AcceleratedSurfaceBuffersSwappedCompleted(int host_id,
int route_id,
int surface_id,
+ uint64 surface_handle,
bool alive,
base::TimeTicks timebase,
base::TimeDelta interval) {
AcceleratedSurfaceBuffersSwappedCompletedForGPU(host_id, route_id,
- alive, true /* presented */);
+ alive, surface_handle);
AcceleratedSurfaceBuffersSwappedCompletedForRenderer(surface_id, timebase,
interval);
}
@@ -762,7 +763,7 @@ void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped(
base::ScopedClosureRunner scoped_completion_runner(
base::Bind(&AcceleratedSurfaceBuffersSwappedCompletedForGPU,
host_id_, params.route_id,
- true /* alive */, false /* presented */));
+ true /* alive */, params.surface_handle));
int render_process_id = 0;
int render_widget_id = 0;
@@ -797,8 +798,8 @@ void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped(
base::ScopedClosureRunner scoped_completion_runner(
base::Bind(&AcceleratedSurfaceBuffersSwappedCompleted,
- host_id_, params.route_id, params.surface_id,
- true, base::TimeTicks(), base::TimeDelta()));
+ host_id_, params.route_id, params.surface_id, params.surface_handle,
+ true, base::TimeTicks(), base::TimeDelta()));
gfx::PluginWindowHandle handle =
GpuSurfaceTracker::Get()->GetSurfaceWindowHandle(params.surface_id);
@@ -830,7 +831,8 @@ void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped(
base::Bind(&AcceleratedSurfaceBuffersSwappedCompleted,
host_id_,
params.route_id,
- params.surface_id));
+ params.surface_id,
+ params.surface_handle));
}
void GpuProcessHost::OnAcceleratedSurfacePostSubBuffer(
diff --git a/content/browser/gpu/gpu_process_host_ui_shim.cc b/content/browser/gpu/gpu_process_host_ui_shim.cc
index 4a991e0..d1f35dd 100644
--- a/content/browser/gpu/gpu_process_host_ui_shim.cc
+++ b/content/browser/gpu/gpu_process_host_ui_shim.cc
@@ -31,6 +31,11 @@
#include <gdk/gdkx.h> // NOLINT
#endif
+// From gl2/gl2ext.h.
+#ifndef GL_MAILBOX_SIZE_CHROMIUM
+#define GL_MAILBOX_SIZE_CHROMIUM 64
+#endif
+
namespace content {
namespace {
@@ -302,8 +307,14 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceNew(
params.surface_id);
if (!view)
return;
+
+ if (params.mailbox_name.length() &&
+ params.mailbox_name.length() != GL_MAILBOX_SIZE_CHROMIUM)
+ return;
+
view->AcceleratedSurfaceNew(
- params.width, params.height, params.surface_handle);
+ params.width, params.height, params.surface_handle,
+ params.mailbox_name);
}
static base::TimeDelta GetSwapDelay() {
@@ -323,7 +334,9 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped(
ScopedSendOnIOThread delayed_send(
host_id_,
- new AcceleratedSurfaceMsg_BufferPresented(params.route_id, false, 0));
+ new AcceleratedSurfaceMsg_BufferPresented(params.route_id,
+ params.surface_handle,
+ 0));
RenderWidgetHostViewPort* view = GetRenderWidgetHostViewFromSurfaceID(
params.surface_id);
@@ -347,7 +360,9 @@ void GpuProcessHostUIShim::OnAcceleratedSurfacePostSubBuffer(
ScopedSendOnIOThread delayed_send(
host_id_,
- new AcceleratedSurfaceMsg_BufferPresented(params.route_id, false, 0));
+ new AcceleratedSurfaceMsg_BufferPresented(params.route_id,
+ params.surface_handle,
+ 0));
RenderWidgetHostViewPort* view =
GetRenderWidgetHostViewFromSurfaceID(params.surface_id);
@@ -378,7 +393,7 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceRelease(
params.surface_id);
if (!view)
return;
- view->AcceleratedSurfaceRelease(params.identifier);
+ view->AcceleratedSurfaceRelease();
}
void GpuProcessHostUIShim::OnVideoMemoryUsageStatsReceived(
diff --git a/content/browser/renderer_host/image_transport_factory.cc b/content/browser/renderer_host/image_transport_factory.cc
index 7e3e6e3..0a1dc2c 100644
--- a/content/browser/renderer_host/image_transport_factory.cc
+++ b/content/browser/renderer_host/image_transport_factory.cc
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "base/threading/non_thread_safe.h"
#include "cc/output_surface.h"
@@ -27,6 +28,8 @@
#include "content/public/common/content_switches.h"
#include "gpu/ipc/command_buffer_proxy.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebGraphicsContext3D.h"
+#include "third_party/khronos/GLES2/gl2.h"
+#include "third_party/khronos/GLES2/gl2ext.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/compositor_setup.h"
#include "ui/compositor/test_web_graphics_context_3d.h"
@@ -65,7 +68,7 @@ class DefaultTransportFactory
virtual scoped_refptr<ui::Texture> CreateTransportClient(
const gfx::Size& size,
float device_scale_factor,
- uint64 transport_handle) OVERRIDE {
+ const std::string& mailbox_name) OVERRIDE {
return NULL;
}
@@ -97,40 +100,6 @@ class DefaultTransportFactory
DISALLOW_COPY_AND_ASSIGN(DefaultTransportFactory);
};
-class ImageTransportClientTexture : public ui::Texture {
- public:
- ImageTransportClientTexture(
- WebKit::WebGraphicsContext3D* host_context,
- const gfx::Size& size,
- float device_scale_factor,
- uint64 surface_id)
- : ui::Texture(true, size, device_scale_factor),
- host_context_(host_context),
- texture_id_(surface_id) {
- }
-
- // ui::Texture overrides:
- virtual unsigned int PrepareTexture() OVERRIDE {
- return texture_id_;
- }
-
- virtual WebKit::WebGraphicsContext3D* HostContext3D() OVERRIDE {
- return host_context_;
- }
-
- protected:
- virtual ~ImageTransportClientTexture() {}
-
- private:
- // A raw pointer. This |ImageTransportClientTexture| will be destroyed
- // before the |host_context_| via
- // |ImageTransportFactoryObserver::OnLostContext()| handlers.
- WebKit::WebGraphicsContext3D* host_context_;
- unsigned texture_id_;
-
- DISALLOW_COPY_AND_ASSIGN(ImageTransportClientTexture);
-};
-
class OwnedTexture : public ui::Texture, ImageTransportFactoryObserver {
public:
OwnedTexture(WebKit::WebGraphicsContext3D* host_context,
@@ -163,7 +132,7 @@ class OwnedTexture : public ui::Texture, ImageTransportFactoryObserver {
DeleteTexture();
}
- private:
+ protected:
void DeleteTexture() {
if (texture_id_) {
host_context_->deleteTexture(texture_id_);
@@ -180,6 +149,53 @@ class OwnedTexture : public ui::Texture, ImageTransportFactoryObserver {
DISALLOW_COPY_AND_ASSIGN(OwnedTexture);
};
+class ImageTransportClientTexture : public OwnedTexture {
+ public:
+ ImageTransportClientTexture(
+ WebKit::WebGraphicsContext3D* host_context,
+ const gfx::Size& size,
+ float device_scale_factor,
+ const std::string& mailbox_name)
+ : OwnedTexture(host_context,
+ size,
+ device_scale_factor,
+ host_context->createTexture()),
+ mailbox_name_(mailbox_name) {
+ DCHECK(mailbox_name.size() == GL_MAILBOX_SIZE_CHROMIUM);
+ }
+
+ virtual void Consume(const gfx::Size& new_size) OVERRIDE {
+ if (!mailbox_name_.length())
+ return;
+
+ DCHECK(host_context_ && texture_id_);
+ host_context_->bindTexture(GL_TEXTURE_2D, texture_id_);
+ host_context_->consumeTextureCHROMIUM(
+ GL_TEXTURE_2D,
+ reinterpret_cast<const signed char*>(mailbox_name_.c_str()));
+ size_ = new_size;
+ host_context_->flush();
+ }
+
+ virtual void Produce() OVERRIDE {
+ if (!mailbox_name_.length())
+ return;
+
+ DCHECK(host_context_ && texture_id_);
+ host_context_->bindTexture(GL_TEXTURE_2D, texture_id_);
+ host_context_->produceTextureCHROMIUM(
+ GL_TEXTURE_2D,
+ reinterpret_cast<const signed char*>(mailbox_name_.c_str()));
+ }
+
+ protected:
+ virtual ~ImageTransportClientTexture() {}
+
+ private:
+ std::string mailbox_name_;
+ DISALLOW_COPY_AND_ASSIGN(ImageTransportClientTexture);
+};
+
class GpuProcessTransportFactory;
class CompositorSwapClient
@@ -409,40 +425,24 @@ class GpuProcessTransportFactory :
gfx::kNullPluginWindow, true);
handle.parent_gpu_process_id = shared_context_->GetGPUProcessID();
handle.parent_client_id = shared_context_->GetChannelID();
- handle.parent_context_id = shared_context_->GetContextID();
- handle.parent_texture_id[0] = shared_context_->createTexture();
- handle.parent_texture_id[1] = shared_context_->createTexture();
- handle.sync_point = shared_context_->insertSyncPoint();
return handle;
}
virtual void DestroySharedSurfaceHandle(
gfx::GLSurfaceHandle surface) OVERRIDE {
- if (!shared_context_.get())
- return;
- uint32 channel_id = shared_context_->GetChannelID();
- uint32 context_id = shared_context_->GetContextID();
- if (surface.parent_gpu_process_id != shared_context_->GetGPUProcessID() ||
- surface.parent_client_id != channel_id ||
- surface.parent_context_id != context_id)
- return;
-
- shared_context_->deleteTexture(surface.parent_texture_id[0]);
- shared_context_->deleteTexture(surface.parent_texture_id[1]);
- shared_context_->flush();
}
virtual scoped_refptr<ui::Texture> CreateTransportClient(
const gfx::Size& size,
float device_scale_factor,
- uint64 transport_handle) {
+ const std::string& mailbox_name) {
if (!shared_context_.get())
return NULL;
scoped_refptr<ImageTransportClientTexture> image(
new ImageTransportClientTexture(shared_context_.get(),
size, device_scale_factor,
- transport_handle));
+ mailbox_name));
return image;
}
diff --git a/content/browser/renderer_host/image_transport_factory.h b/content/browser/renderer_host/image_transport_factory.h
index 415f9e5..f081e20 100644
--- a/content/browser/renderer_host/image_transport_factory.h
+++ b/content/browser/renderer_host/image_transport_factory.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_IMAGE_TRANSPORT_FACTORY_H_
#define CONTENT_BROWSER_RENDERER_HOST_IMAGE_TRANSPORT_FACTORY_H_
+#include <string>
+
#include "base/memory/ref_counted.h"
#include "ui/gfx/native_widget_types.h"
@@ -73,7 +75,7 @@ class ImageTransportFactory {
virtual scoped_refptr<ui::Texture> CreateTransportClient(
const gfx::Size& size,
float device_scale_factor,
- uint64 transport_handle) = 0;
+ const std::string& mailbox_name) = 0;
// Variant of CreateTransportClient() that deletes the texture on the GPU when
// the returned value is deleted.
diff --git a/content/browser/renderer_host/image_transport_factory_android.cc b/content/browser/renderer_host/image_transport_factory_android.cc
index a2b8f10..558e485 100644
--- a/content/browser/renderer_host/image_transport_factory_android.cc
+++ b/content/browser/renderer_host/image_transport_factory_android.cc
@@ -11,6 +11,7 @@
#include "content/common/gpu/client/gl_helper.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
+#include "third_party/khronos/GLES2/gl2.h"
#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"
namespace content {
@@ -30,6 +31,16 @@ class DirectGLImageTransportFactory : public ImageTransportFactoryAndroid {
virtual void DestroySharedSurfaceHandle(
const gfx::GLSurfaceHandle& handle) OVERRIDE {}
virtual uint32_t InsertSyncPoint() OVERRIDE { return 0; }
+ virtual uint32_t CreateTexture() OVERRIDE {
+ return context_->createTexture();
+ }
+ virtual void DeleteTexture(uint32_t id) OVERRIDE {
+ context_->deleteTexture(id);
+ }
+ virtual void AcquireTexture(
+ uint32 texture_id, const signed char* mailbox_name) OVERRIDE {}
+ virtual void ReleaseTexture(
+ uint32 texture_id, const signed char* mailbox_name) OVERRIDE {}
virtual WebKit::WebGraphicsContext3D* GetContext3D() OVERRIDE {
return context_.get();
}
@@ -64,6 +75,12 @@ class CmdBufferImageTransportFactory : public ImageTransportFactoryAndroid {
virtual void DestroySharedSurfaceHandle(
const gfx::GLSurfaceHandle& handle) OVERRIDE;
virtual uint32_t InsertSyncPoint() OVERRIDE;
+ virtual uint32_t CreateTexture() OVERRIDE;
+ virtual void DeleteTexture(uint32_t id) OVERRIDE;
+ virtual void AcquireTexture(
+ uint32 texture_id, const signed char* mailbox_name) OVERRIDE;
+ virtual void ReleaseTexture(
+ uint32 texture_id, const signed char* mailbox_name) OVERRIDE;
virtual WebKit::WebGraphicsContext3D* GetContext3D() OVERRIDE {
return context_.get();
}
@@ -105,11 +122,6 @@ CmdBufferImageTransportFactory::CreateSharedSurfaceHandle() {
gfx::GLSurfaceHandle handle = gfx::GLSurfaceHandle(
gfx::kNullPluginWindow, true);
handle.parent_gpu_process_id = context_->GetGPUProcessID();
- handle.parent_client_id = context_->GetChannelID();
- handle.parent_context_id = context_->GetContextID();
- handle.parent_texture_id[0] = context_->createTexture();
- handle.parent_texture_id[1] = context_->createTexture();
- handle.sync_point = context_->insertSyncPoint();
context_->flush();
return handle;
}
@@ -120,16 +132,33 @@ void CmdBufferImageTransportFactory::DestroySharedSurfaceHandle(
NOTREACHED() << "Failed to make shared graphics context current";
return;
}
-
- context_->deleteTexture(handle.parent_texture_id[0]);
- context_->deleteTexture(handle.parent_texture_id[1]);
- context_->finish();
}
uint32_t CmdBufferImageTransportFactory::InsertSyncPoint() {
return context_->insertSyncPoint();
}
+uint32_t CmdBufferImageTransportFactory::CreateTexture() {
+ return context_->createTexture();
+}
+
+void CmdBufferImageTransportFactory::DeleteTexture(uint32_t id) {
+ context_->deleteTexture(id);
+}
+
+void CmdBufferImageTransportFactory::AcquireTexture(
+ uint32 texture_id, const signed char* mailbox_name) {
+ context_->bindTexture(GL_TEXTURE_2D, texture_id);
+ context_->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox_name);
+ context_->flush();
+}
+
+void CmdBufferImageTransportFactory::ReleaseTexture(
+ uint32 texture_id, const signed char* mailbox_name) {
+ context_->bindTexture(GL_TEXTURE_2D, texture_id);
+ context_->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox_name);
+}
+
GLHelper* CmdBufferImageTransportFactory::GetGLHelper() {
if (!gl_helper_.get())
gl_helper_.reset(new GLHelper(GetContext3D(), NULL));
diff --git a/content/browser/renderer_host/image_transport_factory_android.h b/content/browser/renderer_host/image_transport_factory_android.h
index 669d516..57fc5f6 100644
--- a/content/browser/renderer_host/image_transport_factory_android.h
+++ b/content/browser/renderer_host/image_transport_factory_android.h
@@ -30,6 +30,12 @@ class ImageTransportFactoryAndroid {
const gfx::GLSurfaceHandle& handle) = 0;
virtual uint32_t InsertSyncPoint() = 0;
+ virtual uint32_t CreateTexture() = 0;
+ virtual void DeleteTexture(uint32_t id) = 0;
+ virtual void AcquireTexture(
+ uint32 texture_id, const signed char* mailbox_name) = 0;
+ virtual void ReleaseTexture(
+ uint32 texture_id, const signed char* mailbox_name) = 0;
virtual WebKit::WebGraphicsContext3D* GetContext3D() = 0;
virtual GLHelper* GetGLHelper() = 0;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index b943bde..d50a905 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1590,7 +1590,7 @@ void RenderProcessHostImpl::OnCompositorSurfaceBuffersSwappedNoHost(
"RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost");
RenderWidgetHostImpl::AcknowledgeBufferPresent(route_id,
gpu_process_host_id,
- false,
+ surface_handle,
0);
}
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 45a1cf1..9ada9e8 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1512,7 +1512,7 @@ void RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwapped(
if (!view_) {
RenderWidgetHostImpl::AcknowledgeBufferPresent(route_id,
gpu_process_host_id,
- false,
+ surface_handle,
0);
return;
}
@@ -2292,11 +2292,11 @@ bool RenderWidgetHostImpl::GotResponseToLockMouseRequest(bool allowed) {
// static
void RenderWidgetHostImpl::AcknowledgeBufferPresent(
- int32 route_id, int gpu_host_id, bool presented, uint32 sync_point) {
+ int32 route_id, int gpu_host_id, uint64 surface_handle, uint32 sync_point) {
GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(gpu_host_id);
if (ui_shim)
ui_shim->Send(new AcceleratedSurfaceMsg_BufferPresented(route_id,
- presented,
+ surface_handle,
sync_point));
}
@@ -2319,18 +2319,6 @@ void RenderWidgetHostImpl::ParentChanged(gfx::NativeViewId new_parent) {
#endif
}
-// static
-void RenderWidgetHostImpl::SendFrontSurfaceIsProtected(
- bool is_protected,
- uint32 protection_state_id,
- int32 route_id,
- int gpu_host_id) {
- GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(gpu_host_id);
- if (ui_shim) {
- ui_shim->Send(new AcceleratedSurfaceMsg_SetFrontSurfaceIsProtected(
- route_id, is_protected, protection_state_id));
- }
-}
#endif
void RenderWidgetHostImpl::DelayedAutoResized() {
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 228789d..7c335f4 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -397,7 +397,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
static void AcknowledgeBufferPresent(
int32 route_id,
int gpu_host_id,
- bool presented,
+ uint64 surface_handle,
uint32 sync_point);
// Called by the view in response to AcceleratedSurfaceBuffersSwapped for
@@ -410,15 +410,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
// Called by the view when the parent changes. If a parent isn't available,
// NULL is used.
void ParentChanged(gfx::NativeViewId new_parent);
-
- // Called by the view in response to visibility changes:
- // 1. After the front surface is guarenteed to no longer be in use by the ui
- // (protected false),
- // 2. When the ui expects to have a valid front surface (protected true).
- static void SendFrontSurfaceIsProtected(bool is_protected,
- uint32 protection_state_id,
- int32 route_id,
- int gpu_host_id);
#endif
// Signals that the compositing surface was updated, e.g. after a lost context
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 e37df9c..b912373 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -56,7 +56,8 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
content_view_core_(NULL),
ime_adapter_android_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
cached_background_color_(SK_ColorWHITE),
- texture_id_in_layer_(0) {
+ texture_id_in_layer_(0),
+ current_buffer_id_(0) {
if (CompositorImpl::UsesDirectGL()) {
surface_texture_transport_.reset(new SurfaceTextureTransportClient());
layer_ = surface_texture_transport_->Initialize();
@@ -78,6 +79,10 @@ RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
ImageTransportFactoryAndroid::GetInstance()->DestroySharedSurfaceHandle(
shared_surface_);
}
+ if (texture_id_in_layer_) {
+ ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
+ texture_id_in_layer_);
+ }
}
void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
@@ -388,19 +393,42 @@ void RenderWidgetHostViewAndroid::OnAcceleratedCompositingStateChange() {
void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
int gpu_host_id) {
- texture_layer_->setTextureId(params.surface_handle);
- DCHECK(texture_layer_ == layer_);
- layer_->setBounds(params.size);
- texture_id_in_layer_ = params.surface_handle;
- texture_size_in_layer_ = params.size;
+ ImageTransportFactoryAndroid* factory =
+ ImageTransportFactoryAndroid::GetInstance();
// TODO(sievers): When running the impl thread in the browser we
- // need to delay the ACK until after commit.
+ // need to delay the ACK until after commit and use more than a single
+ // texture.
DCHECK(!CompositorImpl::IsThreadingEnabled());
+
+ uint64 previous_buffer = current_buffer_id_;
+ if (previous_buffer && texture_id_in_layer_) {
+ DCHECK(id_to_mailbox_.find(previous_buffer) != id_to_mailbox_.end());
+ ImageTransportFactoryAndroid::GetInstance()->ReleaseTexture(
+ texture_id_in_layer_,
+ reinterpret_cast<const signed char*>(
+ id_to_mailbox_[previous_buffer].c_str()));
+ }
+
+ current_buffer_id_ = params.surface_handle;
+ if (!texture_id_in_layer_) {
+ texture_id_in_layer_ = factory->CreateTexture();
+ texture_layer_->setTextureId(texture_id_in_layer_);
+ }
+
+ DCHECK(id_to_mailbox_.find(current_buffer_id_) != id_to_mailbox_.end());
+ ImageTransportFactoryAndroid::GetInstance()->AcquireTexture(
+ texture_id_in_layer_,
+ reinterpret_cast<const signed char*>(
+ id_to_mailbox_[current_buffer_id_].c_str()));
+ texture_layer_->setNeedsDisplay();
+ texture_layer_->setBounds(params.size);
+ texture_size_in_layer_ = params.size;
+
uint32 sync_point =
ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint();
RenderWidgetHostImpl::AcknowledgeBufferPresent(
- params.route_id, gpu_host_id, true, sync_point);
+ params.route_id, gpu_host_id, previous_buffer, sync_point);
}
void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
@@ -413,6 +441,23 @@ void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
NOTREACHED();
}
+void RenderWidgetHostViewAndroid::AcceleratedSurfaceNew(
+ int32 width_in_pixel, int32 height_in_pixel, uint64 surface_id,
+ const std::string& mailbox_name) {
+ DCHECK(surface_id == 1 || surface_id == 2);
+ id_to_mailbox_[surface_id] = mailbox_name;
+}
+
+void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
+ // This tells us we should free the frontbuffer.
+ if (texture_id_in_layer_) {
+ texture_layer_->setTextureId(0);
+ ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
+ texture_id_in_layer_);
+ texture_id_in_layer_ = 0;
+ }
+}
+
bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
const gfx::Size& desired_size) {
NOTREACHED();
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index 9c950af..967dadf 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_ANDROID_H_
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_ANDROID_H_
+#include <map>
+
#include "base/compiler_specific.h"
#include "base/i18n/rtl.h"
#include "base/memory/scoped_ptr.h"
@@ -101,6 +103,12 @@ class RenderWidgetHostViewAndroid : public RenderWidgetHostViewBase {
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
int gpu_host_id) OVERRIDE;
virtual void AcceleratedSurfaceSuspend() OVERRIDE;
+ virtual void AcceleratedSurfaceNew(
+ int32 width_in_pixel,
+ int32 height_in_pixel,
+ uint64 surface_id,
+ const std::string& mailbox_name) OVERRIDE;
+ virtual void AcceleratedSurfaceRelease() OVERRIDE;
virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) OVERRIDE;
virtual void SetBackground(const SkBitmap& background) OVERRIDE;
virtual void CopyFromCompositingSurface(
@@ -193,6 +201,12 @@ class RenderWidgetHostViewAndroid : public RenderWidgetHostViewBase {
// Used for image transport when needing to share resources across threads.
scoped_ptr<SurfaceTextureTransportClient> surface_texture_transport_;
+ typedef std::map<uint64, std::string> MailboxMap;
+ MailboxMap id_to_mailbox_;
+
+ // The identifier of the previously received frame
+ uint64 current_buffer_id_;
+
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAndroid);
};
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index ea0a015..f244484 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -47,7 +47,6 @@
#include "ui/base/hit_test.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/ui_base_types.h"
-#include "ui/compositor/compositor.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/display.h"
@@ -59,6 +58,9 @@
#include "ui/base/win/hidden_window.h"
#endif
+using gfx::RectToSkIRect;
+using gfx::SkIRectToRect;
+
using WebKit::WebScreenInfo;
using WebKit::WebTouchEvent;
@@ -275,6 +277,18 @@ class RenderWidgetHostViewAura::ResizeLock {
DISALLOW_COPY_AND_ASSIGN(ResizeLock);
};
+RenderWidgetHostViewAura::BufferPresentedParams::BufferPresentedParams(
+ int route_id,
+ int gpu_host_id,
+ uint64 surface_handle)
+ : route_id(route_id),
+ gpu_host_id(gpu_host_id),
+ surface_handle(surface_handle) {
+}
+
+RenderWidgetHostViewAura::BufferPresentedParams::~BufferPresentedParams() {
+}
+
////////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewAura, public:
@@ -291,10 +305,6 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host)
has_composition_text_(false),
device_scale_factor_(1.0f),
current_surface_(0),
- current_surface_is_protected_(true),
- current_surface_in_use_by_compositor_(true),
- protection_state_id_(0),
- surface_route_id_(0),
paint_canvas_(NULL),
synthetic_move_sent_(false),
accelerated_compositing_state_changed_(false),
@@ -395,8 +405,6 @@ void RenderWidgetHostViewAura::WasShown() {
released_front_lock_ = GetCompositor()->GetCompositorLock();
}
- AdjustSurfaceProtection();
-
#if defined(OS_WIN)
LPARAM lparam = reinterpret_cast<LPARAM>(this);
EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam);
@@ -410,14 +418,6 @@ void RenderWidgetHostViewAura::WasHidden() {
released_front_lock_ = NULL;
- if (ShouldReleaseFrontSurface() &&
- host_->is_accelerated_compositing_active()) {
- current_surface_ = 0;
- UpdateExternalTexture();
- }
-
- AdjustSurfaceProtection();
-
#if defined(OS_WIN)
aura::RootWindow* root_window = window_->GetRootWindow();
if (root_window) {
@@ -725,7 +725,7 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurface(
output->GetBitmap().getPixels());
scoped_callback_runner.Release();
// Wrap the callback with an internal handler so that we can inject our
- // own completion handlers (where we can call AdjustSurfaceProtection).
+ // own completion handlers (where we can try to free the frontbuffer).
base::Callback<void(bool)> wrapper_callback = base::Bind(
&RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished,
AsWeakPtr(),
@@ -758,16 +758,13 @@ void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() {
accelerated_compositing_state_changed_ = true;
}
-bool RenderWidgetHostViewAura::ShouldFastACK(uint64 surface_id) {
- ui::Texture* container = image_transport_clients_[surface_id];
- DCHECK(container);
-
+bool RenderWidgetHostViewAura::ShouldSkipFrame(const gfx::Size& size) {
if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
can_lock_compositor_ == NO_PENDING_COMMIT ||
resize_locks_.empty())
return false;
- gfx::Size container_size = ConvertSizeToDIP(this, container->size());
+ gfx::Size container_size = ConvertSizeToDIP(this, size);
ResizeLockList::iterator it = resize_locks_.begin();
while (it != resize_locks_.end()) {
if ((*it)->expected_size() == container_size)
@@ -790,7 +787,6 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() {
if (current_surface_ != 0 && host_->is_accelerated_compositing_active()) {
ui::Texture* container = image_transport_clients_[current_surface_];
window_->SetExternalTexture(container);
- current_surface_in_use_by_compositor_ = true;
if (!container) {
resize_locks_.clear();
@@ -826,120 +822,132 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() {
}
} else {
window_->SetExternalTexture(NULL);
- if (ShouldReleaseFrontSurface() &&
- host_->is_accelerated_compositing_active()) {
- // We need to wait for a commit to clear to guarantee that all we
- // will not issue any more GL referencing the previous surface.
- ui::Compositor* compositor = GetCompositor();
- if (compositor) {
- can_lock_compositor_ = NO_PENDING_COMMIT;
- on_compositing_did_commit_callbacks_.push_back(
- base::Bind(&RenderWidgetHostViewAura::
- SetSurfaceNotInUseByCompositor,
- AsWeakPtr()));
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
- }
- }
resize_locks_.clear();
}
}
-void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
- const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel,
- int gpu_host_id) {
- surface_route_id_ = params_in_pixel.route_id;
- // If protection state changed, then this swap is stale. We must still ACK but
- // do not update current_surface_ since it may have been discarded.
- if (params_in_pixel.protection_state_id &&
- params_in_pixel.protection_state_id != protection_state_id_) {
- DCHECK(!current_surface_);
- if (!params_in_pixel.skip_ack)
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL);
- return;
+bool RenderWidgetHostViewAura::SwapBuffersPrepare(
+ const gfx::Rect& surface_rect,
+ const gfx::Rect& damage_rect,
+ BufferPresentedParams* params) {
+ DCHECK(params->surface_handle);
+ DCHECK(!params->texture_to_produce);
+
+ if (last_swapped_surface_size_ != surface_rect.size()) {
+ // The surface could have shrunk since we skipped an update, in which
+ // case we can expect a full update.
+ DLOG_IF(ERROR, damage_rect != surface_rect) << "Expected full damage rect";
+ skipped_damage_.setEmpty();
+ last_swapped_surface_size_ = surface_rect.size();
}
- if (ShouldFastACK(params_in_pixel.surface_handle)) {
- if (!params_in_pixel.skip_ack)
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL);
- return;
+ if (ShouldSkipFrame(surface_rect.size())) {
+ skipped_damage_.op(RectToSkIRect(damage_rect), SkRegion::kUnion_Op);
+ InsertSyncPointAndACK(*params);
+ return false;
}
- current_surface_ = params_in_pixel.surface_handle;
- // If we don't require an ACK that means the content is not a fresh updated
- // new frame, rather we are just resetting our handle to some old content
- // that we still hadn't discarded. Although we could display immediately,
- // by not resetting the compositor lock here, we give us some time to get
- // a fresh frame which means fewer content flashes.
- if (!params_in_pixel.skip_ack)
- released_front_lock_ = NULL;
+ DCHECK(!current_surface_ || image_transport_clients_.find(current_surface_) !=
+ image_transport_clients_.end());
+ if (current_surface_)
+ params->texture_to_produce = image_transport_clients_[current_surface_];
+
+ std::swap(current_surface_, params->surface_handle);
+ DCHECK(image_transport_clients_.find(current_surface_) !=
+ image_transport_clients_.end());
+
+ image_transport_clients_[current_surface_]->Consume(surface_rect.size());
+ released_front_lock_ = NULL;
UpdateExternalTexture();
+ return true;
+}
+
+void RenderWidgetHostViewAura::SwapBuffersCompleted(
+ const BufferPresentedParams& params) {
ui::Compositor* compositor = GetCompositor();
if (!compositor) {
- if (!params_in_pixel.skip_ack)
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, true, NULL);
+ InsertSyncPointAndACK(params);
} else {
- DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) !=
- image_transport_clients_.end());
- gfx::Size surface_size_in_pixel =
- image_transport_clients_[params_in_pixel.surface_handle]->size();
- gfx::Size surface_size = ConvertSizeToDIP(this, surface_size_in_pixel);
- window_->SchedulePaintInRect(gfx::Rect(surface_size));
+ // Add sending an ACK to the list of things to do OnCompositingDidCommit
+ can_lock_compositor_ = NO_PENDING_COMMIT;
+ on_compositing_did_commit_callbacks_.push_back(
+ base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, params));
+ if (!compositor->HasObserver(this))
+ compositor->AddObserver(this);
+ }
+}
- if (!params_in_pixel.skip_ack) {
- // Add sending an ACK to the list of things to do OnCompositingDidCommit
- can_lock_compositor_ = NO_PENDING_COMMIT;
- on_compositing_did_commit_callbacks_.push_back(
- base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK,
- params_in_pixel.route_id,
- gpu_host_id,
- true));
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
- }
+void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
+ const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel,
+ int gpu_host_id) {
+ const gfx::Rect surface_rect = gfx::Rect(gfx::Point(), params_in_pixel.size);
+ BufferPresentedParams ack_params(
+ params_in_pixel.route_id, gpu_host_id, params_in_pixel.surface_handle);
+ if (!SwapBuffersPrepare(surface_rect, surface_rect, &ack_params))
+ return;
+
+ previous_damage_.setRect(RectToSkIRect(surface_rect));
+ skipped_damage_.setEmpty();
+
+ ui::Compositor* compositor = GetCompositor();
+ if (compositor) {
+ gfx::Size surface_size = ConvertSizeToDIP(this, params_in_pixel.size);
+ window_->SchedulePaintInRect(gfx::Rect(surface_size));
}
+
+ SwapBuffersCompleted(ack_params);
}
void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel,
int gpu_host_id) {
- surface_route_id_ = params_in_pixel.route_id;
- // If visible state changed, then this PSB is stale. We must still ACK but
- // do not update current_surface_.
- if (params_in_pixel.protection_state_id &&
- params_in_pixel.protection_state_id != protection_state_id_) {
- DCHECK(!current_surface_);
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL);
+ const gfx::Rect surface_rect =
+ gfx::Rect(gfx::Point(), params_in_pixel.surface_size);
+ gfx::Rect damage_rect(params_in_pixel.x,
+ params_in_pixel.y,
+ params_in_pixel.width,
+ params_in_pixel.height);
+ BufferPresentedParams ack_params(
+ params_in_pixel.route_id, gpu_host_id, params_in_pixel.surface_handle);
+ if (!SwapBuffersPrepare(surface_rect, damage_rect, &ack_params))
return;
- }
- if (ShouldFastACK(params_in_pixel.surface_handle)) {
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL);
- return;
+ SkRegion damage(RectToSkIRect(damage_rect));
+ if (!skipped_damage_.isEmpty()) {
+ damage.op(skipped_damage_, SkRegion::kUnion_Op);
+ skipped_damage_.setEmpty();
}
- current_surface_ = params_in_pixel.surface_handle;
- released_front_lock_ = NULL;
- DCHECK(current_surface_);
- UpdateExternalTexture();
+ DCHECK(surface_rect.Contains(SkIRectToRect(damage.getBounds())));
+ ui::Texture* current_texture = image_transport_clients_[current_surface_];
- ui::Compositor* compositor = GetCompositor();
- if (!compositor) {
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, true, NULL);
- } else {
- DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) !=
- image_transport_clients_.end());
- gfx::Size surface_size_in_pixel =
- image_transport_clients_[params_in_pixel.surface_handle]->size();
+ const gfx::Size surface_size_in_pixel = params_in_pixel.surface_size;
+ DLOG_IF(ERROR, ack_params.texture_to_produce &&
+ ack_params.texture_to_produce->size() != current_texture->size() &&
+ SkIRectToRect(damage.getBounds()) != surface_rect) <<
+ "Expected full damage rect after size change";
+ if (ack_params.texture_to_produce && !previous_damage_.isEmpty() &&
+ ack_params.texture_to_produce->size() == current_texture->size()) {
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
+ GLHelper* gl_helper = factory->GetGLHelper();
+ gl_helper->CopySubBufferDamage(
+ current_texture->PrepareTexture(),
+ ack_params.texture_to_produce->PrepareTexture(),
+ damage,
+ previous_damage_);
+ }
+ previous_damage_ = damage;
+ ui::Compositor* compositor = GetCompositor();
+ if (compositor) {
// Co-ordinates come in OpenGL co-ordinate space.
// We need to convert to layer space.
gfx::Rect rect_to_paint = ConvertRectToDIP(this, gfx::Rect(
params_in_pixel.x,
surface_size_in_pixel.height() - params_in_pixel.y -
- params_in_pixel.height,
+ params_in_pixel.height,
params_in_pixel.width,
params_in_pixel.height));
@@ -949,17 +957,9 @@ void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
rect_to_paint.Intersect(window_->bounds());
window_->SchedulePaintInRect(rect_to_paint);
-
- // Add sending an ACK to the list of things to do OnCompositingDidCommit
- can_lock_compositor_ = NO_PENDING_COMMIT;
- on_compositing_did_commit_callbacks_.push_back(
- base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK,
- params_in_pixel.route_id,
- gpu_host_id,
- true));
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
}
+
+ SwapBuffersCompleted(ack_params);
}
void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() {
@@ -978,60 +978,45 @@ bool RenderWidgetHostViewAura::HasAcceleratedSurface(
void RenderWidgetHostViewAura::AcceleratedSurfaceNew(
int32 width_in_pixel,
int32 height_in_pixel,
- uint64 surface_handle) {
+ uint64 surface_handle,
+ const std::string& mailbox_name) {
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
scoped_refptr<ui::Texture> surface(factory->CreateTransportClient(
gfx::Size(width_in_pixel, height_in_pixel), device_scale_factor_,
- surface_handle));
+ mailbox_name));
if (!surface) {
LOG(ERROR) << "Failed to create ImageTransport texture";
return;
}
-
image_transport_clients_[surface_handle] = surface;
}
-void RenderWidgetHostViewAura::AcceleratedSurfaceRelease(
- uint64 surface_handle) {
- DCHECK(image_transport_clients_.find(surface_handle) !=
- image_transport_clients_.end());
- if (current_surface_ == surface_handle) {
+void RenderWidgetHostViewAura::AcceleratedSurfaceRelease() {
+ // This really tells us to release the frontbuffer.
+ if (current_surface_ && ShouldReleaseFrontSurface()) {
+ ui::Compositor* compositor = GetCompositor();
+ if (compositor) {
+ // We need to wait for a commit to clear to guarantee that all we
+ // will not issue any more GL referencing the previous surface.
+ can_lock_compositor_ = NO_PENDING_COMMIT;
+ scoped_refptr<ui::Texture> surface_ref =
+ image_transport_clients_[current_surface_];
+ on_compositing_did_commit_callbacks_.push_back(
+ base::Bind(&RenderWidgetHostViewAura::
+ SetSurfaceNotInUseByCompositor,
+ AsWeakPtr(),
+ surface_ref));
+ if (!compositor->HasObserver(this))
+ compositor->AddObserver(this);
+ }
+ image_transport_clients_.erase(current_surface_);
current_surface_ = 0;
UpdateExternalTexture();
}
- image_transport_clients_.erase(surface_handle);
}
-void RenderWidgetHostViewAura::SetSurfaceNotInUseByCompositor(ui::Compositor*) {
- if (current_surface_ || !host_->is_hidden())
- return;
- current_surface_in_use_by_compositor_ = false;
- AdjustSurfaceProtection();
-}
-
-void RenderWidgetHostViewAura::AdjustSurfaceProtection() {
- // If the current surface is non null, it is protected.
- // If we are visible, it is protected.
- // Otherwise, change to not proctected once done thumbnailing and compositing.
- bool surface_is_protected =
- current_surface_ ||
- !host_->is_hidden() ||
- (current_surface_is_protected_ &&
- (pending_thumbnail_tasks_ > 0 ||
- current_surface_in_use_by_compositor_));
- if (current_surface_is_protected_ == surface_is_protected)
- return;
- current_surface_is_protected_ = surface_is_protected;
- ++protection_state_id_;
-
- if (!surface_route_id_ || !shared_surface_handle_.parent_gpu_process_id)
- return;
-
- RenderWidgetHostImpl::SendFrontSurfaceIsProtected(
- surface_is_protected,
- protection_state_id_,
- surface_route_id_,
- shared_surface_handle_.parent_gpu_process_id);
+void RenderWidgetHostViewAura::SetSurfaceNotInUseByCompositor(
+ scoped_refptr<ui::Texture>) {
}
void RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished(
@@ -1043,7 +1028,6 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished(
if (!render_widget_host_view.get())
return;
--render_widget_host_view->pending_thumbnail_tasks_;
- render_widget_host_view->AdjustSurfaceProtection();
}
void RenderWidgetHostViewAura::SetBackground(const SkBitmap& background) {
@@ -1763,7 +1747,7 @@ void RenderWidgetHostViewAura::OnCompositingDidCommit(
if ((*it)->GrabDeferredLock())
can_lock_compositor_ = YES_DID_LOCK;
}
- RunCompositingDidCommitCallbacks(compositor);
+ RunCompositingDidCommitCallbacks();
locks_pending_commit_.clear();
}
@@ -1794,10 +1778,6 @@ void RenderWidgetHostViewAura::OnCompositingLockStateChanged(
void RenderWidgetHostViewAura::OnLostResources() {
image_transport_clients_.clear();
current_surface_ = 0;
- protection_state_id_ = 0;
- current_surface_is_protected_ = true;
- current_surface_in_use_by_compositor_ = true;
- surface_route_id_ = 0;
UpdateExternalTexture();
locks_pending_commit_.clear();
@@ -1939,30 +1919,28 @@ bool RenderWidgetHostViewAura::ShouldMoveToCenter() {
global_mouse_position_.y() > rect.bottom() - border_y;
}
-void RenderWidgetHostViewAura::RunCompositingDidCommitCallbacks(
- ui::Compositor* compositor) {
- for (std::vector< base::Callback<void(ui::Compositor*)> >::const_iterator
+void RenderWidgetHostViewAura::RunCompositingDidCommitCallbacks() {
+ for (std::vector<base::Closure>::const_iterator
it = on_compositing_did_commit_callbacks_.begin();
it != on_compositing_did_commit_callbacks_.end(); ++it) {
- it->Run(compositor);
+ it->Run();
}
on_compositing_did_commit_callbacks_.clear();
}
// static
void RenderWidgetHostViewAura::InsertSyncPointAndACK(
- int32 route_id, int gpu_host_id, bool presented,
- ui::Compositor* compositor) {
+ const BufferPresentedParams& params) {
uint32 sync_point = 0;
- // If we have no compositor, so we must still send the ACK. A zero
- // sync point will not be waited for in the GPU process.
- if (compositor) {
- ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
- sync_point = factory->InsertSyncPoint();
+ // If we produced a texture, we have to synchronize with the consumer of
+ // that texture.
+ if (params.texture_to_produce) {
+ params.texture_to_produce->Produce();
+ sync_point = ImageTransportFactory::GetInstance()->InsertSyncPoint();
}
RenderWidgetHostImpl::AcknowledgeBufferPresent(
- route_id, gpu_host_id, presented, sync_point);
+ params.route_id, params.gpu_host_id, params.surface_handle, sync_point);
}
void RenderWidgetHostViewAura::AddingToRootWindow() {
@@ -1979,7 +1957,7 @@ void RenderWidgetHostViewAura::RemovingFromRootWindow() {
// frame though, because we will reissue a new frame right away without that
// composited data.
ui::Compositor* compositor = GetCompositor();
- RunCompositingDidCommitCallbacks(compositor);
+ RunCompositingDidCommitCallbacks();
locks_pending_commit_.clear();
if (compositor && compositor->HasObserver(this))
compositor->RemoveObserver(this);
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index 42e9fec..9a6fd26 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -12,13 +12,16 @@
#include "base/gtest_prod_util.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/renderer_host/image_transport_factory.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/common/content_export.h"
+#include "third_party/skia/include/core/SkRegion.h"
#include "ui/aura/client/activation_delegate.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/ime/text_input_client.h"
+#include "ui/compositor/compositor.h"
#include "ui/compositor/compositor_observer.h"
#include "ui/gfx/display_observer.h"
#include "ui/gfx/rect.h"
@@ -121,11 +124,11 @@ class RenderWidgetHostViewAura
int gpu_host_id) OVERRIDE;
virtual void AcceleratedSurfaceSuspend() OVERRIDE;
virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) OVERRIDE;
- virtual void AcceleratedSurfaceNew(
- int32 width_in_pixel,
- int32 height_in_pixel,
- uint64 surface_id) OVERRIDE;
- virtual void AcceleratedSurfaceRelease(uint64 surface_id) OVERRIDE;
+ virtual void AcceleratedSurfaceNew(int32 width_in_pixel,
+ int32 height_in_pixel,
+ uint64 surface_id,
+ const std::string& mailbox_name) OVERRIDE;
+ virtual void AcceleratedSurfaceRelease() OVERRIDE;
virtual void GetScreenInfo(WebKit::WebScreenInfo* results) OVERRIDE;
virtual gfx::Rect GetBoundsInRootWindow() OVERRIDE;
virtual void ProcessAckedTouchEvent(
@@ -231,7 +234,7 @@ class RenderWidgetHostViewAura
virtual ~RenderWidgetHostViewAura();
void UpdateCursorIfOverSelf();
- bool ShouldFastACK(uint64 surface_id);
+ bool ShouldSkipFrame(const gfx::Size& size);
void UpdateExternalTexture();
ui::InputMethod* GetInputMethod() const;
@@ -255,14 +258,23 @@ class RenderWidgetHostViewAura
bool ShouldMoveToCenter();
// Run the compositing callbacks.
- void RunCompositingDidCommitCallbacks(ui::Compositor* compositor);
+ void RunCompositingDidCommitCallbacks();
+
+ struct BufferPresentedParams {
+ BufferPresentedParams(int route_id,
+ int gpu_host_id,
+ uint64 surface_handle);
+ ~BufferPresentedParams();
+
+ int32 route_id;
+ int gpu_host_id;
+ uint64 surface_handle;
+ scoped_refptr<ui::Texture> texture_to_produce;
+ };
// Insert a sync point into the compositor's command stream and acknowledge
// that we have presented the accelerated surface buffer.
- static void InsertSyncPointAndACK(int32 route_id,
- int gpu_host_id,
- bool presented,
- ui::Compositor* compositor);
+ static void InsertSyncPointAndACK(const BufferPresentedParams& params);
// Called when window_ gets added to a new window tree.
void AddingToRootWindow();
@@ -270,15 +282,9 @@ class RenderWidgetHostViewAura
// Called when window_ is removed from the window tree.
void RemovingFromRootWindow();
- // After clearing |current_surface_|, and waiting for the compositor to finish
- // using it, call this to inform the gpu process.
- void SetSurfaceNotInUseByCompositor(ui::Compositor* compositor);
-
- // This is called every time |current_surface_| usage changes (by thumbnailer,
- // compositor draws, and tab visibility). Every time usage of current surface
- // changes between "may be used" and "certain to not be used" by the ui, we
- // inform the gpu process.
- void AdjustSurfaceProtection();
+ // Called after commit for the last reference to the texture going away
+ // after it was released as the frontbuffer.
+ void SetSurfaceNotInUseByCompositor(scoped_refptr<ui::Texture>);
// Called after async thumbnailer task completes. Used to call
// AdjustSurfaceProtection.
@@ -295,6 +301,12 @@ class RenderWidgetHostViewAura
// Converts |rect| from window coordinate to screen coordinate.
gfx::Rect ConvertRectToScreen(const gfx::Rect& rect);
+ bool SwapBuffersPrepare(const gfx::Rect& surface_rect,
+ const gfx::Rect& damage_rect,
+ BufferPresentedParams* params);
+
+ void SwapBuffersCompleted(const BufferPresentedParams& params);
+
// The model object.
RenderWidgetHostImpl* host_;
@@ -347,27 +359,25 @@ class RenderWidgetHostViewAura
// The scale factor of the display the renderer is currently on.
float device_scale_factor_;
- std::vector< base::Callback<void(ui::Compositor*)> >
- on_compositing_did_commit_callbacks_;
+ std::vector<base::Closure> on_compositing_did_commit_callbacks_;
- std::map<uint64, scoped_refptr<ui::Texture> >
- image_transport_clients_;
+ std::map<uint64, scoped_refptr<ui::Texture> > image_transport_clients_;
+ // The identifier of the current frontbuffer.
uint64 current_surface_;
- // Protected means that the |current_surface_| may be in use by ui and cannot
- // be safely discarded. Things to consider are thumbnailer, compositor draw,
- // and tab visibility.
- bool current_surface_is_protected_;
- bool current_surface_in_use_by_compositor_;
+ // The damage in the previously presented buffer.
+ SkRegion previous_damage_;
- int pending_thumbnail_tasks_;
+ // Pending damage from previous frames that we skipped.
+ SkRegion skipped_damage_;
- // This id increments every time surface_is_protected changes. We tag IPC
- // messages which rely on protection state with this id to stay in sync.
- uint32 protection_state_id_;
+ // The size of the last frame that was swapped (even if we skipped it).
+ // Used to determine when the skipped_damage_ needs to be reset due to
+ // size changes between front- and backbuffer.
+ gfx::Size last_swapped_surface_size_;
- int32 surface_route_id_;
+ int pending_thumbnail_tasks_;
gfx::GLSurfaceHandle shared_surface_handle_;
diff --git a/content/browser/renderer_host/render_widget_host_view_gtk.cc b/content/browser/renderer_host/render_widget_host_view_gtk.cc
index 5120764..70ab67c 100644
--- a/content/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/content/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -1057,14 +1057,14 @@ void RenderWidgetHostViewGtk::AcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
int gpu_host_id) {
RenderWidgetHostImpl::AcknowledgeBufferPresent(
- params.route_id, gpu_host_id, true, 0);
+ params.route_id, gpu_host_id, params.surface_handle, 0);
}
void RenderWidgetHostViewGtk::AcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
int gpu_host_id) {
RenderWidgetHostImpl::AcknowledgeBufferPresent(
- params.route_id, gpu_host_id, true, 0);
+ params.route_id, gpu_host_id, params.surface_handle, 0);
}
void RenderWidgetHostViewGtk::AcceleratedSurfaceSuspend() {
diff --git a/content/browser/renderer_host/render_widget_host_view_guest.cc b/content/browser/renderer_host/render_widget_host_view_guest.cc
index b9adaff..fcad0fe 100644
--- a/content/browser/renderer_host/render_widget_host_view_guest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_guest.cc
@@ -201,9 +201,11 @@ void RenderWidgetHostViewGuest::CopyFromCompositingSurface(
NOTIMPLEMENTED();
}
-void RenderWidgetHostViewGuest::AcceleratedSurfaceNew(int32 width_in_pixel,
- int32 height_in_pixel,
- uint64 surface_handle) {
+void RenderWidgetHostViewGuest::AcceleratedSurfaceNew(
+ int32 width_in_pixel,
+ int32 height_in_pixel,
+ uint64 surface_handle,
+ const std::string& mailbox_name) {
NOTIMPLEMENTED();
}
diff --git a/content/browser/renderer_host/render_widget_host_view_guest.h b/content/browser/renderer_host/render_widget_host_view_guest.h
index 2f2947a..b2b0088 100644
--- a/content/browser/renderer_host/render_widget_host_view_guest.h
+++ b/content/browser/renderer_host/render_widget_host_view_guest.h
@@ -104,7 +104,8 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) OVERRIDE;
virtual void AcceleratedSurfaceNew(int32 width_in_pixel,
int32 height_in_pixel,
- uint64 surface_id) OVERRIDE;
+ uint64 surface_id,
+ const std::string& mailbox_name) OVERRIDE;
virtual void SetHasHorizontalScrollbar(
bool has_horizontal_scrollbar) OVERRIDE;
virtual void SetScrollOffsetPinning(
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index 5c2244a..724884b 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1088,7 +1088,7 @@ void RenderWidgetHostViewMac::AckPendingSwapBuffers() {
RenderWidgetHostImpl::AcknowledgeBufferPresent(
pending_swap_buffers_acks_.front().first,
pending_swap_buffers_acks_.front().second,
- true,
+ 0,
0);
if (render_widget_host_) {
render_widget_host_->AcknowledgeSwapBuffersToRenderer();
diff --git a/content/browser/renderer_host/test_render_view_host.h b/content/browser/renderer_host/test_render_view_host.h
index 6d1c60d..d65f897 100644
--- a/content/browser/renderer_host/test_render_view_host.h
+++ b/content/browser/renderer_host/test_render_view_host.h
@@ -167,12 +167,6 @@ class TestRenderWidgetHostView : public RenderWidgetHostViewBase {
virtual void SetScrollOffsetPinning(
bool is_pinned_to_left, bool is_pinned_to_right) OVERRIDE { }
-#if defined(USE_AURA)
- virtual void AcceleratedSurfaceNew(
- int32 width, int32 height, uint64 surface_id) OVERRIDE { }
- virtual void AcceleratedSurfaceRelease(uint64 surface_id) OVERRIDE { }
-#endif
-
#if defined(TOOLKIT_GTK)
virtual void CreatePluginContainer(gfx::PluginWindowHandle id) OVERRIDE { }
virtual void DestroyPluginContainer(gfx::PluginWindowHandle id) OVERRIDE { }
diff --git a/content/common/gpu/client/gl_helper.cc b/content/common/gpu/client/gl_helper.cc
index 645ee43..8843695 100644
--- a/content/common/gpu/client/gl_helper.cc
+++ b/content/common/gpu/client/gl_helper.cc
@@ -17,6 +17,7 @@
#include "base/threading/thread_restrictions.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
+#include "third_party/skia/include/core/SkRegion.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
#include "ui/gl/gl_bindings.h"
@@ -791,4 +792,30 @@ void GLHelper::InitCopyTextToImpl() {
}
+void GLHelper::CopySubBufferDamage(WebKit::WebGLId texture,
+ WebKit::WebGLId previous_texture,
+ const SkRegion& new_damage,
+ const SkRegion& old_damage) {
+ SkRegion region(old_damage);
+ if (region.op(new_damage, SkRegion::kDifference_Op)) {
+ ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer());
+ ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(
+ context_, dst_framebuffer);
+ ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture);
+ context_->framebufferTexture2D(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D,
+ previous_texture,
+ 0);
+ for (SkRegion::Iterator it(region); !it.done(); it.next()) {
+ const SkIRect& rect = it.rect();
+ context_->copyTexSubImage2D(GL_TEXTURE_2D, 0,
+ rect.x(), rect.y(),
+ rect.x(), rect.y(),
+ rect.width(), rect.height());
+ }
+ context_->flush();
+ }
+}
+
} // namespace content
diff --git a/content/common/gpu/client/gl_helper.h b/content/common/gpu/client/gl_helper.h
index 41360b9..c7f161b 100644
--- a/content/common/gpu/client/gl_helper.h
+++ b/content/common/gpu/client/gl_helper.h
@@ -16,6 +16,8 @@ class Rect;
class Size;
}
+class SkRegion;
+
namespace content {
// Provides higher level operations on top of the WebKit::WebGraphicsContext3D
@@ -66,6 +68,12 @@ class GLHelper {
WebKit::WebGLId CompileShaderFromSource(const WebKit::WGC3Dchar* source,
WebKit::WGC3Denum type);
+ // Copies all pixels from |previous_texture| into |texture| that are
+ // inside the region covered by |old_damage| but not part of |new_damage|.
+ void CopySubBufferDamage(WebKit::WebGLId texture,
+ WebKit::WebGLId previous_texture,
+ const SkRegion& new_damage,
+ const SkRegion& old_damage);
private:
class CopyTextureToImpl;
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index 8eefd15..0fb6c6e 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -136,8 +136,6 @@ GpuCommandBufferStub::GpuCommandBufferStub(
new GpuCommandBufferMemoryTracker(channel),
true);
}
- if (handle_.sync_point)
- OnWaitSyncPoint(handle_.sync_point);
}
GpuCommandBufferStub::~GpuCommandBufferStub() {
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index d72bf05..38d2156 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -46,6 +46,7 @@ IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceNew_Params)
IPC_STRUCT_MEMBER(int32, width)
IPC_STRUCT_MEMBER(int32, height)
IPC_STRUCT_MEMBER(uint64, surface_handle)
+ IPC_STRUCT_MEMBER(std::string, mailbox_name)
IPC_STRUCT_MEMBER(int32, route_id)
#if defined(OS_MACOSX)
IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, window)
@@ -63,8 +64,6 @@ IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params)
#if defined(OS_MACOSX)
IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, window)
#endif
- IPC_STRUCT_MEMBER(uint32, protection_state_id)
- IPC_STRUCT_MEMBER(bool, skip_ack)
IPC_STRUCT_END()
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT
@@ -81,12 +80,10 @@ IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params)
#if defined(OS_MACOSX)
IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, window)
#endif
- IPC_STRUCT_MEMBER(uint32, protection_state_id)
IPC_STRUCT_END()
IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceRelease_Params)
IPC_STRUCT_MEMBER(int32, surface_id)
- IPC_STRUCT_MEMBER(uint64, identifier)
IPC_STRUCT_MEMBER(int32, route_id)
#if defined(OS_MACOSX)
IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, window)
@@ -197,10 +194,6 @@ IPC_STRUCT_TRAITS_BEGIN(gfx::GLSurfaceHandle)
IPC_STRUCT_TRAITS_MEMBER(transport)
IPC_STRUCT_TRAITS_MEMBER(parent_gpu_process_id)
IPC_STRUCT_TRAITS_MEMBER(parent_client_id)
- IPC_STRUCT_TRAITS_MEMBER(parent_context_id)
- IPC_STRUCT_TRAITS_MEMBER(parent_texture_id[0])
- IPC_STRUCT_TRAITS_MEMBER(parent_texture_id[1])
- IPC_STRUCT_TRAITS_MEMBER(sync_point)
IPC_STRUCT_TRAITS_END()
IPC_ENUM_TRAITS(content::CauseForGpuLaunch)
@@ -280,16 +273,12 @@ IPC_MESSAGE_CONTROL1(GpuMsg_SetVideoMemoryWindowCount,
// view.
IPC_MESSAGE_ROUTED0(AcceleratedSurfaceMsg_ResizeViewACK)
-// Tells the GPU process if it's worth suggesting release of the front surface.
-IPC_MESSAGE_ROUTED2(AcceleratedSurfaceMsg_SetFrontSurfaceIsProtected,
- bool /* is_protected */,
- uint32 /* protection_state_id */)
-
// Tells the GPU process that the browser process has handled the swap
// buffers or post sub-buffer request. A non-zero sync point means
-// that we should wait for the sync point.
+// that we should wait for the sync point. The surface_handle identifies
+// that buffer that has finished presented, i.e. the buffer being returned.
IPC_MESSAGE_ROUTED2(AcceleratedSurfaceMsg_BufferPresented,
- bool /* presented */,
+ uint64 /* surface_handle */,
uint32 /* sync_point */)
// Tells the GPU process to remove all contexts.
diff --git a/content/common/gpu/image_transport_surface.cc b/content/common/gpu/image_transport_surface.cc
index d9ea02e..96240c7 100644
--- a/content/common/gpu/image_transport_surface.cc
+++ b/content/common/gpu/image_transport_surface.cc
@@ -24,10 +24,6 @@ ImageTransportSurface::ImageTransportSurface() {}
ImageTransportSurface::~ImageTransportSurface() {}
-void ImageTransportSurface::OnSetFrontSurfaceIsProtected(
- bool is_protected, uint32 protection_state_id) {
-}
-
void ImageTransportSurface::GetRegionsToCopy(
const gfx::Rect& previous_damage_rect,
const gfx::Rect& new_damage_rect,
@@ -100,8 +96,6 @@ bool ImageTransportHelper::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(ImageTransportHelper, message)
IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_BufferPresented,
OnBufferPresented)
- IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_SetFrontSurfaceIsProtected,
- OnSetFrontSurfaceIsProtected)
IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_ResizeViewACK, OnResizeViewACK);
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -212,14 +206,9 @@ gpu::gles2::GLES2Decoder* ImageTransportHelper::Decoder() {
return stub_->decoder();
}
-void ImageTransportHelper::OnSetFrontSurfaceIsProtected(
- bool is_protected, uint32 protection_state_id) {
- surface_->OnSetFrontSurfaceIsProtected(is_protected, protection_state_id);
-}
-
-void ImageTransportHelper::OnBufferPresented(bool presented,
+void ImageTransportHelper::OnBufferPresented(uint64 surface_handle,
uint32 sync_point) {
- surface_->OnBufferPresented(presented, sync_point);
+ surface_->OnBufferPresented(surface_handle, sync_point);
}
void ImageTransportHelper::OnResizeViewACK() {
@@ -322,7 +311,7 @@ bool PassThroughImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
}
void PassThroughImageTransportSurface::OnBufferPresented(
- bool /* presented */,
+ uint64 /* surface_handle */,
uint32 /* sync_point */) {
DCHECK(transport_);
helper_->SetScheduled(true);
diff --git a/content/common/gpu/image_transport_surface.h b/content/common/gpu/image_transport_surface.h
index 2036fa5..17a2be6 100644
--- a/content/common/gpu/image_transport_surface.h
+++ b/content/common/gpu/image_transport_surface.h
@@ -60,11 +60,9 @@ class ImageTransportSurface {
public:
ImageTransportSurface();
- virtual void OnBufferPresented(bool presented, uint32 sync_point) = 0;
+ virtual void OnBufferPresented(uint64 surface_handle, uint32 sync_point) = 0;
virtual void OnResizeViewACK() = 0;
virtual void OnResize(gfx::Size size) = 0;
- virtual void OnSetFrontSurfaceIsProtected(bool is_protected,
- uint32 protection_state_id);
// Creates the appropriate surface depending on the GL implementation.
static scoped_refptr<gfx::GLSurface>
@@ -143,10 +141,8 @@ class ImageTransportHelper
gpu::gles2::GLES2Decoder* Decoder();
// IPC::Message handlers.
- void OnBufferPresented(bool presented, uint32 sync_point);
+ void OnBufferPresented(uint64 surface_handle, uint32 sync_point);
void OnResizeViewACK();
- void OnSetFrontSurfaceIsProtected(bool is_protected,
- uint32 protection_state_id);
// Backbuffer resize callback.
void Resize(gfx::Size size);
@@ -181,7 +177,7 @@ class PassThroughImageTransportSurface
virtual bool OnMakeCurrent(gfx::GLContext* context) OVERRIDE;
// ImageTransportSurface implementation.
- virtual void OnBufferPresented(bool presented,
+ virtual void OnBufferPresented(uint64 surface_handle,
uint32 sync_point) OVERRIDE;
virtual void OnResizeViewACK() OVERRIDE;
virtual void OnResize(gfx::Size size) OVERRIDE;
diff --git a/content/common/gpu/image_transport_surface_android.cc b/content/common/gpu/image_transport_surface_android.cc
index 045a4c8..f476f755 100644
--- a/content/common/gpu/image_transport_surface_android.cc
+++ b/content/common/gpu/image_transport_surface_android.cc
@@ -18,7 +18,6 @@ scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
const gfx::GLSurfaceHandle& handle) {
scoped_refptr<gfx::GLSurface> surface;
if (!handle.handle && handle.transport) {
- DCHECK(handle.parent_client_id);
surface = new TextureImageTransportSurface(manager, stub, handle);
} else if (handle.handle == gfx::kDummyPluginWindow && !handle.transport) {
DCHECK(GpuSurfaceLookup::GetInstance());
diff --git a/content/common/gpu/image_transport_surface_mac.cc b/content/common/gpu/image_transport_surface_mac.cc
index 5046912..4f888db 100644
--- a/content/common/gpu/image_transport_surface_mac.cc
+++ b/content/common/gpu/image_transport_surface_mac.cc
@@ -57,7 +57,7 @@ class IOSurfaceImageTransportSurface : public gfx::NoOpGLSurfaceCGL,
protected:
// ImageTransportSurface implementation
- virtual void OnBufferPresented(bool presented,
+ virtual void OnBufferPresented(uint64 surface_handle,
uint32 sync_point) OVERRIDE;
virtual void OnResizeViewACK() OVERRIDE;
virtual void OnResize(gfx::Size size) OVERRIDE;
@@ -268,7 +268,7 @@ gfx::Size IOSurfaceImageTransportSurface::GetSize() {
return size_;
}
-void IOSurfaceImageTransportSurface::OnBufferPresented(bool presented,
+void IOSurfaceImageTransportSurface::OnBufferPresented(uint64 surface_handle,
uint32 sync_point) {
DCHECK(is_swap_buffers_pending_);
is_swap_buffers_pending_ = false;
diff --git a/content/common/gpu/image_transport_surface_win.cc b/content/common/gpu/image_transport_surface_win.cc
index 9c8eed4..62296a7 100644
--- a/content/common/gpu/image_transport_surface_win.cc
+++ b/content/common/gpu/image_transport_surface_win.cc
@@ -50,7 +50,8 @@ class PbufferImageTransportSurface
protected:
// ImageTransportSurface implementation
- virtual void OnBufferPresented(bool presented, uint32 sync_point) OVERRIDE;
+ virtual void OnBufferPresented(uint64 surface_handle,
+ uint32 sync_point) OVERRIDE;
virtual void OnResizeViewACK() OVERRIDE;
virtual void OnResize(gfx::Size size) OVERRIDE;
virtual gfx::Size GetSize() OVERRIDE;
@@ -206,7 +207,7 @@ void PbufferImageTransportSurface::SendBuffersSwapped() {
is_swap_buffers_pending_ = true;
}
-void PbufferImageTransportSurface::OnBufferPresented(bool presented,
+void PbufferImageTransportSurface::OnBufferPresented(uint64 surface_handle,
uint32 sync_point) {
is_swap_buffers_pending_ = false;
if (did_unschedule_) {
diff --git a/content/common/gpu/texture_image_transport_surface.cc b/content/common/gpu/texture_image_transport_surface.cc
index 64848fe..7fa2690 100644
--- a/content/common/gpu/texture_image_transport_surface.cc
+++ b/content/common/gpu/texture_image_transport_surface.cc
@@ -16,17 +16,19 @@
#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/gpu_scheduler.h"
-#include "gpu/command_buffer/service/texture_manager.h"
+#include "gpu/command_buffer/service/texture_definition.h"
using gpu::gles2::ContextGroup;
+using gpu::gles2::MailboxManager;
+using gpu::gles2::MailboxName;
+using gpu::gles2::TextureDefinition;
using gpu::gles2::TextureManager;
-typedef TextureManager::TextureInfo TextureInfo;
namespace content {
TextureImageTransportSurface::Texture::Texture()
- : client_id(0),
- sent_to_client(false) {
+ : service_id(0),
+ surface_handle(0) {
}
TextureImageTransportSurface::Texture::~Texture() {
@@ -37,17 +39,12 @@ TextureImageTransportSurface::TextureImageTransportSurface(
GpuCommandBufferStub* stub,
const gfx::GLSurfaceHandle& handle)
: fbo_id_(0),
- front_(0),
stub_destroyed_(false),
backbuffer_suggested_allocation_(true),
frontbuffer_suggested_allocation_(true),
- frontbuffer_is_protected_(true),
- protection_state_id_(0),
handle_(handle),
- parent_stub_(NULL),
is_swap_buffers_pending_(false),
- did_unschedule_(false),
- did_flip_(false) {
+ did_unschedule_(false) {
helper_.reset(new ImageTransportHelper(this,
manager,
stub,
@@ -60,39 +57,12 @@ TextureImageTransportSurface::~TextureImageTransportSurface() {
}
bool TextureImageTransportSurface::Initialize() {
- GpuChannelManager* manager = helper_->manager();
- GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id);
- if (!parent_channel)
- return false;
+ mailbox_manager_ =
+ helper_->stub()->decoder()->GetContextGroup()->mailbox_manager();
- parent_stub_ = parent_channel->LookupCommandBuffer(handle_.parent_context_id);
- if (!parent_stub_)
- return false;
-
- parent_stub_->AddDestructionObserver(this);
- TextureManager* texture_manager =
- parent_stub_->decoder()->GetContextGroup()->texture_manager();
- DCHECK(texture_manager);
-
- for (int i = 0; i < 2; ++i) {
- Texture& texture = textures_[i];
- texture.client_id = handle_.parent_texture_id[i];
- texture.info = texture_manager->GetTextureInfo(texture.client_id);
- if (!texture.info)
- return false;
-
- if (!texture.info->target())
- texture_manager->SetInfoTarget(texture.info, GL_TEXTURE_2D);
- texture_manager->SetParameter(
- texture.info, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- texture_manager->SetParameter(
- texture.info, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- texture_manager->SetParameter(
- texture.info, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- texture_manager->SetParameter(
- texture.info, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- }
+ backbuffer_.surface_handle = 1;
+ GpuChannelManager* manager = helper_->manager();
surface_ = manager->GetDefaultOffscreenSurface();
if (!surface_.get())
return false;
@@ -100,19 +70,17 @@ bool TextureImageTransportSurface::Initialize() {
if (!helper_->Initialize())
return false;
- const CommandLine* command_line = CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess))
- helper_->SetPreemptByCounter(parent_channel->MessagesPendingCount());
+ GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id);
+ if (parent_channel) {
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess))
+ helper_->SetPreemptByCounter(parent_channel->MessagesPendingCount());
+ }
return true;
}
void TextureImageTransportSurface::Destroy() {
- if (parent_stub_) {
- parent_stub_->decoder()->MakeCurrent();
- ReleaseParentStub();
- }
-
if (surface_.get())
surface_ = NULL;
@@ -149,10 +117,23 @@ bool TextureImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
return true;
}
+ if (!context_.get()) {
+ DCHECK(helper_->stub());
+ context_ = helper_->stub()->decoder()->GetGLContext();
+ }
+
if (!fbo_id_) {
glGenFramebuffersEXT(1, &fbo_id_);
glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_id_);
- CreateBackTexture(gfx::Size(1, 1));
+ current_size_ = gfx::Size(1, 1);
+ helper_->stub()->AddDestructionObserver(this);
+ }
+
+ // We could be receiving non-deferred GL commands, that is anything that does
+ // not need a framebuffer.
+ if (!backbuffer_.service_id && !is_swap_buffers_pending_ &&
+ backbuffer_suggested_allocation_) {
+ CreateBackTexture();
#ifndef NDEBUG
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
@@ -163,10 +144,7 @@ bool TextureImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
return false;
}
#endif
- DCHECK(helper_->stub());
- helper_->stub()->AddDestructionObserver(this);
}
-
return true;
}
@@ -180,15 +158,11 @@ void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) {
return;
backbuffer_suggested_allocation_ = allocation;
- if (!helper_->MakeCurrent())
- return;
-
if (backbuffer_suggested_allocation_) {
- DCHECK(!textures_[back()].info->service_id() ||
- !textures_[back()].sent_to_client);
- CreateBackTexture(textures_[back()].size);
+ DCHECK(!backbuffer_.service_id);
+ CreateBackTexture();
} else {
- ReleaseTexture(back());
+ ReleaseBackTexture();
}
}
@@ -196,22 +170,10 @@ void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) {
if (frontbuffer_suggested_allocation_ == allocation)
return;
frontbuffer_suggested_allocation_ = allocation;
- AdjustFrontBufferAllocation();
-}
-void TextureImageTransportSurface::AdjustFrontBufferAllocation() {
- if (!helper_->MakeCurrent())
- return;
-
- if (!frontbuffer_suggested_allocation_ && !frontbuffer_is_protected_ &&
- textures_[front()].info->service_id()) {
- ReleaseTexture(front());
- if (textures_[front()].sent_to_client) {
- GpuHostMsg_AcceleratedSurfaceRelease_Params params;
- params.identifier = textures_[front()].client_id;
- helper_->SendAcceleratedSurfaceRelease(params);
- textures_[front()].sent_to_client = false;
- }
+ if (!frontbuffer_suggested_allocation_) {
+ GpuHostMsg_AcceleratedSurfaceRelease_Params params;
+ helper_->SendAcceleratedSurfaceRelease(params);
}
}
@@ -228,50 +190,47 @@ void* TextureImageTransportSurface::GetConfig() {
}
void TextureImageTransportSurface::OnResize(gfx::Size size) {
- CreateBackTexture(size);
+ current_size_ = size;
+ CreateBackTexture();
}
void TextureImageTransportSurface::OnWillDestroyStub(
GpuCommandBufferStub* stub) {
- if (stub == parent_stub_) {
- ReleaseParentStub();
- helper_->SetPreemptByCounter(NULL);
- } else {
- DCHECK(stub == helper_->stub());
- stub->RemoveDestructionObserver(this);
+ DCHECK(stub == helper_->stub());
+ stub->RemoveDestructionObserver(this);
- // We are losing the stub owning us, this is our last chance to clean up the
- // resources we allocated in the stub's context.
- if (fbo_id_) {
- glDeleteFramebuffersEXT(1, &fbo_id_);
- CHECK_GL_ERROR();
- fbo_id_ = 0;
- }
+ GpuHostMsg_AcceleratedSurfaceRelease_Params params;
+ helper_->SendAcceleratedSurfaceRelease(params);
- stub_destroyed_ = true;
+ ReleaseBackTexture();
+
+ // We are losing the stub owning us, this is our last chance to clean up the
+ // resources we allocated in the stub's context.
+ if (fbo_id_) {
+ glDeleteFramebuffersEXT(1, &fbo_id_);
+ CHECK_GL_ERROR();
+ fbo_id_ = 0;
}
+
+ stub_destroyed_ = true;
}
bool TextureImageTransportSurface::SwapBuffers() {
DCHECK(backbuffer_suggested_allocation_);
- if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_)
+ if (!frontbuffer_suggested_allocation_)
return true;
- if (!parent_stub_) {
- LOG(ERROR) << "SwapBuffers failed because no parent stub.";
- return false;
- }
glFlush();
- front_ = back();
- previous_damage_rect_ = gfx::Rect(textures_[front()].size);
+ ProduceTexture(backbuffer_);
- DCHECK(textures_[front()].client_id != 0);
+ // Do not allow destruction while we are still waiting for a swap ACK,
+ // so we do not leak a texture in the mailbox.
+ AddRef();
+ DCHECK(backbuffer_.size == current_size_);
GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
- params.surface_handle = textures_[front()].client_id;
- params.size = textures_[front()].size;
- params.protection_state_id = protection_state_id_;
- params.skip_ack = false;
+ params.surface_handle = backbuffer_.surface_handle;
+ params.size = backbuffer_.size;
helper_->SendAcceleratedSurfaceBuffersSwapped(params);
DCHECK(!is_swap_buffers_pending_);
@@ -282,68 +241,31 @@ bool TextureImageTransportSurface::SwapBuffers() {
bool TextureImageTransportSurface::PostSubBuffer(
int x, int y, int width, int height) {
DCHECK(backbuffer_suggested_allocation_);
- DCHECK(textures_[back()].info->service_id());
- if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_)
+ if (!frontbuffer_suggested_allocation_)
return true;
- // If we are recreating the frontbuffer with this swap, make sure we are
- // drawing a full frame.
- DCHECK(textures_[front()].info->service_id() ||
- (!x && !y && gfx::Size(width, height) == textures_[back()].size));
- if (!parent_stub_) {
- LOG(ERROR) << "PostSubBuffer failed because no parent stub.";
- return false;
- }
-
const gfx::Rect new_damage_rect(x, y, width, height);
+ DCHECK(gfx::Rect(gfx::Point(), current_size_).Contains(new_damage_rect));
// An empty damage rect is a successful no-op.
if (new_damage_rect.IsEmpty())
return true;
- int back_texture_service_id = textures_[back()].info->service_id();
- int front_texture_service_id = textures_[front()].info->service_id();
-
- gfx::Size expected_size = textures_[back()].size;
- bool surfaces_same_size = textures_[front()].size == expected_size;
-
- if (surfaces_same_size) {
- std::vector<gfx::Rect> regions_to_copy;
- GetRegionsToCopy(previous_damage_rect_, new_damage_rect, &regions_to_copy);
-
- ScopedFrameBufferBinder fbo_binder(fbo_id_);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D,
- front_texture_service_id,
- 0);
- ScopedTextureBinder texture_binder(back_texture_service_id);
-
- for (size_t i = 0; i < regions_to_copy.size(); ++i) {
- const gfx::Rect& region_to_copy = regions_to_copy[i];
- if (!region_to_copy.IsEmpty()) {
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, region_to_copy.x(),
- region_to_copy.y(), region_to_copy.x(), region_to_copy.y(),
- region_to_copy.width(), region_to_copy.height());
- }
- }
- } else if (!surfaces_same_size && did_flip_) {
- DCHECK(new_damage_rect == gfx::Rect(expected_size));
- }
-
glFlush();
- front_ = back();
- previous_damage_rect_ = new_damage_rect;
+ ProduceTexture(backbuffer_);
+
+ // Do not allow destruction while we are still waiting for a swap ACK,
+ // so we do not leak a texture in the mailbox.
+ AddRef();
- DCHECK(textures_[front()].client_id);
+ DCHECK(current_size_ == backbuffer_.size);
GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params;
- params.surface_handle = textures_[front()].client_id;
- params.surface_size = textures_[front()].size;
+ params.surface_handle = backbuffer_.surface_handle;
+ params.surface_size = backbuffer_.size;
params.x = x;
params.y = y;
params.width = width;
params.height = height;
- params.protection_state_id = protection_state_id_;
helper_->SendAcceleratedSurfacePostSubBuffer(params);
DCHECK(!is_swap_buffers_pending_);
@@ -360,7 +282,7 @@ std::string TextureImageTransportSurface::GetExtensions() {
}
gfx::Size TextureImageTransportSurface::GetSize() {
- gfx::Size size = textures_[back()].size;
+ gfx::Size size = current_size_;
// OSMesa expects a non-zero size.
return gfx::Size(size.width() == 0 ? 1 : size.width(),
@@ -375,70 +297,60 @@ unsigned TextureImageTransportSurface::GetFormat() {
return surface_.get() ? surface_->GetFormat() : 0;
}
-void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected(
- bool is_protected, uint32 protection_state_id) {
- protection_state_id_ = protection_state_id;
- if (frontbuffer_is_protected_ == is_protected)
- return;
- frontbuffer_is_protected_ = is_protected;
- AdjustFrontBufferAllocation();
-
- // If surface is set to protected, and we haven't actually released it yet,
- // we can set the ui surface handle now just by sending a swap message.
- if (is_protected && textures_[front()].info->service_id() &&
- textures_[front()].sent_to_client) {
- GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
- params.surface_handle = textures_[front()].client_id;
- params.size = textures_[front()].size;
- params.protection_state_id = protection_state_id_;
- params.skip_ack = true;
- helper_->SendAcceleratedSurfaceBuffersSwapped(params);
- }
-}
-
-void TextureImageTransportSurface::OnBufferPresented(bool presented,
+void TextureImageTransportSurface::OnBufferPresented(uint64 surface_handle,
uint32 sync_point) {
if (sync_point == 0) {
- BufferPresentedImpl(presented);
+ BufferPresentedImpl(surface_handle);
} else {
helper_->manager()->sync_point_manager()->AddSyncPointCallback(
sync_point,
base::Bind(&TextureImageTransportSurface::BufferPresentedImpl,
- this->AsWeakPtr(),
- presented));
+ this,
+ surface_handle));
}
-}
-void TextureImageTransportSurface::BufferPresentedImpl(bool presented) {
- DCHECK(is_swap_buffers_pending_);
- is_swap_buffers_pending_ = false;
+ // Careful, we might get deleted now if we were only waiting for
+ // a final swap ACK.
+ Release();
+}
- if (presented) {
- // If we had not flipped, the two frame damage tracking is inconsistent.
- // So conservatively take the whole frame.
- if (!did_flip_)
- previous_damage_rect_ = gfx::Rect(textures_[front()].size);
+void TextureImageTransportSurface::BufferPresentedImpl(uint64 surface_handle) {
+ DCHECK(!backbuffer_.service_id);
+ if (surface_handle) {
+ DCHECK(surface_handle == 1 || surface_handle == 2);
+ backbuffer_.surface_handle = surface_handle;
+ ConsumeTexture(backbuffer_);
} else {
- front_ = back();
- previous_damage_rect_ = gfx::Rect(0, 0, 0, 0);
+ // We didn't get back a texture, so allocate 'the other' buffer.
+ backbuffer_.surface_handle = (backbuffer_.surface_handle == 1) ? 2 : 1;
+ mailbox_name(backbuffer_.surface_handle) = MailboxName();
+ }
+
+ if (stub_destroyed_ && backbuffer_.service_id) {
+ // TODO(sievers): Remove this after changes to the mailbox to take ownership
+ // of the service ids.
+ DCHECK(context_.get() && surface_.get());
+ if (context_->MakeCurrent(surface_.get()))
+ glDeleteTextures(1, &backbuffer_.service_id);
+
+ return;
}
- did_flip_ = presented;
+ DCHECK(is_swap_buffers_pending_);
+ is_swap_buffers_pending_ = false;
+
+ // We should not have allowed the backbuffer to be discarded while the ack
+ // was pending.
+ DCHECK(backbuffer_suggested_allocation_);
// We're relying on the fact that the parent context is
// finished with it's context when it inserts the sync point that
// triggers this callback.
if (helper_->MakeCurrent()) {
- if ((presented && textures_[front()].size != textures_[back()].size) ||
- !textures_[back()].info->service_id() ||
- !textures_[back()].sent_to_client) {
- // We may get an ACK from a stale swap just to reschedule. In that case,
- // we may not have a backbuffer suggestion and should not recreate one.
- if (backbuffer_suggested_allocation_)
- CreateBackTexture(textures_[front()].size);
- } else {
+ if (backbuffer_.size != current_size_ || !backbuffer_.service_id)
+ CreateBackTexture();
+ else
AttachBackTextureToFBO();
- }
}
// Even if MakeCurrent fails, schedule anyway, to trigger the lost context
@@ -453,94 +365,69 @@ void TextureImageTransportSurface::OnResizeViewACK() {
NOTREACHED();
}
-void TextureImageTransportSurface::ReleaseTexture(int id) {
- if (!parent_stub_)
- return;
- Texture& texture = textures_[id];
- TextureInfo* info = texture.info;
- DCHECK(info);
-
- GLuint service_id = info->service_id();
- if (!service_id)
+void TextureImageTransportSurface::ReleaseBackTexture() {
+ if (!backbuffer_.service_id)
return;
- info->SetServiceId(0);
- {
- ScopedFrameBufferBinder fbo_binder(fbo_id_);
- glDeleteTextures(1, &service_id);
- }
+ glDeleteTextures(1, &backbuffer_.service_id);
+ backbuffer_.service_id = 0;
+ mailbox_name(backbuffer_.surface_handle) = MailboxName();
glFlush();
CHECK_GL_ERROR();
}
-void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) {
- if (!parent_stub_)
- return;
- Texture& texture = textures_[back()];
- TextureInfo* info = texture.info;
- DCHECK(info);
-
- GLuint service_id = info->service_id();
+void TextureImageTransportSurface::CreateBackTexture() {
+ // If |is_swap_buffers_pending| we are waiting for our backbuffer
+ // in the mailbox, so we shouldn't be reallocating it now.
+ DCHECK(!is_swap_buffers_pending_);
- if (service_id && texture.size == size && texture.sent_to_client)
+ if (backbuffer_.service_id && backbuffer_.size == current_size_)
return;
- if (!service_id) {
- glGenTextures(1, &service_id);
- info->SetServiceId(service_id);
+ if (!backbuffer_.service_id) {
+ MailboxName new_mailbox_name;
+ MailboxName& name = mailbox_name(backbuffer_.surface_handle);
+ // This slot should be uninitialized.
+ DCHECK(!memcmp(&name, &new_mailbox_name, sizeof(MailboxName)));
+ mailbox_manager_->GenerateMailboxName(&new_mailbox_name);
+ name = new_mailbox_name;
+ glGenTextures(1, &backbuffer_.service_id);
}
- if (size != texture.size) {
- texture.size = size;
- TextureManager* texture_manager =
- parent_stub_->decoder()->GetContextGroup()->texture_manager();
- texture_manager->SetLevelInfo(
- info,
- GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- size.width(),
- size.height(),
- 1,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- true);
- }
+ backbuffer_.size = current_size_;
{
- ScopedTextureBinder texture_binder(service_id);
+ ScopedTextureBinder texture_binder(backbuffer_.service_id);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- size.width(), size.height(), 0,
+ current_size_.width(), current_size_.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
CHECK_GL_ERROR();
}
AttachBackTextureToFBO();
+ const MailboxName& name = mailbox_name(backbuffer_.surface_handle);
+
GpuHostMsg_AcceleratedSurfaceNew_Params params;
- params.width = size.width();
- params.height = size.height();
- params.surface_handle = texture.client_id;
+ params.width = current_size_.width();
+ params.height = current_size_.height();
+ params.surface_handle = backbuffer_.surface_handle;
+ params.mailbox_name.append(
+ reinterpret_cast<const char*>(&name), sizeof(name));
helper_->SendAcceleratedSurfaceNew(params);
- texture.sent_to_client = true;
}
void TextureImageTransportSurface::AttachBackTextureToFBO() {
- if (!parent_stub_)
- return;
- TextureInfo* info = textures_[back()].info;
- DCHECK(info);
-
+ DCHECK(backbuffer_.service_id);
ScopedFrameBufferBinder fbo_binder(fbo_id_);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
- info->service_id(),
+ backbuffer_.service_id,
0);
glFlush();
CHECK_GL_ERROR();
@@ -548,24 +435,58 @@ void TextureImageTransportSurface::AttachBackTextureToFBO() {
#ifndef NDEBUG
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
- DLOG(ERROR) << "Framebuffer incomplete.";
+ DLOG(FATAL) << "Framebuffer incomplete: " << status;
}
#endif
}
-void TextureImageTransportSurface::ReleaseParentStub() {
- DCHECK(parent_stub_);
- parent_stub_->RemoveDestructionObserver(this);
- for (int i = 0; i < 2; ++i) {
- Texture& texture = textures_[i];
- texture.info = NULL;
- if (!texture.sent_to_client)
- continue;
- GpuHostMsg_AcceleratedSurfaceRelease_Params params;
- params.identifier = texture.client_id;
- helper_->SendAcceleratedSurfaceRelease(params);
+void TextureImageTransportSurface::ConsumeTexture(Texture& texture) {
+ DCHECK(!texture.service_id);
+ DCHECK(texture.surface_handle == 1 || texture.surface_handle == 2);
+
+ scoped_ptr<TextureDefinition> definition(mailbox_manager_->ConsumeTexture(
+ GL_TEXTURE_2D, mailbox_name(texture.surface_handle)));
+ if (definition.get()) {
+ texture.service_id = definition->ReleaseServiceId();
+ texture.size = gfx::Size(definition->level_infos()[0][0].width,
+ definition->level_infos()[0][0].height);
}
- parent_stub_ = NULL;
+}
+
+void TextureImageTransportSurface::ProduceTexture(Texture& texture) {
+ DCHECK(texture.service_id);
+ DCHECK(texture.surface_handle == 1 || texture.surface_handle == 2);
+ TextureManager* texture_manager =
+ helper_->stub()->decoder()->GetContextGroup()->texture_manager();
+ DCHECK(texture.size.width() > 0 && texture.size.height() > 0);
+ TextureDefinition::LevelInfo info(
+ GL_TEXTURE_2D, GL_RGBA, texture.size.width(), texture.size.height(), 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
+
+ TextureDefinition::LevelInfos level_infos;
+ level_infos.resize(1);
+ level_infos[0].resize(texture_manager->MaxLevelsForTarget(GL_TEXTURE_2D));
+ level_infos[0][0] = info;
+ scoped_ptr<TextureDefinition> definition(new TextureDefinition(
+ GL_TEXTURE_2D,
+ texture.service_id,
+ GL_LINEAR,
+ GL_LINEAR,
+ GL_CLAMP_TO_EDGE,
+ GL_CLAMP_TO_EDGE,
+ GL_NONE,
+ true,
+ level_infos));
+ // Pass NULL as |owner| here to avoid errors from glConsumeTextureCHROMIUM()
+ // when the renderer context group goes away before the RWHV handles a pending
+ // ACK. We avoid leaking a texture in the mailbox by waiting for the final ACK
+ // at which point we consume the correct texture back.
+ mailbox_manager_->ProduceTexture(
+ GL_TEXTURE_2D,
+ mailbox_name(texture.surface_handle),
+ definition.release(),
+ NULL);
+ texture.service_id = 0;
}
} // namespace content
diff --git a/content/common/gpu/texture_image_transport_surface.h b/content/common/gpu/texture_image_transport_surface.h
index 150b585..4501347 100644
--- a/content/common/gpu/texture_image_transport_surface.h
+++ b/content/common/gpu/texture_image_transport_surface.h
@@ -6,10 +6,11 @@
#define CONTENT_COMMON_GPU_TEXTURE_IMAGE_TRANSPORT_SURFACE_H_
#include "base/basictypes.h"
-#include "base/memory/weak_ptr.h"
#include "content/common/gpu/gpu_command_buffer_stub.h"
#include "content/common/gpu/image_transport_surface.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/texture_manager.h"
+#include "ui/gl/gl_context.h"
#include "ui/gl/gl_surface.h"
namespace content {
@@ -18,8 +19,7 @@ class GpuChannelManager;
class TextureImageTransportSurface :
public ImageTransportSurface,
public GpuCommandBufferStub::DestructionObserver,
- public gfx::GLSurface,
- public base::SupportsWeakPtr<TextureImageTransportSurface> {
+ public gfx::GLSurface {
public:
TextureImageTransportSurface(GpuChannelManager* manager,
GpuCommandBufferStub* stub,
@@ -48,57 +48,53 @@ class TextureImageTransportSurface :
protected:
// ImageTransportSurface implementation.
virtual void OnBufferPresented(
- bool presented,
+ uint64 surface_handle,
uint32 sync_point) OVERRIDE;
virtual void OnResizeViewACK() OVERRIDE;
- virtual void OnSetFrontSurfaceIsProtected(
- bool is_protected,
- uint32 protection_state_id) OVERRIDE;
virtual void OnResize(gfx::Size size) OVERRIDE;
// GpuCommandBufferStub::DestructionObserver implementation.
virtual void OnWillDestroyStub(GpuCommandBufferStub* stub) OVERRIDE;
private:
- // A texture backing the front/back buffer in the parent stub.
+ // A texture backing the front/back buffer.
struct Texture {
Texture();
~Texture();
- // The client-side id in the parent stub.
- uint32 client_id;
-
// The currently allocated size.
gfx::Size size;
- // Whether or not that texture has been sent to the client yet.
- bool sent_to_client;
+ // The actual GL texture id.
+ uint32 service_id;
- // The texture info in the parent stub.
- gpu::gles2::TextureManager::TextureInfo::Ref info;
+ // The surface handle for this texture (only 1 and 2 are valid).
+ uint64 surface_handle;
};
virtual ~TextureImageTransportSurface();
- void CreateBackTexture(const gfx::Size& size);
+ void CreateBackTexture();
void AttachBackTextureToFBO();
- void ReleaseTexture(int id);
- void ReleaseParentStub();
- void AdjustFrontBufferAllocation();
- void BufferPresentedImpl(bool presented);
- int front() const { return front_; }
- int back() const { return 1 - front_; }
+ void ReleaseBackTexture();
+ void BufferPresentedImpl(uint64 surface_handle);
+ void ProduceTexture(Texture& texture);
+ void ConsumeTexture(Texture& texture);
+
+ gpu::gles2::MailboxName& mailbox_name(uint64 surface_handle) {
+ DCHECK(surface_handle == 1 || surface_handle == 2);
+ return mailbox_names_[surface_handle - 1];
+ }
// The framebuffer that represents this surface (service id). Allocated lazily
// in OnMakeCurrent.
uint32 fbo_id_;
- // The front and back buffers.
- Texture textures_[2];
-
- gfx::Rect previous_damage_rect_;
+ // The current backbuffer.
+ Texture backbuffer_;
- // Indicates which of the 2 above is the front buffer.
- int front_;
+ // The current size of the GLSurface. Used to disambiguate from the current
+ // texture size which might be outdated (since we use two buffers).
+ gfx::Size current_size_;
// Whether or not the command buffer stub has been destroyed.
bool stub_destroyed_;
@@ -106,16 +102,15 @@ class TextureImageTransportSurface :
bool backbuffer_suggested_allocation_;
bool frontbuffer_suggested_allocation_;
- bool frontbuffer_is_protected_;
- uint32 protection_state_id_;
-
scoped_ptr<ImageTransportHelper> helper_;
gfx::GLSurfaceHandle handle_;
- GpuCommandBufferStub* parent_stub_;
// The offscreen surface used to make the context current. However note that
// the actual rendering is always redirected to an FBO.
- scoped_refptr<GLSurface> surface_;
+ scoped_refptr<gfx::GLSurface> surface_;
+
+ // Holds a reference to the underlying context for cleanup.
+ scoped_refptr<gfx::GLContext> context_;
// Whether a SwapBuffers is pending.
bool is_swap_buffers_pending_;
@@ -123,9 +118,11 @@ class TextureImageTransportSurface :
// Whether we unscheduled command buffer because of pending SwapBuffers.
bool did_unschedule_;
- // Whether or not the buffer flip went through browser side on the last
- // swap or post sub buffer.
- bool did_flip_;
+ // The mailbox names used for texture exchange. Uses surface_handle as key.
+ gpu::gles2::MailboxName mailbox_names_[2];
+
+ // Holds a reference to the mailbox manager for cleanup.
+ scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager_;
DISALLOW_COPY_AND_ASSIGN(TextureImageTransportSurface);
};
diff --git a/content/port/browser/render_widget_host_view_port.h b/content/port/browser/render_widget_host_view_port.h
index 6d4806a..9fe93ac 100644
--- a/content/port/browser/render_widget_host_view_port.h
+++ b/content/port/browser/render_widget_host_view_port.h
@@ -244,8 +244,9 @@ class CONTENT_EXPORT RenderWidgetHostViewPort : public RenderWidgetHostView {
virtual void AcceleratedSurfaceNew(
int32 width_in_pixel,
int32 height_in_pixel,
- uint64 surface_id) {}
- virtual void AcceleratedSurfaceRelease(uint64 surface_id) {}
+ uint64 surface_id,
+ const std::string& mailbox_name) {}
+ virtual void AcceleratedSurfaceRelease() {}
#if defined(TOOLKIT_GTK)
virtual void CreatePluginContainer(gfx::PluginWindowHandle id) = 0;
diff --git a/gpu/command_buffer/service/mailbox_manager.cc b/gpu/command_buffer/service/mailbox_manager.cc
index ec7ad94..9019393 100644
--- a/gpu/command_buffer/service/mailbox_manager.cc
+++ b/gpu/command_buffer/service/mailbox_manager.cc
@@ -4,6 +4,8 @@
#include "gpu/command_buffer/service/mailbox_manager.h"
+#include <algorithm>
+
#include "base/rand_util.h"
#include "crypto/hmac.h"
#include "gpu/command_buffer/service/gl_utils.h"
@@ -12,6 +14,11 @@
namespace gpu {
namespace gles2 {
+MailboxName::MailboxName() {
+ std::fill(key, key + sizeof(key), 0);
+ std::fill(signature, signature + sizeof(signature), 0);
+}
+
MailboxManager::MailboxManager()
: hmac_(crypto::HMAC::SHA256),
textures_(std::ptr_fun(&MailboxManager::TargetNameLess)) {
@@ -19,9 +26,11 @@ MailboxManager::MailboxManager()
bool success = hmac_.Init(
base::StringPiece(private_key_, sizeof(private_key_)));
DCHECK(success);
+ DCHECK(!IsMailboxNameValid(MailboxName()));
}
MailboxManager::~MailboxManager() {
+ DCHECK(!textures_.size());
}
void MailboxManager::GenerateMailboxName(MailboxName* name) {
@@ -36,10 +45,8 @@ TextureDefinition* MailboxManager::ConsumeTexture(unsigned target,
TextureDefinitionMap::iterator it =
textures_.find(TargetName(target, name));
- if (it == textures_.end()) {
- NOTREACHED();
+ if (it == textures_.end())
return NULL;
- }
TextureDefinition* definition = it->second.definition.release();
textures_.erase(it);
diff --git a/gpu/command_buffer/service/mailbox_manager.h b/gpu/command_buffer/service/mailbox_manager.h
index 337998d..8f97dd4 100644
--- a/gpu/command_buffer/service/mailbox_manager.h
+++ b/gpu/command_buffer/service/mailbox_manager.h
@@ -30,7 +30,8 @@ class TextureManager;
// Identifies a mailbox where a texture definition can be stored for
// transferring textures between contexts that are not in the same context
// group. It is a random key signed with a hash of a private key.
-struct MailboxName {
+struct GPU_EXPORT MailboxName {
+ MailboxName();
GLbyte key[GL_MAILBOX_SIZE_CHROMIUM / 2];
GLbyte signature[GL_MAILBOX_SIZE_CHROMIUM / 2];
};
diff --git a/gpu/command_buffer/service/texture_definition.cc b/gpu/command_buffer/service/texture_definition.cc
index aba0dfa..e1c606f 100644
--- a/gpu/command_buffer/service/texture_definition.cc
+++ b/gpu/command_buffer/service/texture_definition.cc
@@ -27,6 +27,18 @@ TextureDefinition::LevelInfo::LevelInfo(GLenum target,
cleared(cleared) {
}
+TextureDefinition::LevelInfo::LevelInfo()
+ : target(0),
+ internal_format(0),
+ width(0),
+ height(0),
+ depth(0),
+ border(0),
+ format(0),
+ type(0),
+ cleared(true) {
+}
+
TextureDefinition::TextureDefinition(GLenum target,
GLuint service_id,
GLenum min_filter,
diff --git a/gpu/command_buffer/service/texture_definition.h b/gpu/command_buffer/service/texture_definition.h
index 0a9910b..7f7d3cd 100644
--- a/gpu/command_buffer/service/texture_definition.h
+++ b/gpu/command_buffer/service/texture_definition.h
@@ -19,7 +19,7 @@ namespace gles2 {
// context using the same GLShareGroup with the corresponding service ID.
class GPU_EXPORT TextureDefinition {
public:
- struct LevelInfo {
+ struct GPU_EXPORT LevelInfo {
LevelInfo(GLenum target,
GLenum internal_format,
GLsizei width,
@@ -29,6 +29,8 @@ class GPU_EXPORT TextureDefinition {
GLenum format,
GLenum type,
bool cleared);
+ LevelInfo();
+
GLenum target;
GLenum internal_format;
GLsizei width;
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index bc8491e..bdeea58 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -196,8 +196,8 @@ WebKit::WebGraphicsContext3D* DefaultContextFactory::CreateContextCommon(
}
Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor)
- : flipped_(flipped),
- size_(size),
+ : size_(size),
+ flipped_(flipped),
device_scale_factor_(device_scale_factor) {
}
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index fa621a3..1a2324f 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -112,14 +112,17 @@ class COMPOSITOR_EXPORT Texture : public base::RefCounted<Texture> {
virtual unsigned int PrepareTexture() = 0;
virtual WebKit::WebGraphicsContext3D* HostContext3D() = 0;
+ virtual void Consume(const gfx::Size& new_size) {}
+ virtual void Produce() {}
+
protected:
virtual ~Texture();
+ gfx::Size size_; // in pixel
private:
friend class base::RefCounted<Texture>;
bool flipped_;
- gfx::Size size_; // in pixel
float device_scale_factor_;
DISALLOW_COPY_AND_ASSIGN(Texture);
diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h
index 6dbc4e7..22a6756 100644
--- a/ui/gfx/native_widget_types.h
+++ b/ui/gfx/native_widget_types.h
@@ -278,30 +278,19 @@ struct GLSurfaceHandle {
: handle(kNullPluginWindow),
transport(false),
parent_gpu_process_id(0),
- parent_client_id(0),
- parent_context_id(0),
- sync_point(0) {
- parent_texture_id[0] = 0;
- parent_texture_id[1] = 0;
+ parent_client_id(0) {
}
GLSurfaceHandle(PluginWindowHandle handle_, bool transport_)
: handle(handle_),
transport(transport_),
parent_gpu_process_id(0),
- parent_client_id(0),
- parent_context_id(0),
- sync_point(0) {
- parent_texture_id[0] = 0;
- parent_texture_id[1] = 0;
+ parent_client_id(0) {
}
bool is_null() const { return handle == kNullPluginWindow && !transport; }
PluginWindowHandle handle;
bool transport;
int parent_gpu_process_id;
uint32 parent_client_id;
- uint32 parent_context_id;
- uint32 parent_texture_id[2];
- uint32 sync_point;
};
// AcceleratedWidget provides a surface to compositors to paint pixels.