<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>75637</bug_id>
          
          <creation_ts>2012-01-05 11:25:12 -0800</creation_ts>
          <short_desc>[Chromium] Protect visible textures before updating them</short_desc>
          <delta_ts>2012-02-09 11:26:30 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>Layout and Rendering</component>
          <version>528+ (Nightly build)</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>Unspecified</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>INVALID</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          <blocked>72078</blocked>
          <everconfirmed>1</everconfirmed>
          <reporter name="Xianzhu Wang">wangxianzhu</reporter>
          <assigned_to name="Xianzhu Wang">wangxianzhu</assigned_to>
          <cc>cc-bugs</cc>
    
    <cc>danakj</cc>
    
    <cc>enne</cc>
    
    <cc>jamesr</cc>
    
    <cc>klobag</cc>
    
    <cc>nduca</cc>
    
    <cc>reveman</cc>
    
    <cc>vangelis</cc>
    
    <cc>webkit.review.bot</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>530467</commentid>
    <comment_count>0</comment_count>
    <who name="Xianzhu Wang">wangxianzhu</who>
    <bug_when>2012-01-05 11:25:12 -0800</bug_when>
    <thetext>Currently, tile textures are reserved (requested for new ones or protected for existing ones) in TiledLayerChromium::prepareToUpdateTiles(). If a new tile causes the memory to exceed the preferred memory limit, a least used texture will be replaced. However, sometimes the texture being replaced will be used soon. (In fact, at the time, the least used texture is more likely to be used soon.)

For example, a layer has the following tiles to be drawn in the current cycle:
1 2 3 4
5 6 7 8
Tiles 1 to 4 don&apos;t have textures, and 5 to 8 have.
And the layer also have tiles 9 to 12 which have textures but are no longer visible.

Assume the preferred memory limit can contain 6 textures.

TextureManager will do the following for the tiles:
1: replaceTexture(5 =&gt; 1)
2: replaceTexture(6 =&gt; 2)
3: replaceTexture(7 =&gt; 3)
4: replaceTexture(8 =&gt; 4)
5: replaceTexture(9 =&gt; 5)
6: replaceTexture(10 =&gt; 6)
7: replaceTexture(11 =&gt; 7)
8: replaceTexture(12 =&gt; 8)

The textures of tiles 5 to 8 are replaced and then recreated and repainted.

