Bug 76715 - Refactor plugin drawing to be more data driven
Summary: Refactor plugin drawing to be more data driven
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-01-20 10:40 PST by Tim Dresser
Modified: 2012-02-02 17:35 PST (History)
6 users (show)

See Also:


Attachments
Patch (22.08 KB, patch)
2012-01-20 10:53 PST, Tim Dresser
no flags Details | Formatted Diff | Diff
Patch (24.89 KB, patch)
2012-01-23 11:07 PST, Tim Dresser
no flags Details | Formatted Diff | Diff
Patch (25.39 KB, patch)
2012-01-24 14:20 PST, Tim Dresser
no flags Details | Formatted Diff | Diff
Patch (19.19 KB, patch)
2012-01-30 08:43 PST, Tim Dresser
no flags Details | Formatted Diff | Diff
Patch (18.96 KB, patch)
2012-01-30 09:03 PST, Tim Dresser
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tim Dresser 2012-01-20 10:40:26 PST
From bug 73059:

CCLayerImpl-derived classes all currently handle drawing themselves internally, making direct GL calls.  This is problematic for several reasons.  Testing these layers is tricky because testing must be done at a mock GL interface level rather than at a higher abstract level.  It makes culling closely dependent on how each layer draws.  It also makes some optimizations like layer squashing impossible.

To fix this, CCLayerImpl-derived classes should produce a set of quads to render with some basic information in them about how they are to be drawn.  This list can then be processed and drawn in a more data-driven and abstract manner.


CCPluginLayerImpl still handles drawing internally and should be transitioned to the data-driven approach.
This builds on the initial refactor from bug 76274 and is closely related to bug 76635, which refactors CCCanvasLayerImpl.
Comment 1 Tim Dresser 2012-01-20 10:53:46 PST
Created attachment 123343 [details]
Patch
Comment 2 Adrienne Walker 2012-01-20 12:07:06 PST
Comment on attachment 123343 [details]
Patch

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

> Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp:682
> +struct PluginProgramBinding {

Whoa, I never knew this code existed.  Can you combine all four of these shader permutations? (If you want to make it a separate patch for clarity, feel welcome to.) It looks like PosTexStretch is PosTexTransform but with an identical translation and stretch for x and y.  And, "flip" could be considered just a change in tex transform, so there's no need for a separate shader for it or any of this boilerplate uniform-related template code.

> Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp:723
> +        ASSERT(extensions->supports("GL_CHROMIUQUAD->iosurface"));

Search/replace typo?

> Source/WebCore/platform/graphics/chromium/cc/CCPluginDrawQuad.h:63
> +    CCPluginLayerImpl* m_layer;

From a design perspective, I don't think quads should have backpointers back to their originating layers if it can be helped.  Architecturally, I'd be fine with the assumption that we call appendQuads prior to any draw call.  That would let you push all the io surface handling back into plugin layer, and simply give the quad a texture id.
Comment 3 Tim Dresser 2012-01-20 13:29:28 PST
> From a design perspective, I don't think quads should have backpointers back to their originating layers if it can be helped.  Architecturally, I'd be fine with the assumption that we call appendQuads prior to any draw call.  That would let you push all the io surface handling back into plugin layer, and simply give the quad a texture id.

It definitely would be a lot nicer if that backpointer wasn't there.

In appendQuads, I have no access to a GraphicsContext3D, so if the layer's ioSurface doesn't have a texture, I can't create one.

The ioSurface's textureId needs to be shared between all the quads. I don't see how I can share it without the backpointer, in the case where no texture exists when appendQuads is called.

I can move the ioSurfaceChanged logic into appendQuads, which is an improvement.
Comment 4 Adrienne Walker 2012-01-20 13:51:10 PST
(In reply to comment #3)
> > From a design perspective, I don't think quads should have backpointers back to their originating layers if it can be helped.  Architecturally, I'd be fine with the assumption that we call appendQuads prior to any draw call.  That would let you push all the io surface handling back into plugin layer, and simply give the quad a texture id.
> 
> It definitely would be a lot nicer if that backpointer wasn't there.
> 
> In appendQuads, I have no access to a GraphicsContext3D, so if the layer's ioSurface doesn't have a texture, I can't create one.

You could create one during PluginLayerChromium::updateCompositorResources, store it on the PluginLayerChromium, and sync it over to the CCPluginLayerChromium.  That's the path where all the other texture ids gets allocated.
Comment 5 Tim Dresser 2012-01-23 11:07:00 PST
Created attachment 123578 [details]
Patch
Comment 6 Adrienne Walker 2012-01-23 16:29:40 PST
Comment on attachment 123578 [details]
Patch

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

> Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp:66
> +        if (!m_ioSurfaceTextureId)
> +            m_ioSurfaceTextureId = rendererContext->createTexture();

If you're going to store the texture ID on the main thread, please use a ManagedTexture like other layer types.  Otherwise, we can't track this GPU memory or make sure we're not using a bogus texture id when the context is lost.  Additionally, you'll need to reserve it each frame and set m_ioSurfaceChanged if it stops being valid because the texture manager has evicted it.  VideoLayerChromium is a good model to use here.

> Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp:78
> +        extensions->texImageIOSurface2DCHROMIUM(Extensions3D::TEXTURE_RECTANGLE_ARB,
> +                                                m_ioSurfaceWidth,
> +                                                m_ioSurfaceHeight,
> +                                                m_ioSurfaceId,
> +                                                0);

I'm a little dubious about this texImage, since the texture id could be in use on the impl thread.  reveman: If this texture id comes from a managed texture, is that sufficient to work with atomic updates? Does this also need to get wrapped in a texture updater?
Comment 7 Tim Dresser 2012-01-24 14:20:46 PST
Created attachment 123808 [details]
Patch
Comment 8 David Reveman 2012-01-25 12:43:13 PST
(In reply to comment #6)
> (From update of attachment 123578 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=123578&action=review
> 
> > Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp:66
> > +        if (!m_ioSurfaceTextureId)
> > +            m_ioSurfaceTextureId = rendererContext->createTexture();
> 
> If you're going to store the texture ID on the main thread, please use a ManagedTexture like other layer types.  Otherwise, we can't track this GPU memory or make sure we're not using a bogus texture id when the context is lost.  Additionally, you'll need to reserve it each frame and set m_ioSurfaceChanged if it stops being valid because the texture manager has evicted it.  VideoLayerChromium is a good model to use here.
> 
> > Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp:78
> > +        extensions->texImageIOSurface2DCHROMIUM(Extensions3D::TEXTURE_RECTANGLE_ARB,
> > +                                                m_ioSurfaceWidth,
> > +                                                m_ioSurfaceHeight,
> > +                                                m_ioSurfaceId,
> > +                                                0);
> 
> I'm a little dubious about this texImage, since the texture id could be in use on the impl thread.  reveman: If this texture id comes from a managed texture, is that sufficient to work with atomic updates? Does this also need to get wrapped in a texture updater?

It's not sufficient for guaranteeing that these plugin layer updates are atomic. You'll need to use the "deleteTextureAfterCommit(texture->steal())" before reserving the texture for that. Btw, I'm failing to see where in this patch the texture is reserved.

It doesn't need to get wrapped in the texture updater right now. The patches I have in flight requires that but you don't need to worry about the yet.
Comment 9 Tim Dresser 2012-01-26 06:00:06 PST
On further testing, I found a reproducible crash on OSX.
It occurs using my most recent patch, both with and without reveman's suggestion.

I'll fix it, and submit a new patch with the bug fixed and reveman's suggestion incorporated.
Comment 10 Tim Dresser 2012-01-26 12:54:53 PST
Would it be preferable to create the layer's ioSurfaceTexture in the CCLayerImpl::willDraw function discussed in bug 76720? 

With that approach, all the texture management would be in the impl thread, which seems like it might be better. Would it be cleaner to use a ManagedTexture in that case, or not?
Comment 11 David Reveman 2012-01-26 13:43:14 PST
(In reply to comment #10)
> Would it be preferable to create the layer's ioSurfaceTexture in the CCLayerImpl::willDraw function discussed in bug 76720? 
> 
> With that approach, all the texture management would be in the impl thread, which seems like it might be better. Would it be cleaner to use a ManagedTexture in that case, or not?

I think that works well right now. The only problem I'm aware of is that in a future unified/out-of-process compositor we can't pass pointers around so textures and serialized properties set in pushPropertiesTo are likely the only way you can transfer data from a layer in the renderer to a layer in the compositor.
Comment 12 Tim Dresser 2012-01-27 07:31:10 PST
(In reply to comment #8)
> It's not sufficient for guaranteeing that these plugin layer updates are atomic. You'll need to use the "deleteTextureAfterCommit(texture->steal())" before reserving the texture for that. Btw, I'm failing to see where in this patch the texture is reserved.

It looks like deleteTextureAfterCommit doesn't do anything at the moment.
It appends the texture to the CCLayerTreeHost's m_deleteTextureAfterCommitList, but that list is never used...

Will this approach be adequate to ensure that the texImageIOSurface2DCHROMIUM call is safe?
Comment 13 Dana Jansens 2012-01-27 07:34:05 PST
The list is used to hold a reference to a texture during a commit, so that the texture doesn't disappear on draw/impl side and it can continue to draw with it, until the commit is finished and it isn't needed anymore.
Comment 14 Tim Dresser 2012-01-27 09:46:22 PST
When reserving the ioSurfaceTexture, I believe that I should be passing Extensions3D::TEXTURE_RECTANGLE_ARB as the format. With this format, the call to ManagedTexture::reserve reaches GraphicsContext3D::computeFormatAndTypeParameters and then chokes, because TEXTURE_RECTANGLE_ARB isn't expected.

I've tried just adding TEXTURE_RECTANGLE_ARB to the switch statement in computeFormatAndTypeParameters, but I end up with a GL_INVALID_ENUM error that I'm not sure how to handle.

Should I be trying to reserve the texture formatted TEXTURE_RECTANGLE_ARB, or am I approaching this incorrectly?
Comment 15 David Reveman 2012-01-27 10:01:58 PST
(In reply to comment #14)
> When reserving the ioSurfaceTexture, I believe that I should be passing Extensions3D::TEXTURE_RECTANGLE_ARB as the format. With this format, the call to ManagedTexture::reserve reaches GraphicsContext3D::computeFormatAndTypeParameters and then chokes, because TEXTURE_RECTANGLE_ARB isn't expected.
> 
> I've tried just adding TEXTURE_RECTANGLE_ARB to the switch statement in computeFormatAndTypeParameters, but I end up with a GL_INVALID_ENUM error that I'm not sure how to handle.
> 
> Should I be trying to reserve the texture formatted TEXTURE_RECTANGLE_ARB, or am I approaching this incorrectly?

Sorry, I should have looked more closely at this patch. TextureManager doesn't really support foreign texture formats and you can't really allocate the texture on your own when using a ManagedTexture.

I think you'll have to do your own double buffering for it to work correctly with incremental updates. Use two ioSurfaceTextureIds and flip between them for each update.
Comment 16 Tim Dresser 2012-01-27 11:05:06 PST
(In reply to comment #15)
> I think you'll have to do your own double buffering for it to work correctly with incremental updates. Use two ioSurfaceTextureIds and flip between them for each update.

From my understanding, this additional complexity has been introduced because we moved the texture creation code off the compositor thread.

It feels like things could be simplified significantly by moving everything back onto the compositor thread. 

Is there any advantage to allocating the ioSurfaceTexture on the main thread?

If I was to leave the allocation of the ioSurfaceTexture on the compositor thread, could I avoid the additional overhead of the ManagedTexture and double buffering?
Comment 17 Adrienne Walker 2012-01-27 11:16:25 PST
(In reply to comment #16)

> If I was to leave the allocation of the ioSurfaceTexture on the compositor thread, could I avoid the additional overhead of the ManagedTexture and double buffering?

Definitely.  You could do something similar to the video layer here, where you call something before appendQuads to create and upload the texture.
Comment 18 David Reveman 2012-01-27 11:17:35 PST
(In reply to comment #16)
> (In reply to comment #15)
> > I think you'll have to do your own double buffering for it to work correctly with incremental updates. Use two ioSurfaceTextureIds and flip between them for each update.
> 
> From my understanding, this additional complexity has been introduced because we moved the texture creation code off the compositor thread.
> 
> It feels like things could be simplified significantly by moving everything back onto the compositor thread. 
> 
> Is there any advantage to allocating the ioSurfaceTexture on the main thread?

The textures are always allocated on the compositor thread. It's just the management of textures that can be done on the main thread. As you can't use a ManagedTexture for these ioSurfaces, all texture handling has to happen on the compositor thread.

> 
> If I was to leave the allocation of the ioSurfaceTexture on the compositor thread, could I avoid the additional overhead of the ManagedTexture and double buffering?

You shouldn't use ManagedTexture but you still need double buffering to not get artifacts when incremental updates are enabled.
Comment 19 Tim Dresser 2012-01-27 11:21:15 PST
(In reply to comment #18)
> You shouldn't use ManagedTexture but you still need double buffering to not get artifacts when incremental updates are enabled.

It feels like double buffering is a separate issue from this refactor, should it be left as a separate bug?
Comment 20 David Reveman 2012-01-27 11:22:41 PST
(In reply to comment #19)
> (In reply to comment #18)
> > You shouldn't use ManagedTexture but you still need double buffering to not get artifacts when incremental updates are enabled.
> 
> It feels like double buffering is a separate issue from this refactor, should it be left as a separate bug?

Yes, that's fine with me. Just make sure you create a new bug for it before you close this one so we don't forget.
Comment 21 Tim Dresser 2012-01-30 08:43:25 PST
Created attachment 124560 [details]
Patch
Comment 22 Dana Jansens 2012-01-30 08:49:43 PST
Comment on attachment 124560 [details]
Patch

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

> Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:229
> +            layer->willDraw(m_layerRenderer.get());

willDraw() will be called on the layer both when it represents itself and when it represents a contributing RenderSurface. Is that what you want here?
Comment 23 Tim Dresser 2012-01-30 09:03:39 PST
Created attachment 124561 [details]
Patch
Comment 24 Adrienne Walker 2012-01-30 15:22:31 PST
Comment on attachment 124561 [details]
Patch

This looks good to me.  Thanks for taking the time to remove the layer backpointer.  :)
Comment 25 James Robinson 2012-02-02 16:32:20 PST
Comment on attachment 124561 [details]
Patch

Awesome, R=me
Comment 26 WebKit Review Bot 2012-02-02 17:35:47 PST
Comment on attachment 124561 [details]
Patch

Clearing flags on attachment: 124561

Committed r106607: <http://trac.webkit.org/changeset/106607>
Comment 27 WebKit Review Bot 2012-02-02 17:35:54 PST
All reviewed patches have been landed.  Closing bug.