| Index: chrome/browser/renderer_host/render_widget_host_view_mac.mm
|
| ===================================================================
|
| --- chrome/browser/renderer_host/render_widget_host_view_mac.mm (revision 67289)
|
| +++ chrome/browser/renderer_host/render_widget_host_view_mac.mm (working copy)
|
| @@ -24,6 +24,7 @@
|
| #include "chrome/browser/browser_trial.h"
|
| #import "chrome/browser/cocoa/rwhvm_editcommand_helper.h"
|
| #import "chrome/browser/cocoa/view_id_util.h"
|
| +#include "chrome/browser/gpu_process_host.h"
|
| #include "chrome/browser/plugin_process_host.h"
|
| #include "chrome/browser/renderer_host/backing_store_mac.h"
|
| #include "chrome/browser/renderer_host/render_process_host.h"
|
| @@ -33,6 +34,7 @@
|
| #include "chrome/common/chrome_switches.h"
|
| #include "chrome/common/native_web_keyboard_event.h"
|
| #include "chrome/common/edit_command.h"
|
| +#include "chrome/common/gpu_messages.h"
|
| #include "chrome/common/plugin_messages.h"
|
| #include "chrome/common/render_messages.h"
|
| #include "skia/ext/platform_canvas.h"
|
| @@ -170,9 +172,22 @@
|
| RenderWidgetHostViewMac* renderWidgetHostView_; // weak
|
| gfx::PluginWindowHandle pluginHandle_; // weak
|
|
|
| - // True if the backing IO surface was updated since we last painted.
|
| - BOOL surfaceWasSwapped_;
|
| + // The number of swap buffers calls that have been requested by the
|
| + // GPU process, or a monotonically increasing number of calls to
|
| + // updateSwapBuffersCount:fromRenderer:routeId: if the update came
|
| + // from an accelerated plugin.
|
| + uint64 swapBuffersCount_;
|
| + // The number of swap buffers calls that have been processed by the
|
| + // display link thread. This is only used with the GPU process
|
| + // update path.
|
| + volatile uint64 acknowledgedSwapBuffersCount_;
|
|
|
| + // Auxiliary information needed to formulate an acknowledgment to
|
| + // the GPU process. These are constant after the first message.
|
| + // These are both zero for updates coming from a plugin process.
|
| + volatile int rendererId_;
|
| + volatile int32 routeId_;
|
| +
|
| // Cocoa methods can only be called on the main thread, so have a copy of the
|
| // view's size, since it's required on the displaylink thread.
|
| NSSize cachedSize_;
|
| @@ -186,6 +201,15 @@
|
| pluginHandle:(gfx::PluginWindowHandle)pluginHandle;
|
| - (void)drawView;
|
|
|
| +// Updates the number of swap buffers calls that have been requested.
|
| +// This is currently called with non-zero values only in response to
|
| +// updates from the GPU process. For accelerated plugins, all zeros
|
| +// are passed, and the view takes this as a hint that no flow control
|
| +// or acknowledgment of the swap buffers are desired.
|
| +- (void)updateSwapBuffersCount:(uint64)count
|
| + fromRenderer:(int)rendererId
|
| + routeId:(int32)routeId;
|
| +
|
| // NSViews autorelease subviews when they die. The RWHVMac gets destroyed when
|
| // RHWVCocoa gets dealloc'd, which means the AcceleratedPluginView child views
|
| // can be around a little longer than the RWHVMac. This is called when the
|
| @@ -193,14 +217,10 @@
|
| - (void)onRenderWidgetHostViewGone;
|
|
|
| // This _must_ be atomic, since it's accessed from several threads.
|
| -@property BOOL surfaceWasSwapped;
|
| -
|
| -// This _must_ be atomic, since it's accessed from several threads.
|
| @property NSSize cachedSize;
|
| @end
|
|
|
| @implementation AcceleratedPluginView
|
| -@synthesize surfaceWasSwapped = surfaceWasSwapped_;
|
| @synthesize cachedSize = cachedSize_;
|
|
|
| - (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime {
|
| @@ -208,11 +228,22 @@
|
| // called from a background thread.
|
| base::mac::ScopedNSAutoreleasePool pool;
|
|
|
| - if (![self surfaceWasSwapped])
|
| + bool sendAck = (rendererId_ != 0 || routeId_ != 0);
|
| + uint64 currentSwapBuffersCount = swapBuffersCount_;
|
| + if (currentSwapBuffersCount == acknowledgedSwapBuffersCount_) {
|
| return kCVReturnSuccess;
|
| + }
|
|
|
| [self drawView];
|
| - [self setSurfaceWasSwapped:NO];
|
| +
|
| + acknowledgedSwapBuffersCount_ = currentSwapBuffersCount;
|
| + if (sendAck && renderWidgetHostView_) {
|
| + renderWidgetHostView_->AcknowledgeSwapBuffers(
|
| + rendererId_,
|
| + routeId_,
|
| + acknowledgedSwapBuffersCount_);
|
| + }
|
| +
|
| return kCVReturnSuccess;
|
| }
|
|
|
| @@ -235,6 +266,10 @@
|
| renderWidgetHostView_ = r;
|
| pluginHandle_ = pluginHandle;
|
| cachedSize_ = NSZeroSize;
|
| + swapBuffersCount_ = 0;
|
| + acknowledgedSwapBuffersCount_ = 0;
|
| + rendererId_ = 0;
|
| + routeId_ = 0;
|
|
|
| [self setAutoresizingMask:NSViewMaxXMargin|NSViewMinYMargin];
|
|
|
| @@ -290,9 +325,25 @@
|
| }
|
|
|
| CGLFlushDrawable(cglContext_);
|
| + CGLSetCurrentContext(0);
|
| CGLUnlockContext(cglContext_);
|
| }
|
|
|
| +- (void)updateSwapBuffersCount:(uint64)count
|
| + fromRenderer:(int)rendererId
|
| + routeId:(int32)routeId {
|
| + if (rendererId == 0 && routeId == 0) {
|
| + // This notification is coming from a plugin process, for which we
|
| + // don't have flow control implemented right now. Fake up a swap
|
| + // buffers count so that we can at least skip useless renders.
|
| + ++swapBuffersCount_;
|
| + } else {
|
| + rendererId_ = rendererId;
|
| + routeId_ = routeId;
|
| + swapBuffersCount_ = count;
|
| + }
|
| +}
|
| +
|
| - (void)onRenderWidgetHostViewGone {
|
| if (!renderWidgetHostView_)
|
| return;
|
| @@ -340,6 +391,7 @@
|
| NSSize size = [self frame].size;
|
| glViewport(0, 0, size.width, size.height);
|
|
|
| + CGLSetCurrentContext(0);
|
| CGLUnlockContext(cglContext_);
|
| globalFrameDidChangeCGLLockCount_--;
|
|
|
| @@ -938,7 +990,11 @@
|
| }
|
|
|
| void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped(
|
| - gfx::PluginWindowHandle window, uint64 surface_id) {
|
| + gfx::PluginWindowHandle window,
|
| + uint64 surface_id,
|
| + int renderer_id,
|
| + int32 route_id,
|
| + uint64 swap_buffers_count) {
|
| CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| PluginViewMap::iterator it = plugin_views_.find(window);
|
| DCHECK(plugin_views_.end() != it);
|
| @@ -953,7 +1009,9 @@
|
| // The surface is hidden until its first paint, to not show gargabe.
|
| if (plugin_container_manager_.SurfaceShouldBeVisible(window))
|
| [view setHidden:NO];
|
| - [view setSurfaceWasSwapped:YES];
|
| + [view updateSwapBuffersCount:swap_buffers_count
|
| + fromRenderer:renderer_id
|
| + routeId:route_id];
|
| }
|
|
|
| void RenderWidgetHostViewMac::UpdateRootGpuViewVisibility(
|
| @@ -988,6 +1046,43 @@
|
| }
|
| }
|
|
|
| +namespace {
|
| +class BuffersSwappedAcknowledger : public Task {
|
| + public:
|
| + BuffersSwappedAcknowledger(
|
| + int renderer_id,
|
| + int32 route_id,
|
| + uint64 swap_buffers_count)
|
| + : renderer_id_(renderer_id),
|
| + route_id_(route_id),
|
| + swap_buffers_count_(swap_buffers_count) {
|
| + }
|
| +
|
| + void Run() {
|
| + GpuProcessHost::Get()->Send(
|
| + new GpuMsg_AcceleratedSurfaceBuffersSwappedACK(
|
| + renderer_id_, route_id_, swap_buffers_count_));
|
| + }
|
| +
|
| + private:
|
| + int renderer_id_;
|
| + int32 route_id_;
|
| + uint64 swap_buffers_count_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(BuffersSwappedAcknowledger);
|
| +};
|
| +} // anonymous namespace
|
| +
|
| +void RenderWidgetHostViewMac::AcknowledgeSwapBuffers(
|
| + int renderer_id,
|
| + int32 route_id,
|
| + uint64 swap_buffers_count) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + new BuffersSwappedAcknowledger(
|
| + renderer_id, route_id, swap_buffers_count));
|
| +}
|
| +
|
| void RenderWidgetHostViewMac::GpuRenderingStateDidChange() {
|
| CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| if (GetRenderWidgetHost()->is_gpu_rendering_active()) {
|
|
|