[chromium-dev] Re: Mac/Linux heads-up: RenderWidgetHostView changes needed

2009-10-26 Thread Rohit Rao

Darin, Peter,
  I'm digging up this thread because the current Mac behavior turns
out to be problematic.  Cocoa sets up the proper clipping region
before calling drawRect:.  We can't just expand the invalid rect and
paint wherever we want, since Cocoa will ignore any drawing outside of
the original invalid rect.

I've coded up another possibility: if we detect a recursive call to
DidPaintRect(), defer the second paint until we return to the main
loop and the first drawRect: is completed.  This seems to work, but
I'd like confirmation that it's ok to do the second paint
asychronously.

The code is up at http://codereview.chromium.org/335029/show .  Does
this look like something that will cause problems or race conditions?

Thanks!
  Rohit

On Mon, Apr 13, 2009 at 12:13 PM, Darin Fisher da...@chromium.org wrote:
 On Mon, Apr 13, 2009 at 8:43 AM, Avi Drissman a...@chromium.org wrote:

 I'm still a little lost in this discussion. I'm repeatedly reading the
 code and the patch, and I'll get back to you when I fully understand it. But
 what I wanted to say is that there is a significant difference in the paint
 pipeline as it currently exists on the Mac compared to Win/Lin.

 On Win, DidPaintRect() calls Redraw() which calls
 RedrawWindow(...RDW_UPDATENOW...) which (AFAIK) does a synchronous draw via
 Win32 callback to OnPaint().

 On Lin, DidPaintRect() calls Paint() which blits via
 BackingStore::ShowRect(). Again, synchronously.

 On Mac, DidPaintRect() calls Redraw() which calls -[NSView
 setNeedsDisplayInRect:], setting the damaged rect in the view. The call
 returns, and sometime later, during the next pump of the message loop, Cocoa
 wakes up, decides to repaint all damaged windows, calls our -drawRect:,
 which then calls RenderWidgetHost::GetBackingStore().

 The Mac implementation is wrong.  On a single core machine, the renderer
 could starve the UI thread of the browser, preventing any pixels from ever
 being updated on the screen.  You need to change the Mac implementation to
 flush to the screen when DidPaintRect is not called withing drawRect /
 GetBackingStore.
 Prior to Peter's change it was not possible for DidPaintRect to be called
 from within GetBackingStore.  Now that is possible, so the consumer needs to
 take care.
 -Darin


 That gap prevents recursion. If for some reason GetBackingStore ends up
 causing a DidPaintRect() message, what will happen is:

 - Original DidPaintRect(), adds damage
  ... message loop ...
 - -drawRect:
 -- GetBackingStore()
 --- New DidPaintRect(), adds more damage
 -- blitting
  ... Cocoa clears the damage region, all of it

 Avi


 


--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: Mac/Linux heads-up: RenderWidgetHostView changes needed

2009-04-14 Thread Darin Fisher
This isn't just about message priorities.  It is also about thread
priorities.  There is no point in having the renderer produces new images of
the page if the browser process hasn't put them on the screen yet.

-Darin



On Mon, Apr 13, 2009 at 11:28 AM, Adam Langley a...@chromium.org wrote:


 On Mon, Apr 13, 2009 at 11:12 AM, Peter Kasting pkast...@google.com
 wrote:
  Perhaps not safe, but not worse.

 It's not that don't want to deal with this right now, it's that I
 believe that the current behaviour is correct on Linux. I've reread
 your patch and email and I haven't understood any arguments about why
 there's a problem. (I get that there might be something about the
 priority of Windows WM_PAINT messages that causes an issue, but that
 obviously doesn't apply with X.)


 AGL

 


--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: Mac/Linux heads-up: RenderWidgetHostView changes needed

2009-04-14 Thread Peter Kasting
On Mon, Apr 13, 2009 at 11:51 AM, Avi Drissman a...@chromium.org wrote:

 On Mon, Apr 13, 2009 at 2:47 PM, Peter Kasting pkast...@google.comwrote:

 it doesn't fire on Mac and at some point Avi will fix the Mac
 implementation.


 Side note: I now understand the issue this fixes and the fix to make the
 Mac impl compliant and to handle this one is item #2 on my todo list.


I have now committed the patch here, along with Adam Langley's Linux fix,
after the combination passed all three trybots.  r13681.

At this point I believe Avi's upcoming fix is the only remaining piece here.

PK

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: Mac/Linux heads-up: RenderWidgetHostView changes needed

2009-04-13 Thread Avi Drissman
I'm still a little lost in this discussion. I'm repeatedly reading the code
and the patch, and I'll get back to you when I fully understand it. But what
I wanted to say is that there is a significant difference in the paint
pipeline as it currently exists on the Mac compared to Win/Lin.

