Bug 95379 - [chromium] Register/unregister contents layers with GraphicsLayerChromium
Summary: [chromium] Register/unregister contents layers with GraphicsLayerChromium
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: James Robinson
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-08-29 14:14 PDT by James Robinson
Modified: 2012-08-29 18:33 PDT (History)
12 users (show)

See Also:


Attachments
Patch (18.72 KB, patch)
2012-08-29 14:32 PDT, James Robinson
no flags Details | Formatted Diff | Diff
with test (19.94 KB, patch)
2012-08-29 15:59 PDT, James Robinson
enne: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description James Robinson 2012-08-29 14:14:25 PDT
[chromium] Register/unregister contents layers with GraphicsLayerChromium
Comment 1 James Robinson 2012-08-29 14:32:54 PDT
Created attachment 161319 [details]
Patch
Comment 2 James Robinson 2012-08-29 14:35:01 PDT
Enne's the most likely reviewer for this change, but they're out on vacation for a few days and this is a fairly frequent crasher on dev so could one of you fine folks take a look?  See the ChangeLog and http://code.google.com/p/chromium/issues/detail?id=144951 for context.  I'm still working on producing a good, reliable layout test to hit this case.  This is (sadly) yet another WeakPtr implementation, but this is WebKit where we spend all our time reimplementing WeakPtr.  I'm using the fact that WebLayers have unique, non-repeating IDs to do object identity checks to avoid doing a fully general WeakPtr<T> implementation.
Comment 3 Adam Barth 2012-08-29 14:41:21 PDT
There's no way that I can check whether this patch is correct.  If no one feels like they know enough to review it, maybe we should land it TBR=enne?
Comment 4 Dirk Pranke 2012-08-29 15:21:16 PDT
I'm way out of my depth on this patch, so I'm punting as well ... sorry!
Comment 5 James Robinson 2012-08-29 15:48:11 PDT
Other approaches:

1.) reorder the RenderLayerBacking calls such that we always get a setContentsTo..() call before any calls that might want to mutate our contentsLayer.

2.) buffer state on GraphicsLayerChromium instead of pushing straight down to m_contentsLayer and only set state when we know we're in a "steady state"

(1) Seems good generally but tricky to do and tricky to maintain since nobody else would be depending on this particular behavior

(2) Requires inventing a new buffering+sync concept to GraphicsLayerChromium and defining a proper steady state timing. This is plausible but also a bit tricky since it means you have to be really careful about when you can touch certain bits of state and when things are out-of-sync.  We'd also have to keep redundant copies around of various bits of data.
Comment 6 James Robinson 2012-08-29 15:48:14 PDT
Other approaches:

1.) reorder the RenderLayerBacking calls such that we always get a setContentsTo..() call before any calls that might want to mutate our contentsLayer.

2.) buffer state on GraphicsLayerChromium instead of pushing straight down to m_contentsLayer and only set state when we know we're in a "steady state"

(1) Seems good generally but tricky to do and tricky to maintain since nobody else would be depending on this particular behavior

(2) Requires inventing a new buffering+sync concept to GraphicsLayerChromium and defining a proper steady state timing. This is plausible but also a bit tricky since it means you have to be really careful about when you can touch certain bits of state and when things are out-of-sync.  We'd also have to keep redundant copies around of various bits of data.
Comment 7 Nat Duca 2012-08-29 15:54:37 PDT
Would a "wilLDie" on the layer delegate be helpful here? Iirw, glc sets a delegate on the content ...
Comment 8 James Robinson 2012-08-29 15:59:02 PDT
Created attachment 161345 [details]
with test
Comment 9 Nat Duca 2012-08-29 16:07:23 PDT
Talked offline with James. I'm happy with this approach, all things considered. The key thing is exploding if a person-who-creates-a-new layer forgets to register, which is there.
Comment 10 James Robinson 2012-08-29 16:11:39 PDT
For the record, comment #7's suggestion is valid.  The question basically boils down to whether it's better to implement weakptr-type semantics as part of the WebLayer interface - either through a destruction listener or some other mechanism - or keep it all contained in WebCore.  This patch does the latter, and hopefully the ASSERT()s are enough to keep folks in line.
Comment 11 Adrienne Walker 2012-08-29 17:36:12 PDT
Comment on attachment 161345 [details]
with test

View in context: https://bugs.webkit.org/attachment.cgi?id=161345&action=review

This is causing crashes, so I'm going to R+ it since the solution looks good to me in general.  I have a few comments, that you're free to address or not.

> Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp:295
> +    clearContentsLayerIfUnregistered();
> +    if (m_contentsLayer)

Can you wrap this common access pattern in some sort of contentsLayerSafe() function or somesuch?

> Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp:513
> +    ASSERT(s_registeredLayerSet);
> +    ASSERT(s_registeredLayerSet->contains(layer->id()));

I think the asserts in register and unregister should be CRASHes instead.  If any of these happen, you'll potentially have bogus content layer pointers lying around that point to deleted memory and that feels like a security issue.

> Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h:118
> -    virtual void setContentsToMedia(PlatformLayer*);
> -    virtual void setContentsToCanvas(PlatformLayer*);
> +    virtual void setContentsToMedia(WebKit::WebLayer*);
> +    virtual void setContentsToCanvas(WebKit::WebLayer*);

Why?
Comment 12 James Robinson 2012-08-29 18:03:41 PDT
(In reply to comment #11)
> (From update of attachment 161345 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=161345&action=review
> 
> This is causing crashes, so I'm going to R+ it since the solution looks good to me in general.  I have a few comments, that you're free to address or not.
> 
> > Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp:295
> > +    clearContentsLayerIfUnregistered();
> > +    if (m_contentsLayer)
> 
> Can you wrap this common access pattern in some sort of contentsLayerSafe() function or somesuch?

Yup, I think so. Good idea.

> 
> > Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp:513
> > +    ASSERT(s_registeredLayerSet);
> > +    ASSERT(s_registeredLayerSet->contains(layer->id()));
> 
> I think the asserts in register and unregister should be CRASHes instead.  If any of these happen, you'll potentially have bogus content layer pointers lying around that point to deleted memory and that feels like a security issue.

Sounds good.

> 
> > Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h:118
> > -    virtual void setContentsToMedia(PlatformLayer*);
> > -    virtual void setContentsToCanvas(PlatformLayer*);
> > +    virtual void setContentsToMedia(WebKit::WebLayer*);
> > +    virtual void setContentsToCanvas(WebKit::WebLayer*);
> 
> Why?

No reason - I'll change them back.
Comment 13 James Robinson 2012-08-29 18:33:50 PDT
Committed r127077: <http://trac.webkit.org/changeset/127077>