Bug 56514 - [chromium] Properly reset VideoLayerChromium textures after lost renderer context
Summary: [chromium] Properly reset VideoLayerChromium textures after lost renderer con...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: 528+ (Nightly build)
Hardware: Other OS X 10.5
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-03-16 18:32 PDT by Victoria Kirst
Modified: 2011-03-22 18:13 PDT (History)
4 users (show)

See Also:


Attachments
Patch (3.00 KB, patch)
2011-03-16 18:44 PDT, Victoria Kirst
no flags Details | Formatted Diff | Diff
Patch (14.71 KB, patch)
2011-03-18 15:56 PDT, Victoria Kirst
no flags Details | Formatted Diff | Diff
Patch (16.74 KB, patch)
2011-03-18 16:21 PDT, Victoria Kirst
no flags Details | Formatted Diff | Diff
Patch (16.89 KB, patch)
2011-03-22 16:17 PDT, Victoria Kirst
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Victoria Kirst 2011-03-16 18:32:02 PDT
[chromium] Properly reset VideoLayerChromium textures after lost renderer context
Comment 1 Victoria Kirst 2011-03-16 18:44:02 PDT
Created attachment 86017 [details]
Patch
Comment 2 Kenneth Russell 2011-03-16 18:55:50 PDT
Comment on attachment 86017 [details]
Patch

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

> Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp:96
> +    if (replacingRenderer)
> +        resetFrameParameters();