On Win, DidPaintRect() calls Redraw() which calls
RedrawWindow(...RDW_UPDATENOW...) which (AFAIK) does a synchronous draw via
Win32 callback to OnPaint().

On Lin, DidPaintRect() calls Paint() which blits via
BackingStore::ShowRect(). Again, synchronously.

On Mac, DidPaintRect() calls Redraw() which calls -[NSView
setNeedsDisplayInRect:], setting the damaged rect in the view. The call
returns, and sometime later, during the next pump of the message loop, Cocoa
wakes up, decides to repaint all damaged windows, calls our -drawRect:,
which then calls RenderWidgetHost::GetBackingStore().

That gap prevents recursion. If for some reason GetBackingStore ends up
causing a DidPaintRect() message, what will happen is:

- Original DidPaintRect(), adds damage
 ... message loop ...
- -drawRect:
-- GetBackingStore()
--- New DidPaintRect(), adds more damage
-- blitting
 ... Cocoa clears the damage region, all of it

Avi

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: Mac/Linux heads-up: RenderWidgetHostView changes needed

2009-04-13 Thread Darin Fisher
On Mon, Apr 13, 2009 at 8:43 AM, Avi Drissman a...@chromium.org wrote:

 I'm still a little lost in this discussion. I'm repeatedly reading the code
 and the patch, and I'll get back to you when I fully understand it. But what
 I wanted to say is that there is a significant difference in the paint
 pipeline as it currently exists on the Mac compared to Win/Lin.

 On Win, DidPaintRect() calls Redraw() which calls
 RedrawWindow(...RDW_UPDATENOW...) which (AFAIK) does a synchronous draw via
 Win32 callback to OnPaint().

 On Lin, DidPaintRect() calls Paint() which blits via
 BackingStore::ShowRect(). Again, synchronously.

 On Mac, DidPaintRect() calls Redraw() which calls -[NSView
 setNeedsDisplayInRect:], setting the damaged rect in the view. The call
 returns, and sometime later, during the next pump of the message loop, Cocoa
 wakes up, decides to repaint all damaged windows, calls our -drawRect:,
 which then calls RenderWidgetHost::GetBackingStore().


The Mac implementation is wrong.  On a single core machine, the renderer
could starve the UI thread of the browser, preventing any pixels from ever
being updated on the screen.  You need to change the Mac implementation to
flush to the screen when DidPaintRect is not called withing drawRect /
GetBackingStore.

Prior to Peter's change it was not possible for DidPaintRect to be called
from within GetBackingStore.  Now that is possible, so the consumer needs to
take care.

-Darin





 That gap prevents recursion. If for some reason GetBackingStore ends up
 causing a DidPaintRect() message, what will happen is:

 - Original DidPaintRect(), adds damage
  ... message loop ...
 - -drawRect:
 -- GetBackingStore()
 --- New DidPaintRect(), adds more damage
 -- blitting
  ... Cocoa clears the damage region, all of it

 Avi


--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: Mac/Linux heads-up: RenderWidgetHostView changes needed

2009-04-13 Thread Avi Drissman
On Mon, Apr 13, 2009 at 12:13 PM, Darin Fisher da...@chromium.org wrote:

 You need to change the Mac implementation to flush to the screen when
 DidPaintRect is not called withing drawRect / GetBackingStore.


I'll put it on my list of things to do. (First is fixing a bug that is
causing drawing to not work at all.)

Research time, though, how to do a direct draw in Cocoa.

Avi

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: Mac/Linux heads-up: RenderWidgetHostView changes needed

2009-04-13 Thread Amanda Walker

On Mon, Apr 13, 2009 at 12:13 PM, Darin Fisher da...@chromium.org wrote:
 The Mac implementation is wrong.  On a single core machine, the renderer
 could starve the UI thread of the browser, preventing any pixels from ever
 being updated on the screen.

That seems wrong--the OS-prompted draw should be just blitting from
the backing store, right?  But I'm more concerned about this
starvation problem--the renderer should not be able to starve the UI
thread under any circumstances--we always need to return to the main
runloop every second or two or the OS will decide we're unresponsive
and beachball.   What code path can cause this?

--Amanda

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: Mac/Linux heads-up: RenderWidgetHostView changes needed

2009-04-13 Thread Peter Kasting
On Mon, Apr 13, 2009 at 10:59 AM, Adam Langley a...@chromium.org wrote:

 On Fri, Apr 10, 2009 at 1:16 PM, Peter Kasting pkast...@google.com
 wrote:
  I strongly suggest picking Darin's brain directly for more detail as he
 has
  a stronger grasp of this than I do :)

 I don't want to block landing this patch because of Linux. However, I
 would currently just #ifdef in the old behaviour which I believe is
 correct for Linux. Certainly doing that is a safe.


