On Oct 12, 2010, at 12:44 PM, James Robinson wrote:

> On Tue, Oct 12, 2010 at 9:47 AM, Chris Marrin <cmar...@apple.com> wrote:
> 
> On Oct 11, 2010, at 5:15 PM, Maciej Stachowiak wrote:
> 
> >
> > On Oct 11, 2010, at 4:03 PM, Chris Marrin wrote:
> >
> >>
> >> On Oct 11, 2010, at 3:35 PM, James Robinson wrote:
> >>
> >>> On Mon, Oct 11, 2010 at 3:15 PM, Chris Marrin <cmar...@apple.com> wrote:
> >>>
> >>> For accelerated 2D rendering we created a class called DrawingBuffer. 
> >>> This encapsulates the accelerated drawing surface (usually in the GPU) 
> >>> and the compositing layer used to display that surface on the page. The 
> >>> drawing surface (which is called a Framebuffer Object or FBO) is 
> >>> allocated by GraphicsContext3D, so DrawingBuffer needs a reference to 
> >>> that. Currently this is a weak reference. DrawingBuffer has a ::create() 
> >>> method and you pass the GraphicsContext3D to that method.
> >>>
> >>> If you destroy the GraphicsContext3D, DrawingBuffer has a stale pointer. 
> >>> If you were to try to destroy the DrawingBuffer it would attempt to use 
> >>> that pointer (to destroy its FBO) and crash or worse. Currently we have 
> >>> an implicit policy that you should never destroy a GraphicsContext3D 
> >>> before its DrawingBuffers are all destroyed. That works fine in the 
> >>> current use case, CanvasRenderingContext2D. And we can follow that same 
> >>> policy when in the future when we use DrawingBuffer in 
> >>> WebGLRenderingContext.
> >>>
> >>> My concern is that this sort of implicit policy can lead to errors in the 
> >>> future when other potential clients of these classes use them. So I 
> >>> posted https://bugs.webkit.org/show_bug.cgi?id=47501. In that patch I 
> >>> move the creation of DrawingBuffer to the GraphicsContext3D and keep back 
> >>> pointers to all the DrawingBuffers allocated so they can be cleaned up 
> >>> when GraphicsContext3D is destroyed. In talking to James R. he's 
> >>> concerned this adds unnecessary complexity and would rather stick with 
> >>> the implicit policy.
> >>>
> >>> So is this something I should be concerned about, or is an implicit 
> >>> policy sufficient in this case?
> >>>
> >>> Before somebody suggests it, I think Chris and I are in agreement that 
> >>> neither GraphicsContext3D nor DrawingBuffer should be RefCounted.  They 
> >>> both have clear single-ownership semantics.
> >>
> >> True, although Simon and I just chatted and he pointed out that 
> >> Refcounting both classes would solve this problem. The fact that 
> >> GraphicsContext3D wouldn't need a back pointer to DrawingBuffer means we 
> >> wouldn't have any circular references. I don't think the overhead of 
> >> refcounting is an issue here, so maybe that would be a simpler solution?
> >
> > I think having two independent objects that must be deleted in a specific 
> > order, or else you crash, is a hazardous design. APIs (even internal APIs) 
> > are better when they do not have a way to be "used wrong". So, I think this 
> > should be changed one way or the other.
> >
> > I have to say that to my taste, refcounting seems like a cleaner solution 
> > than ad-hoc weak pointers. I'm skeptical of the claim that refcounting is 
> > not good for a heavyweight object. If there's really a time when special 
> > resources (VRAM, etc) need to be freed at a known point in program code, 
> > then it may be better to have an explicit "close" type function instead of 
> > counting on the destructor. On the other hand, this might end up being 
> > roughly equivalent to the "clear backpointers" solution, but moves the 
> > complexity of being in a possibly-invalid state from DrawingBuffer to 
> > GraphicsContext3D.
> >
> > Either way, I am pretty confident that a design where objects must be 
> > destroyed in a specific order is not the best choice.
> 
> So it seems like we have two choices: 1) my current patch, which uses 
> backpointers to manage the lifetime of the weak pointers, or 2) refcounting. 
> My current approach has the advantage that the resources are cleared as soon 
> as the DrawingBuffer is destroyed. But it is more complex and therefore more 
> error prone. I think that complexity is manageable so that would be my 
> preferred implementation. But refcounting is simpler and my current patch has 
> a clear() method on DrawingBuffer which gets rid of all the resources. I 
> could leave that method and change to a refcounted model, so the author can 
> control when the resources are destroyed.
> 
> Another option would be to generalize the WeakPtr<T> implementation from that 
> patch into a generic class and use that.  Then that logic could be 
> implemented, reviewed and tested independently from the graphics code.  I 
> know that Maciej has expressed concern about this pattern in the past due to 
> the runtime cost it imposes.
> 
> Ref counting is a fairly blunt instrument but it would fit in best with the 
> rest of the codepath.

Weak pointers are both more complicated than refcounting and introduce a 
comparable or possibly even greater level of runtime cost. So if there's ever a 
problem that can be solved either way, I would tend to prefer refcounting.

Regards,
Maciej



_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev

Reply via email to