LayerChromium::setLayerRenderer() will call cleanupResources() if (layerRenderer() && layerRenderer() != renderer), which will call releaseCurrentFrame() which contains a call to resetFrameParameters(). Doesn't that make this override redundant?
Comment 3 Victoria Kirst 2011-03-16 19:24:36 PDT
(In reply to comment #2)
> (From update of attachment 86017 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=86017&action=review
> 
> > Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp:96
> > +    if (replacingRenderer)
> > +        resetFrameParameters();
> 
> LayerChromium::setLayerRenderer() will call cleanupResources() if (layerRenderer() && layerRenderer() != renderer), which will call releaseCurrentFrame() which contains a call to resetFrameParameters(). Doesn't that make this override redundant?

Good question! It's not redundant because m_currentFrame can be null, and in that case releaseCurrentFrame() will not call resetFrameParameters() because it exits out early.

And actually, saveCurrentFrame/releaseCurrentFrame are hooks to be used when we have hardware decoding implemented in Chrome. Right now we don't have hardware decode implemented, so m_currentFrame is _always_ null.
Comment 4 Kenneth Russell 2011-03-17 14:00:34 PDT
Comment on attachment 86017 [details]
Patch

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

>>> Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp:96
>>> +        resetFrameParameters();
>> 
>> LayerChromium::setLayerRenderer() will call cleanupResources() if (layerRenderer() && layerRenderer() != renderer), which will call releaseCurrentFrame() which contains a call to resetFrameParameters(). Doesn't that make this override redundant?
> 
> Good question! It's not redundant because m_currentFrame can be null, and in that case releaseCurrentFrame() will not call resetFrameParameters() because it exits out early.
> 
> And actually, saveCurrentFrame/releaseCurrentFrame are hooks to be used when we have hardware decoding implemented in Chrome. Right now we don't have hardware decode implemented, so m_currentFrame is _always_ null.

Wouldn't it be better to move the call to resetFrameParameters() to the top of releaseCurrentFrame() in that case? It shouldn't be necessary to override setLayerRenderer unless something more than simple resource reallocation needs to occur in response.
Comment 5 Victoria Kirst 2011-03-17 19:42:32 PDT
Hey Kenneth! Wanted your opinion on a style issue...

So essentially there are two types of VideoFrameChromiums, SystemMemory-backed frames and texture-backed frames Both frame types are saved into m_textures because we want the draw method to treat these the same way.

But for SystemMemory frames, we allocate and take of the textures, so we have to delete them after destruction. But if we're already given the textures, we do not take ownership, so we should not destroy them.

I was thinking I would create another m_textures field (i.e. m_texturesToPaint) that stores textures we're painting to screen. Then in m_textures we would keep textures we've allocated and must delete (never ones we've gotten from VideoFrameChromium) and m_texturesToPaint will be ones drawn to screen (either type of texture).

Does that sound reasonable?

(I am also planning on doing some general code clean-up and variable renaming because right now the code is pretty misleading/confusing wrt texture-backed frames.)
Comment 6 Victoria Kirst 2011-03-18 10:06:44 PDT
(In reply to comment #5)
Ahhh ignore this comment, Ken! I'm doing some more serious rewriting because this is pretty fragile. I will just upload the patch in a little bit. :)
Comment 7 Victoria Kirst 2011-03-18 15:56:31 PDT
Created attachment 86234 [details]
Patch
Comment 8 Victoria Kirst 2011-03-18 16:03:14 PDT
Comment on attachment 86234 [details]
Patch

The logic was getting pretty gross so I did some mild refactoring. Please let me know your thoughts and/or if you have questions about my changes.
Comment 9 Victoria Kirst 2011-03-18 16:14:43 PDT
Comment on attachment 86234 [details]
Patch

Ah there are a few more style mistakes I want to clean-up ...
Comment 10 Victoria Kirst 2011-03-18 16:21:08 PDT
Created attachment 86237 [details]
Patch
Comment 11 Kenneth Russell 2011-03-18 17:52:02 PDT
Comment on attachment 86237 [details]
Patch

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

Looks better overall, but a few questions. Also please mark the bug cq? if you would like me to cq+ it.

> Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp:96
> +        Texture texture = m_textures[plane];
> +        if (!texture.isEmpty && texture.ownedByLayerRenderer)
> +            GLC(context, context->deleteTexture(texture.id));

The fact that this code is only in the destructor looks suspicious to me. Since cleanupResources() might be called multiple times (though perhaps only in response to the GPU process being restarted?) it seems this code should be placed elsewhere and called multiple times from code below. I might be wrong about that though.

> Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp:365
> +        m_textures[plane].id = 0;
> +        m_textures[plane].size = IntSize();
> +        m_textures[plane].visibleSize = IntSize();
> +        m_textures[plane].ownedByLayerRenderer = false;
> +        m_textures[plane].isEmpty = true;

What if m_textures[plane] was previously non-empty and was owned by the layer renderer? The overwrite of id here will cause a resource leak. Or is it guaranteed that if this is called, m_textures only contained stale data from an earlier GPU process?

> Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp:378
> +        m_textures[plane].id = frame->texture(plane);
> +        m_textures[plane].size = frame->requiredTextureSize(plane);
> +        m_textures[plane].visibleSize = computeVisibleSize(frame, plane);
> +        m_textures[plane].ownedByLayerRenderer = false;
> +        m_textures[plane].isEmpty = false;

Same basic question here.
Comment 12 Victoria Kirst 2011-03-22 14:32:46 PDT
Comment on attachment 86237 [details]
Patch

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

I will update the patch to fix saveFrame/resetFrame! Would like amarinichev's OK before r+.

>> Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp:96
>> +            GLC(context, context->deleteTexture(texture.id));
> 
> The fact that this code is only in the destructor looks suspicious to me. Since cleanupResources() might be called multiple times (though perhaps only in response to the GPU process being restarted?) it seems this code should be placed elsewhere and called multiple times from code below. I might be wrong about that though.

OK, looks like cleanupResources() is only called in response to a lost context.

(cleanupResources() is called from setLayerRenderer when a renderer is being replaced, and that seems to be triggered only if the context is lost at the end of WebViewImpl::composite().)

@amarinichev, can you confirm this is true?

>> Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp:365
>> +        m_textures[plane].isEmpty = true;
> 
> What if m_textures[plane] was previously non-empty and was owned by the layer renderer? The overwrite of id here will cause a resource leak. Or is it guaranteed that if this is called, m_textures only contained stale data from an earlier GPU process?

Ah, yeah, I was assuming that if you start playing a video with software decoding, you will always use software decoding, and vice versa (meaning that resetFrameParameter() is always called when ownedByLayerRenderer is false). I will update the patch to be robust to this case, though.

>> Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp:378
>> +        m_textures[plane].isEmpty = false;
> 
> Same basic question here.

I will similarly update this as well.
Comment 13 Alexey Marinichev 2011-03-22 15:15:07 PDT
> OK, looks like cleanupResources() is only called in response to a lost context.
> 
> (cleanupResources() is called from setLayerRenderer when a renderer is being replaced, and that seems to be triggered only if the context is lost at the end of WebViewImpl::composite().)
> 
> @amarinichev, can you confirm this is true?

Yes, lost context reallocates a renderer, and when the old renderer is destroyed, it calls its cleanupResources method.
Comment 14 Victoria Kirst 2011-03-22 16:17:06 PDT
Created attachment 86535 [details]
Patch
Comment 15 Kenneth Russell 2011-03-22 17:06:00 PDT
Comment on attachment 86535 [details]
Patch

amarinichev indicated offline that this looks good, and looks good to me too. Nice work.
Comment 16 WebKit Commit Bot 2011-03-22 18:13:44 PDT
Comment on attachment 86535 [details]
Patch

Clearing flags on attachment: 86535

Committed r81737: <http://trac.webkit.org/changeset/81737>
Comment 17 WebKit Commit Bot 2011-03-22 18:13:50 PDT
All reviewed patches have been landed.  Closing bug.