Perhaps not safe, but not worse.

However, I'd rather wait to land than #ifdef.  The old behavior is certainly
wrong (did you not see my + Darin's emails above?), and ifdefs are ugly.
 There's nothing urgently pushing me to get this in in the next few hours.

PK

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: Mac/Linux heads-up: RenderWidgetHostView changes needed

2009-04-13 Thread Adam Langley

On Mon, Apr 13, 2009 at 11:12 AM, Peter Kasting pkast...@google.com wrote:
 Perhaps not safe, but not worse.

It's not that don't want to deal with this right now, it's that I
believe that the current behaviour is correct on Linux. I've reread
your patch and email and I haven't understood any arguments about why
there's a problem. (I get that there might be something about the
priority of Windows WM_PAINT messages that causes an issue, but that
obviously doesn't apply with X.)


AGL

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: Mac/Linux heads-up: RenderWidgetHostView changes needed

2009-04-13 Thread Peter Kasting
On Mon, Apr 13, 2009 at 11:28 AM, Adam Langley a...@chromium.org wrote:

 It's not that don't want to deal with this right now, it's that I
 believe that the current behaviour is correct on Linux.


Yes, I grasped that.

I've reread
 your patch and email and I haven't understood any arguments about why
 there's a problem. (I get that there might be something about the
 priority of Windows WM_PAINT messages that causes an issue, but that
 obviously doesn't apply with X.)


The reason I had to write a patch at all is a cross-platform issue, not a
Windows-specific one.  The Windows-specific stuff in the comments is merely
an example of why an API like DidPaintRect() is useful in the first place,
but we're not adding that API in this patch, just explaining what's going
on.

The issue I'm fixing is that if we get an updated rect from the renderer
while DidPaintRect() is disabled, we don't repaint any extra damaged area in
that rect until the next time it happens to get damaged, because we don't
send anyone any notifications.  This is because we were putting in an
anti-recursion check in the model when instead it should have been in the
view.

Fixing this means that any platform that (correctly) synchrously paints from
DidPaintRect() is now at risk of infinite recursion, and the new DCHECK is
designed to detect this.  It fires on Linux because Linux was doing the
right thing before; it doesn't fire on Mac and at some point Avi will fix
the Mac implementation.

To fix _this_ issue the platform-specific code needs to have its own
anti-recursion check, as Windows now has.  This is what I'm asking Linux to
write.  You write one by detecting (inside DidPaintRect()) that you're
already in a paint and not recursively painting again.

PK

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: Mac/Linux heads-up: RenderWidgetHostView changes needed

2009-04-13 Thread Adam Langley
On Mon, Apr 13, 2009 at 11:47 AM, Peter Kasting pkast...@google.com wrote:
 The issue I'm fixing is that if we get an updated rect from the renderer
 while DidPaintRect() is disabled, we don't repaint any extra damaged area in
 that rect until the next time it happens to get damaged, because we don't
 send anyone any notifications.  This is because we were putting in an
 anti-recursion check in the model when instead it should have been in the
 view.

I always thought that, when we paint without a backing store, we're
painting the whole thing so this isn't an issue.

After patching in your change, the following makes Linux work for me. Hopefully
I have the correct end of the stick this time.

Gmail will probably mangle this patch, so it's attached as well.

diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
index 32135f9..eb1b966 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -159,6 +159,7 @@
RenderWidgetHostViewGtk::RenderWidgetHostViewGtk(RenderWidgetHost*
widget_host)
   parent_(NULL),
   popup_signal_id_(0),
   activatable_(true),
+  about_to_validate_and_paint_(false),
   is_loading_(false) {
   host_-set_view(this);
 }
@@ -277,7 +278,10 @@ void RenderWidgetHostViewGtk::IMEUpdateStatus(int control,
 }

 void RenderWidgetHostViewGtk::DidPaintRect(const gfx::Rect rect) {
-  Paint(rect);
+  if (about_to_validate_and_paint_)
+invalid_rect_ = invalid_rect_.Union(rect);
+  else
+Paint(rect);
 }

 void RenderWidgetHostViewGtk::DidScrollRect(const gfx::Rect rect, int dx,
@@ -338,7 +342,13 @@ void
RenderWidgetHostViewGtk::PasteFromSelectionClipboard() {
 }

 void RenderWidgetHostViewGtk::Paint(const gfx::Rect damage_rect) {
+  DCHECK(!about_to_validate_and_paint_);
+
+  invalid_rect_ = damage_rect;
+  about_to_validate_and_paint_ = true;
   BackingStore* backing_store = host_-GetBackingStore();
+  // Calling GetBackingStore maybe have changed |invalid_rect_|...
+  about_to_validate_and_paint_ = false;

   GdkWindow* window = view_.get()-window;
   if (backing_store) {
@@ -347,7 +357,7 @@ void RenderWidgetHostViewGtk::Paint(const
gfx::Rect damage_rect) {
 // Destroy()ed yet and it receives paint messages...
 if (window) {
   backing_store-ShowRect(
-  damage_rect, x11_util::GetX11WindowFromGtkWidget(view_.get()));
+  invalid_rect_, x11_util::GetX11WindowFromGtkWidget(view_.get()));
 }
   } else {
 if (window)
diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.h
b/chrome/browser/renderer_host/render_widget_host_view_gtk.h
index 215549d..cd49a8d 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.h
@@ -101,6 +101,12 @@ class RenderWidgetHostViewGtk : public
RenderWidgetHostView {
   // activatable popup: select dropdown. Example of non-activatable popup:
   // form autocomplete.
   bool activatable_;
+  // This is true when we are currently painting and thus should handle extra
+  // paint requests by expanding the invalid rect rather than actually
+  // painting.
+  bool about_to_validate_and_paint_;
+  // This is the rectangle which we'll paint.
+  gfx::Rect invalid_rect_;

   // Whether we are currently loading.
   bool is_loading_;

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



patch
Description: Binary data


[chromium-dev] Re: Mac/Linux heads-up: RenderWidgetHostView changes needed

2009-04-10 Thread Adam Langley

On Fri, Apr 10, 2009 at 12:28 PM, Peter Kasting pkast...@google.com wrote:
 Please let me know if you understand this patch enough to make appropriate
 changes, and how to coordinate landing various bits so I don't break anyone.
 PK

I patched this in and started fixing things and ended up writing the
reverse of your patch.

Myabe you want to #ifdef around your changes?

I don't get why you want to do this. We have this situation:

X sends an expose message to us
We ask for a BackingStore
We don't have one, so we start a timed wait on the renderer to send us a paint
We get the paint, so we create the backing store and copy the bitmap to it.
With your patch:
  We then call back into GTK to invalidate the rect again! Error!

Your comment suggests that you want to do more than invalidate in
DidPaintRect because of WM_PAINT starvation. I don't get how this
helps you. In the case that you're talking about, we're dealing with a
message from the renderer without the expose handling on the stack and
then that guard that you removed doesn't even come into play.


AGL

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: Mac/Linux heads-up: RenderWidgetHostView changes needed

2009-04-10 Thread Peter Kasting
On Fri, Apr 10, 2009 at 1:07 PM, Adam Langley a...@chromium.org wrote:

 X sends an expose message to us
 We ask for a BackingStore
 We don't have one, so we start a timed wait on the renderer to send us a
 paint
 We get the paint, so we create the backing store and copy the bitmap to it.
 With your patch:
  We then call back into GTK to invalidate the rect again! Error!


The question is, has GTK already validated the rect it sent us to paint?  If
so, we should just enlarge the rect that the paint function will redraw; if
not, we should both do that and ensure that that larger rect gets validated.
 (On Windows, the case is the latter.)  In neither case do we really want to
come out of painting with a dirty rect from this.

Your comment suggests that you want to do more than invalidate in
 DidPaintRect because of WM_PAINT starvation. I don't get how this
 helps you. In the case that you're talking about, we're dealing with a
 message from the renderer without the expose handling on the stack and
 then that guard that you removed doesn't even come into play.


When you paint, the paint function will ask for the updated backing store,
which potentially needs to go to the renderer and wait (if it is dirty).
 When it comes back, with the guards removed, you call DidPaintRect(), which
calls Paint(), which can recurse because the backing store may still need
updating (e.g. we got an ack of a previous resize but another is waiting, or
similar).  Darin came up with some thought experiments in which this
recursion happens effectively infinitely.  On the other hand, if you fix
this by making DidPaintRect() not paint, then you'll invalidate the area,
but potentially never get a paint callback unless your event system
guarantees that you'll paint within a certain period no matter how much the
renderer is eating the CPU and spamming you with updates.

In short, DidPaintRect() painting rate-limits the renderer from starving
paints, and being clever about how we paint and invalidate prevents infinite
recursion and/or overpainting during this.

I strongly suggest picking Darin's brain directly for more detail as he has
a stronger grasp of this than I do :)

PK

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---