<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[242701] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/242701">242701</a></dd>
<dt>Author</dt> <dd>philn@webkit.org</dd>
<dt>Date</dt> <dd>2019-03-11 07:41:39 -0700 (Mon, 11 Mar 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>[GStreamer][v4l2] Synchronous video texture flushing support
https://bugs.webkit.org/show_bug.cgi?id=195453

Reviewed by Xabier Rodriguez-Calvar.

The v4l2 video decoder currently requires that downstream users of
the graphics resources complete any pending draw call and release
resources before returning from the DRAIN query.

To accomplish this the player monitors the pipeline and whenever a
v4l2 decoder is added, synchronous video texture flushing support
is enabled. Additionally and for all decoder configurations, a
flush is performed before disposing of the player.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::playbinDeepElementAddedCallback):
Monitor elements added to the decodebin bin.
(WebCore::MediaPlayerPrivateGStreamer::decodebinElementAdded): Set
a flag if a v4l2 decoder was added in decodebin.
(WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin): Connect
to the deep-element-added signal so as to monitor pipeline
topology updates.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
(WebCore::MediaPlayerPrivateGStreamerBase::~MediaPlayerPrivateGStreamerBase):
Flush video texture before disposing of the player.
(WebCore::MediaPlayerPrivateGStreamerBase::flushCurrentBuffer):
Synchronously flush if the pipeline contains a v4l2 decoder.
(WebCore::MediaPlayerPrivateGStreamerBase::createGLAppSink): Monitor push events only.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
* platform/graphics/texmap/TextureMapperPlatformLayerProxy.cpp:
(WebCore::TextureMapperPlatformLayerProxy::pushNextBuffer): New
boolean flag used mostly to trigger synchronous flush conditions.
(WebCore::TextureMapperPlatformLayerProxy::dropCurrentBufferWhilePreservingTexture):
Optionally drop the current buffer in a synchronous manner. By
default the method keeps operating asynchronously.
* platform/graphics/texmap/TextureMapperPlatformLayerProxy.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamercpp">trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamerBasecpp">trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamerBaseh">trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicstexmapTextureMapperPlatformLayerProxycpp">trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxy.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicstexmapTextureMapperPlatformLayerProxyh">trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxy.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (242700 => 242701)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2019-03-11 12:58:57 UTC (rev 242700)
+++ trunk/Source/WebCore/ChangeLog      2019-03-11 14:41:39 UTC (rev 242701)
</span><span class="lines">@@ -1,3 +1,43 @@
</span><ins>+2019-03-11  Philippe Normand  <pnormand@igalia.com>
+
+        [GStreamer][v4l2] Synchronous video texture flushing support
+        https://bugs.webkit.org/show_bug.cgi?id=195453
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        The v4l2 video decoder currently requires that downstream users of
+        the graphics resources complete any pending draw call and release
+        resources before returning from the DRAIN query.
+
+        To accomplish this the player monitors the pipeline and whenever a
+        v4l2 decoder is added, synchronous video texture flushing support
+        is enabled. Additionally and for all decoder configurations, a
+        flush is performed before disposing of the player.
+
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::MediaPlayerPrivateGStreamer::playbinDeepElementAddedCallback):
+        Monitor elements added to the decodebin bin.
+        (WebCore::MediaPlayerPrivateGStreamer::decodebinElementAdded): Set
+        a flag if a v4l2 decoder was added in decodebin.
+        (WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin): Connect
+        to the deep-element-added signal so as to monitor pipeline
+        topology updates.
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
+        (WebCore::MediaPlayerPrivateGStreamerBase::~MediaPlayerPrivateGStreamerBase):
+        Flush video texture before disposing of the player.
+        (WebCore::MediaPlayerPrivateGStreamerBase::flushCurrentBuffer):
+        Synchronously flush if the pipeline contains a v4l2 decoder.
+        (WebCore::MediaPlayerPrivateGStreamerBase::createGLAppSink): Monitor push events only.
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
+        * platform/graphics/texmap/TextureMapperPlatformLayerProxy.cpp:
+        (WebCore::TextureMapperPlatformLayerProxy::pushNextBuffer): New
+        boolean flag used mostly to trigger synchronous flush conditions.
+        (WebCore::TextureMapperPlatformLayerProxy::dropCurrentBufferWhilePreservingTexture):
+        Optionally drop the current buffer in a synchronous manner. By
+        default the method keeps operating asynchronously.
+        * platform/graphics/texmap/TextureMapperPlatformLayerProxy.h:
+
</ins><span class="cx"> 2019-03-11  Antti Koivisto  <antti@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Rename contentOffsetInCompostingLayer to contentOffsetInCompositingLayer
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp (242700 => 242701)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp 2019-03-11 12:58:57 UTC (rev 242700)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp    2019-03-11 14:41:39 UTC (rev 242701)
</span><span class="lines">@@ -2445,6 +2445,15 @@
</span><span class="cx"> 
</span><span class="cx">     g_object_set(m_pipeline.get(), "mute", m_player->muted(), nullptr);
</span><span class="cx"> 
</span><ins>+    g_signal_connect(GST_BIN_CAST(m_pipeline.get()), "deep-element-added", G_CALLBACK(+[](GstBin*, GstBin* subBin, GstElement* element, MediaPlayerPrivateGStreamer* player) {
+        GUniquePtr<char> binName(gst_element_get_name(GST_ELEMENT_CAST(subBin)));
+        if (!g_str_has_prefix(binName.get(), "decodebin"))
+            return;
+
+        GUniquePtr<char> elementName(gst_element_get_name(element));
+        player->m_isVideoDecoderVideo4Linux = g_str_has_prefix(elementName.get(), "v4l2");
+    }), this);
+
</ins><span class="cx">     g_signal_connect_swapped(m_pipeline.get(), "source-setup", G_CALLBACK(sourceSetupCallback), this);
</span><span class="cx">     if (m_isLegacyPlaybin) {
</span><span class="cx">         g_signal_connect_swapped(m_pipeline.get(), "video-changed", G_CALLBACK(videoChangedCallback), this);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamerBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp (242700 => 242701)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp     2019-03-11 12:58:57 UTC (rev 242700)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp        2019-03-11 14:41:39 UTC (rev 242701)
</span><span class="lines">@@ -269,6 +269,7 @@
</span><span class="cx"> 
</span><span class="cx"> MediaPlayerPrivateGStreamerBase::~MediaPlayerPrivateGStreamerBase()
</span><span class="cx"> {
</span><ins>+    flushCurrentBuffer();
</ins><span class="cx"> #if USE(TEXTURE_MAPPER_GL) && USE(NICOSIA)
</span><span class="cx">     downcast<Nicosia::ContentLayerTextureMapperImpl>(m_nicosiaLayer->impl()).invalidateClient();
</span><span class="cx"> #endif
</span><span class="lines">@@ -846,7 +847,6 @@
</span><span class="cx"> 
</span><span class="cx"> void MediaPlayerPrivateGStreamerBase::flushCurrentBuffer()
</span><span class="cx"> {
</span><del>-    GST_DEBUG_OBJECT(pipeline(), "Flushing video sample");
</del><span class="cx">     auto sampleLocker = holdLock(m_sampleMutex);
</span><span class="cx"> 
</span><span class="cx">     if (m_sample) {
</span><span class="lines">@@ -858,12 +858,14 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     auto proxyOperation =
</span><del>-        [](TextureMapperPlatformLayerProxy& proxy)
</del><ins>+        [shouldWait = m_isVideoDecoderVideo4Linux, pipeline = pipeline()](TextureMapperPlatformLayerProxy& proxy)
</ins><span class="cx">         {
</span><del>-            LockHolder locker(proxy.lock());
</del><ins>+            GST_DEBUG_OBJECT(pipeline, "Flushing video sample %s", shouldWait ? "synchronously" : "");
+            if (!shouldWait)
+                proxy.lock().lock();
</ins><span class="cx"> 
</span><span class="cx">             if (proxy.isActive())
</span><del>-                proxy.dropCurrentBufferWhilePreservingTexture();
</del><ins>+                proxy.dropCurrentBufferWhilePreservingTexture(shouldWait);
</ins><span class="cx">         };
</span><span class="cx"> 
</span><span class="cx"> #if USE(NICOSIA)
</span><span class="lines">@@ -1010,7 +1012,7 @@
</span><span class="cx">     g_signal_connect(appsink, "new-preroll", G_CALLBACK(newPrerollCallback), this);
</span><span class="cx"> 
</span><span class="cx">     GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(appsink, "sink"));
</span><del>-    gst_pad_add_probe(pad.get(), static_cast<GstPadProbeType>(GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH), [] (GstPad*, GstPadProbeInfo* info,  gpointer userData) -> GstPadProbeReturn {
</del><ins>+    gst_pad_add_probe(pad.get(), static_cast<GstPadProbeType>(GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH), [] (GstPad*, GstPadProbeInfo* info,  gpointer userData) -> GstPadProbeReturn {
</ins><span class="cx">         // In some platforms (e.g. OpenMAX on the Raspberry Pi) when a resolution change occurs the
</span><span class="cx">         // pipeline has to be drained before a frame with the new resolution can be decoded.
</span><span class="cx">         // In this context, it's important that we don't hold references to any previous frame
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamerBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h (242700 => 242701)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h       2019-03-11 12:58:57 UTC (rev 242700)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h  2019-03-11 14:41:39 UTC (rev 242701)
</span><span class="lines">@@ -282,6 +282,8 @@
</span><span class="cx">     HashSet<uint32_t> m_handledProtectionEvents;
</span><span class="cx">     bool m_waitingForKey { false };
</span><span class="cx"> #endif
</span><ins>+
+    mutable bool m_isVideoDecoderVideo4Linux { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicstexmapTextureMapperPlatformLayerProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxy.cpp (242700 => 242701)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxy.cpp        2019-03-11 12:58:57 UTC (rev 242700)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxy.cpp   2019-03-11 14:41:39 UTC (rev 242701)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> #if USE(GLIB_EVENT_LOOP)
</span><span class="cx"> #include <wtf/glib/RunLoopSourcePriority.h>
</span><span class="cx"> #endif
</span><ins>+#include <wtf/Scope.h>
</ins><span class="cx"> 
</span><span class="cx"> static const Seconds releaseUnusedSecondsTolerance { 1_s };
</span><span class="cx"> static const Seconds releaseUnusedBuffersTimerInterval = { 500_ms };
</span><span class="lines">@@ -113,6 +114,7 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_lock.isHeld());
</span><span class="cx">     m_pendingBuffer = WTFMove(newBuffer);
</span><ins>+    m_wasBufferDropped = false;
</ins><span class="cx"> 
</span><span class="cx">     if (m_compositor)
</span><span class="cx">         m_compositor->onNewBufferAvailable();
</span><span class="lines">@@ -187,9 +189,10 @@
</span><span class="cx">         appendToUnusedBuffers(WTFMove(prevBuffer));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void TextureMapperPlatformLayerProxy::dropCurrentBufferWhilePreservingTexture()
</del><ins>+void TextureMapperPlatformLayerProxy::dropCurrentBufferWhilePreservingTexture(bool shouldWait)
</ins><span class="cx"> {
</span><del>-    ASSERT(m_lock.isHeld());
</del><ins>+    if (!shouldWait)
+        ASSERT(m_lock.isHeld());
</ins><span class="cx"> 
</span><span class="cx">     if (m_pendingBuffer && m_pendingBuffer->hasManagedTexture()) {
</span><span class="cx">         m_usedBuffers.append(WTFMove(m_pendingBuffer));
</span><span class="lines">@@ -200,9 +203,17 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     m_compositorThreadUpdateFunction =
</span><del>-        [this] {
</del><ins>+        [this, shouldWait] {
</ins><span class="cx">             LockHolder locker(m_lock);
</span><span class="cx"> 
</span><ins>+            auto maybeNotifySynchronousOperation = WTF::makeScopeExit([this, shouldWait]() {
+                if (shouldWait) {
+                    LockHolder holder(m_wasBufferDroppedLock);
+                    m_wasBufferDropped = true;
+                    m_wasBufferDroppedCondition.notifyAll();
+                }
+            });
+
</ins><span class="cx">             if (!m_compositor || !m_targetLayer || !m_currentBuffer)
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><span class="lines">@@ -214,7 +225,19 @@
</span><span class="cx">             if (prevBuffer->hasManagedTexture())
</span><span class="cx">                 appendToUnusedBuffers(WTFMove(prevBuffer));
</span><span class="cx">         };
</span><ins>+
+    if (shouldWait) {
+        LockHolder holder(m_wasBufferDroppedLock);
+        m_wasBufferDropped = false;
+    }
+
</ins><span class="cx">     m_compositorThreadUpdateTimer->startOneShot(0_s);
</span><ins>+    if (shouldWait) {
+        LockHolder holder(m_wasBufferDroppedLock);
+        m_wasBufferDroppedCondition.wait(m_wasBufferDroppedLock, [this] {
+            return m_wasBufferDropped;
+        });
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool TextureMapperPlatformLayerProxy::scheduleUpdateOnCompositorThread(Function<void()>&& updateFunction)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicstexmapTextureMapperPlatformLayerProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxy.h (242700 => 242701)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxy.h  2019-03-11 12:58:57 UTC (rev 242700)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxy.h     2019-03-11 14:41:39 UTC (rev 242701)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #if USE(COORDINATED_GRAPHICS)
</span><span class="cx"> 
</span><span class="cx"> #include "TextureMapperGLHeaders.h"
</span><ins>+#include <wtf/Condition.h>
</ins><span class="cx"> #include <wtf/Function.h>
</span><span class="cx"> #include <wtf/Lock.h>
</span><span class="cx"> #include <wtf/RunLoop.h>
</span><span class="lines">@@ -68,7 +69,7 @@
</span><span class="cx">     WEBCORE_EXPORT void invalidate();
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT void swapBuffer();
</span><del>-    void dropCurrentBufferWhilePreservingTexture();
</del><ins>+    void dropCurrentBufferWhilePreservingTexture(bool shouldWait = false);
</ins><span class="cx"> 
</span><span class="cx">     bool scheduleUpdateOnCompositorThread(Function<void()>&&);
</span><span class="cx"> 
</span><span class="lines">@@ -85,6 +86,10 @@
</span><span class="cx"> 
</span><span class="cx">     Lock m_lock;
</span><span class="cx"> 
</span><ins>+    Lock m_wasBufferDroppedLock;
+    Condition m_wasBufferDroppedCondition;
+    bool m_wasBufferDropped { false };
+
</ins><span class="cx">     Vector<std::unique_ptr<TextureMapperPlatformLayerBuffer>> m_usedBuffers;
</span><span class="cx">     std::unique_ptr<RunLoop::Timer<TextureMapperPlatformLayerProxy>> m_releaseUnusedBuffersTimer;
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>