If we protect all the visible tiles (5 to 8) of all layers before CCLayerTreeHost::paintLayerContents(), TextureManager will do the following:
1: replaceTexture(9 =&gt; 1)
2: replaceTexture(10 =&gt; 2)
3: replaceTexture(11 =&gt; 3)
4: replaceTexture(12 =&gt; 4)
5: do nothing
6: do nothing
7: do nothing
8: do nothing</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>530749</commentid>
    <comment_count>1</comment_count>
    <who name="Grace Kloba">klobag</who>
    <bug_when>2012-01-05 16:14:41 -0800</bug_when>
    <thetext>Currently replaceTexture is based on m_preferredMemoryLimitBytes. If we use the max(m_preferredMemoryLimitBytes, currentlyProtectedByes) and currentlyProtectedByes is set after each call to reduceMemoryToLimit(), will this help?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>531230</commentid>
    <comment_count>2</comment_count>
    <who name="Xianzhu Wang">wangxianzhu</who>
    <bug_when>2012-01-06 12:01:59 -0800</bug_when>
    <thetext>(In reply to comment #1)
&gt; Currently replaceTexture is based on m_preferredMemoryLimitBytes. If we use the max(m_preferredMemoryLimitBytes, currentlyProtectedByes) and currentlyProtectedByes is set after each call to reduceMemoryToLimit(), will this help?

If I understood your method correct, using my example to simulate shows it doesn&apos;t work well: as used = 8 textures and max(preferred, protected) = 8 textures, any request of new texture will still trigger replaceTexture, so what happens is just the same as the current code. If we further raise the threshold of replaceTexture, remove/add will happen which costs even more than replaceTexture.

I prefer doing explicit protection before updating the layers. With it, the textures that are no longer visible are not protected and will be replaced or removed when needed, and visible textures won&apos;t be replaced.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>531366</commentid>
    <comment_count>3</comment_count>
    <who name="James Robinson">jamesr</who>
    <bug_when>2012-01-06 13:52:53 -0800</bug_when>
    <thetext>(In reply to comment #2)
&gt; (In reply to comment #1)
&gt; &gt; Currently replaceTexture is based on m_preferredMemoryLimitBytes. If we use the max(m_preferredMemoryLimitBytes, currentlyProtectedByes) and currentlyProtectedByes is set after each call to reduceMemoryToLimit(), will this help?
&gt; 
&gt; If I understood your method correct, using my example to simulate shows it doesn&apos;t work well: as used = 8 textures and max(preferred, protected) = 8 textures, any request of new texture will still trigger replaceTexture, so what happens is just the same as the current code. If we further raise the threshold of replaceTexture, remove/add will happen which costs even more than replaceTexture.
&gt; 
&gt; I prefer doing explicit protection before updating the layers. With it, the textures that are no longer visible are not protected and will be replaced or removed when needed, and visible textures won&apos;t be replaced.

I think you&apos;re right.  The intent with the preferred/max limits is that currently visible textures should always get priority and kick out anything below the preferred limit if there&apos;s contention, and that we should only keep non-visible textures around if the total use is under the preferred limit.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>552641</commentid>
    <comment_count>4</comment_count>
      <attachid>126192</attachid>
    <who name="Xianzhu Wang">wangxianzhu</who>
    <bug_when>2012-02-08 16:55:25 -0800</bug_when>
    <thetext>Created attachment 126192
patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>552673</commentid>
    <comment_count>5</comment_count>
      <attachid>126192</attachid>
    <who name="Dana Jansens">danakj</who>
    <bug_when>2012-02-08 17:28:19 -0800</bug_when>
    <thetext>Comment on attachment 126192
patch

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

&gt; Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp:460
&gt; +        if (it.representsTargetRenderSurface() || it-&gt;alwaysReserveTextures())

I think you want !it.representsItself()

Right now you protect both in the representsContributingSurface() and representsItself() case. A layer that owns a surface and draws will be protected twice. You care only to catch layers that draw something IIUC so you just want representsItself().</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>552684</commentid>
    <comment_count>6</comment_count>
      <attachid>126192</attachid>
    <who name="Xianzhu Wang">wangxianzhu</who>
    <bug_when>2012-02-08 17:39:10 -0800</bug_when>
    <thetext>Comment on attachment 126192
patch

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

&gt;&gt; Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp:460
&gt;&gt; +        if (it.representsTargetRenderSurface() || it-&gt;alwaysReserveTextures())
&gt; 
&gt; I think you want !it.representsItself()
&gt; 
&gt; Right now you protect both in the representsContributingSurface() and representsItself() case. A layer that owns a surface and draws will be protected twice. You care only to catch layers that draw something IIUC so you just want representsItself().

Does the code in CCLayerTreeHost::reserveTextures() (where I copied some code :) have the same problem?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>552694</commentid>
    <comment_count>7</comment_count>
    <who name="Dana Jansens">danakj</who>
    <bug_when>2012-02-08 17:47:05 -0800</bug_when>
    <thetext>If I am understanding correctly, yes it does.

@enne does a contributing layer need to reserve textures if it doesn&apos;t draw?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>552733</commentid>
    <comment_count>8</comment_count>
      <attachid>126192</attachid>
    <who name="Vangelis Kokkevis">vangelis</who>
    <bug_when>2012-02-08 18:29:58 -0800</bug_when>
    <thetext>Comment on attachment 126192
patch

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

The texture recycling patch was reverted yesterday:
http://trac.webkit.org/changeset/107014

as it was causing a lot of unnecessary repaints. Your patch will need to first re-enable texture recycling.  But before we do that we should make sure that things work as expected and we don&apos;t end up churning through textures again.

&gt;&gt;&gt; Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp:460
&gt;&gt;&gt; +        if (it.representsTargetRenderSurface() || it-&gt;alwaysReserveTextures())
&gt;&gt; 
&gt;&gt; I think you want !it.representsItself()
&gt;&gt; 
&gt;&gt; Right now you protect both in the representsContributingSurface() and representsItself() case. A layer that owns a surface and draws will be protected twice. You care only to catch layers that draw something IIUC so you just want representsItself().
&gt; 
&gt; Does the code in CCLayerTreeHost::reserveTextures() (where I copied some code :) have the same problem?

I don&apos;t think it will be protected twice as regardless of whether the layer has a RS attached to it or not, it should only appear once in the list.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>552746</commentid>
    <comment_count>9</comment_count>
    <who name="Dana Jansens">danakj</who>
    <bug_when>2012-02-08 18:53:47 -0800</bug_when>
    <thetext>(In reply to comment #8)
&gt; I don&apos;t think it will be protected twice as regardless of whether the layer has a RS attached to it or not, it should only appear once in the list.

If a layer draws and owns a surface also, it will be in the list for the RenderSurface it owns, and in the list for the RenderSurface it contributes to. The iterator class will visit the layer in both places, with the &quot;representsX&quot; flag to differentiate (also a third time for visiting the the layer&apos;s render surface as a target but that&apos;s already skipped).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>552865</commentid>
    <comment_count>10</comment_count>
    <who name="Vangelis Kokkevis">vangelis</who>
    <bug_when>2012-02-08 22:16:49 -0800</bug_when>
    <thetext>(In reply to comment #9)
&gt; (In reply to comment #8)
&gt; &gt; I don&apos;t think it will be protected twice as regardless of whether the layer has a RS attached to it or not, it should only appear once in the list.
&gt; 
&gt; If a layer draws and owns a surface also, it will be in the list for the RenderSurface it owns, and in the list for the RenderSurface it contributes to. The iterator class will visit the layer in both places, with the &quot;representsX&quot; flag to differentiate (also a third time for visiting the the layer&apos;s render surface as a target but that&apos;s already skipped).

Hmm, the way the code is setup, if a layer owns a RenderSurface, it also contributes to it.  See:

http://code.google.com/codesearch#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp&amp;exact_package=chromium&amp;q=layertreehostcommon&amp;type=cs&amp;l=320

So it will only be visited twice, once in the list of the RS it owns and once in the list of its ancestor&apos;s RS.  If we bail out for it.representsTargetRenderSurface() we should only be protecting it exactly once.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>553192</commentid>
    <comment_count>11</comment_count>
    <who name="Dana Jansens">danakj</who>
    <bug_when>2012-02-09 08:35:46 -0800</bug_when>
    <thetext>(In reply to comment #10)
&gt; Hmm, the way the code is setup, if a layer owns a RenderSurface, it also contributes to it.  See:
&gt; 
&gt; http://code.google.com/codesearch#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp&amp;exact_package=chromium&amp;q=layertreehostcommon&amp;type=cs&amp;l=320
&gt; 
&gt; So it will only be visited twice, once in the list of the RS it owns and once in the list of its ancestor&apos;s RS.  If we bail out for it.representsTargetRenderSurface() we should only be protecting it exactly once.

Sorry this is derailing things a bit Xianzhu, I guess it&apos;s worth getting things right. Vangelis, you&apos;re absolutely right in your understanding of the renderSurfaceLayerList structure. What&apos;s missing is how the iterators run over this structure.

http://code.google.com/codesearch#OAMlx_jo-ck/src/third_party/WebKit/Source/WebKit/chromium/tests/CCLayerIteratorTest.cpp&amp;type=cs&amp;l=259

This layer is hit once in each of the three states during a back-to-front iteration. The iterators do this so that you can easily act differently on targets, contributing surfaces, and drawing surfaces. Most uses of the iterators only care to act on layers when representsItself(), while maybe doing something wrt the surfaces when representsContributingRenderSurface() or representsTargetRenderSurface().</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>553276</commentid>
    <comment_count>12</comment_count>
    <who name="Xianzhu Wang">wangxianzhu</who>
    <bug_when>2012-02-09 10:21:57 -0800</bug_when>
    <thetext>(In reply to comment #11)
&gt; Sorry this is derailing things a bit Xianzhu, I guess it&apos;s worth getting things right. Vangelis, you&apos;re absolutely right in your understanding of the renderSurfaceLayerList structure. What&apos;s missing is how the iterators run over this structure.
&gt; 

No problem. In deed I learned from the discussion :)

&gt; The texture recycling patch was reverted yesterday:
&gt; http://trac.webkit.org/changeset/107014
&gt; 
&gt; as it was causing a lot of unnecessary repaints. Your patch will need to first re-enable texture recycling.  But before we do that we should make sure that things work as expected and we don&apos;t end up churning through textures again.
&gt; 

I noticed the revert but I thought the problem remained with only replace/recreate changed to remove/add. Now I&apos;ve realized that they are different at the memory limits, so this bug no longer exists.

Will file another bug about TiledLayerChromium::protectVisibleTileTextures().</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>553355</commentid>
    <comment_count>13</comment_count>
    <who name="Adrienne Walker">enne</who>
    <bug_when>2012-02-09 11:26:30 -0800</bug_when>
    <thetext>(In reply to comment #5)
&gt; (From update of attachment 126192 [details])
&gt; View in context: https://bugs.webkit.org/attachment.cgi?id=126192&amp;action=review
&gt; 
&gt; &gt; Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp:460
&gt; &gt; +        if (it.representsTargetRenderSurface() || it-&gt;alwaysReserveTextures())
&gt; 
&gt; I think you want !it.representsItself()

You&apos;re quite right.  Here&apos;s https://bugs.webkit.org/show_bug.cgi?id=78258 to fix the reserveTextures part of that.</thetext>
  </long_desc>
      
          <attachment
              isobsolete="1"
              ispatch="1"
              isprivate="0"
          >
            <attachid>126192</attachid>
            <date>2012-02-08 16:55:25 -0800</date>
            <delta_ts>2012-02-09 10:22:14 -0800</delta_ts>
            <desc>patch</desc>
            <filename>75637</filename>
            <type>text/plain</type>
            <size>3662</size>
            <attacher name="Xianzhu Wang">wangxianzhu</attacher>
            
              <data encoding="base64">SW5kZXg6IFNvdXJjZS9XZWJDb3JlL0NoYW5nZUxvZwo9PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLSBTb3VyY2UvV2Vi
Q29yZS9DaGFuZ2VMb2cJKHJldmlzaW9uIDEwNzEzMikKKysrIFNvdXJjZS9XZWJDb3JlL0NoYW5n
ZUxvZwkod29ya2luZyBjb3B5KQpAQCAtMSwzICsxLDIxIEBACisyMDEyLTAyLTA4ICBYaWFuemh1
IFdhbmcgIDx3YW5neGlhbnpodUBjaHJvbWl1bS5vcmc+CisKKyAgICAgICAgW0Nocm9taXVtXSBQ
cm90ZWN0IHZpc2libGUgdGV4dHVyZXMgYmVmb3JlIHVwZGF0aW5nIHRoZW0KKyAgICAgICAgaHR0
cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTc1NjM3CisKKyAgICAgICAgVGhp
cyBjYW4gcHJldmVudCBzb21lIHRleHR1cmVzIHRoYXQgd2lsbCBiZSB1c2VkIGZyb20gYmVpbmcg
cmVwbGFjZWQKKyAgICAgICAgYW5kIHJlY3JlYXRlZCBhZ2Fpbi4KKworICAgICAgICBSZXZpZXdl
ZCBieSBOT0JPRFkgKE9PUFMhKS4KKworICAgICAgICAqIHBsYXRmb3JtL2dyYXBoaWNzL2Nocm9t
aXVtL1RpbGVkTGF5ZXJDaHJvbWl1bS5jcHA6CisgICAgICAgIChXZWJDb3JlOjpUaWxlZExheWVy
Q2hyb21pdW06OnByb3RlY3RWaXNpYmxlVGlsZVRleHR1cmVzKToKKyAgICAgICAgKiBwbGF0Zm9y
bS9ncmFwaGljcy9jaHJvbWl1bS9jYy9DQ0xheWVyVHJlZUhvc3QuY3BwOgorICAgICAgICAoV2Vi
Q29yZTo6Q0NMYXllclRyZWVIb3N0Ojp1cGRhdGVMYXllcnMpOgorICAgICAgICAoV2ViQ29yZTo6
Q0NMYXllclRyZWVIb3N0Ojpwcm90ZWN0VmlzaWJsZVRpbGVUZXh0dXJlcyk6CisgICAgICAgIChX
ZWJDb3JlKToKKyAgICAgICAgKiBwbGF0Zm9ybS9ncmFwaGljcy9jaHJvbWl1bS9jYy9DQ0xheWVy
VHJlZUhvc3QuaDoKKwogMjAxMi0wMi0wOCAgU2hhd24gU2luZ2ggIDxzaGF3bnNpbmdoQGNocm9t
aXVtLm9yZz4KIAogICAgICAgICBbY2hyb21pdW1dIFJlbW92ZSBpbmNvcnJlY3QgZWFybHkgZXhp
dCBpbiBDQ0RhbWFnZVRyYWNrZXIKSW5kZXg6IFNvdXJjZS9XZWJDb3JlL3BsYXRmb3JtL2dyYXBo
aWNzL2Nocm9taXVtL1RpbGVkTGF5ZXJDaHJvbWl1bS5jcHAKPT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gU291cmNl
L1dlYkNvcmUvcGxhdGZvcm0vZ3JhcGhpY3MvY2hyb21pdW0vVGlsZWRMYXllckNocm9taXVtLmNw
cAkocmV2aXNpb24gMTA3MTA4KQorKysgU291cmNlL1dlYkNvcmUvcGxhdGZvcm0vZ3JhcGhpY3Mv
Y2hyb21pdW0vVGlsZWRMYXllckNocm9taXVtLmNwcAkod29ya2luZyBjb3B5KQpAQCAtMzI5LDcg
KzMyOSw3IEBAIHZvaWQgVGlsZWRMYXllckNocm9taXVtOjppbnZhbGlkYXRlUmVjdCgKIAogdm9p
ZCBUaWxlZExheWVyQ2hyb21pdW06OnByb3RlY3RWaXNpYmxlVGlsZVRleHR1cmVzKCkKIHsKLSAg
ICBwcm90ZWN0VGlsZVRleHR1cmVzKEludFJlY3QoSW50UG9pbnQ6Onplcm8oKSwgY29udGVudEJv
dW5kcygpKSk7CisgICAgcHJvdGVjdFRpbGVUZXh0dXJlcyh2aXNpYmxlTGF5ZXJSZWN0KCkpOwog
fQogCiB2b2lkIFRpbGVkTGF5ZXJDaHJvbWl1bTo6cHJvdGVjdFRpbGVUZXh0dXJlcyhjb25zdCBJ
bnRSZWN0JiBsYXllclJlY3QpCkluZGV4OiBTb3VyY2UvV2ViQ29yZS9wbGF0Zm9ybS9ncmFwaGlj
cy9jaHJvbWl1bS9jYy9DQ0xheWVyVHJlZUhvc3QuY3BwCj09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIFNvdXJjZS9X
ZWJDb3JlL3BsYXRmb3JtL2dyYXBoaWNzL2Nocm9taXVtL2NjL0NDTGF5ZXJUcmVlSG9zdC5jcHAJ
KHJldmlzaW9uIDEwNzEwOCkKKysrIFNvdXJjZS9XZWJDb3JlL3BsYXRmb3JtL2dyYXBoaWNzL2No
cm9taXVtL2NjL0NDTGF5ZXJUcmVlSG9zdC5jcHAJKHdvcmtpbmcgY29weSkKQEAgLTQxNiw2ICs0
MTYsNyBAQCB2b2lkIENDTGF5ZXJUcmVlSG9zdDo6dXBkYXRlTGF5ZXJzKExheWVyCiAgICAgfQog
CiAgICAgcmVzZXJ2ZVRleHR1cmVzKCk7CisgICAgcHJvdGVjdFZpc2libGVUaWxlVGV4dHVyZXMo
KTsKIAogICAgIHBhaW50TGF5ZXJDb250ZW50cyhtX3VwZGF0ZUxpc3QsIFBhaW50VmlzaWJsZSk7
CiAgICAgaWYgKCFtX3RyaWdnZXJJZGxlUGFpbnRzKQpAQCAtNDQ4LDYgKzQ0OSwyMCBAQCB2b2lk
IENDTGF5ZXJUcmVlSG9zdDo6cmVzZXJ2ZVRleHR1cmVzKCkKICAgICB9CiB9CiAKK3ZvaWQgQ0NM
YXllclRyZWVIb3N0Ojpwcm90ZWN0VmlzaWJsZVRpbGVUZXh0dXJlcygpCit7CisgICAgLy8gVXNl
IEJhY2tUb0Zyb250IHNpbmNlIGl0J3MgY2hlYXAgYW5kIHRoaXMgaXNuJ3Qgb3JkZXItZGVwZW5k
ZW50LgorICAgIHR5cGVkZWYgQ0NMYXllckl0ZXJhdG9yPExheWVyQ2hyb21pdW0sIFJlbmRlclN1
cmZhY2VDaHJvbWl1bSwgQ0NMYXllckl0ZXJhdG9yQWN0aW9uczo6QmFja1RvRnJvbnQ+IENDTGF5
ZXJJdGVyYXRvclR5cGU7CisKKyAgICBDQ0xheWVySXRlcmF0b3JUeXBlIGVuZCA9IENDTGF5ZXJJ
dGVyYXRvclR5cGU6OmVuZCgmbV91cGRhdGVMaXN0KTsKKyAgICBmb3IgKENDTGF5ZXJJdGVyYXRv
clR5cGUgaXQgPSBDQ0xheWVySXRlcmF0b3JUeXBlOjpiZWdpbigmbV91cGRhdGVMaXN0KTsgaXQg
IT0gZW5kOyArK2l0KSB7CisgICAgICAgIC8vIEFzc3VtZSB0aGUgbGF5ZXJzIHdpdGggYWx3YXlz
UmVzZXJ2ZVRleHR1cmVzIGhhdmUgcmVzZXJ2ZWQgdGhlaXIgdGV4dHVyZXMuCisgICAgICAgIGlm
IChpdC5yZXByZXNlbnRzVGFyZ2V0UmVuZGVyU3VyZmFjZSgpIHx8IGl0LT5hbHdheXNSZXNlcnZl
VGV4dHVyZXMoKSkKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICBpdC0+cHJvdGVjdFZp
c2libGVUaWxlVGV4dHVyZXMoKTsKKyAgICB9Cit9CisKIC8vIHN0YXRpYwogdm9pZCBDQ0xheWVy
VHJlZUhvc3Q6OnBhaW50Q29udGVudHNJZkRpcnR5KExheWVyQ2hyb21pdW0qIGxheWVyLCBQYWlu
dFR5cGUgcGFpbnRUeXBlLCBjb25zdCBSZWdpb24mIG9jY2x1ZGVkU2NyZWVuU3BhY2UpCiB7Cklu
ZGV4OiBTb3VyY2UvV2ViQ29yZS9wbGF0Zm9ybS9ncmFwaGljcy9jaHJvbWl1bS9jYy9DQ0xheWVy
VHJlZUhvc3QuaAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09Ci0tLSBTb3VyY2UvV2ViQ29yZS9wbGF0Zm9ybS9ncmFwaGlj
cy9jaHJvbWl1bS9jYy9DQ0xheWVyVHJlZUhvc3QuaAkocmV2aXNpb24gMTA3MTA4KQorKysgU291
cmNlL1dlYkNvcmUvcGxhdGZvcm0vZ3JhcGhpY3MvY2hyb21pdW0vY2MvQ0NMYXllclRyZWVIb3N0
LmgJKHdvcmtpbmcgY29weSkKQEAgLTIxMiw2ICsyMTIsNyBAQCBwcml2YXRlOgogICAgIHZvaWQg
dXBkYXRlTGF5ZXJzKExheWVyQ2hyb21pdW0qKTsKICAgICAvLyBQcmUtcmVzZXJ2ZSB0ZXh0dXJl
cyBmb3IgYW55IGxheWVyIG1hcmtlZCAiYWx3YXlzIHJlc2VydmUgdGV4dHVyZXMiCiAgICAgdm9p
ZCByZXNlcnZlVGV4dHVyZXMoKTsKKyAgICB2b2lkIHByb3RlY3RWaXNpYmxlVGlsZVRleHR1cmVz
KCk7CiAgICAgdm9pZCBjbGVhclBlbmRpbmdVcGRhdGUoKTsKIAogICAgIGludCBtX2NvbXBvc2l0
b3JJZGVudGlmaWVyOwo=
</data>

          </attachment>
      

    </bug>

</bugzilla>