Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(871)

Unified Diff: chrome/browser/renderer_host/render_widget_host_view_mac.mm

Issue 5317007: Add flow control between renderer and GPU processes, and, on Mac OS X,... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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()) {

Powered by Google App Engine
This is Rietveld 408576698