diff options
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, ®ions_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. |