Bug 1480608. Skip over items that aren't in DrawTarget/DirtyRect. r=mstange
☠☠ backed out by 24705823c696 ☠ ☠
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Thu, 02 Aug 2018 18:09:17 -0400
changeset 430444 00ff83d23238b770a947bb407ec1afe39c3010b5
parent 430443 89a67ef04c61a3f01146f082676259e2ac585fbf
child 430445 24705823c696fbc83b3ace3b0a7f441fa6c2488d
push id34405
push userncsoregi@mozilla.com
push dateWed, 08 Aug 2018 09:57:26 +0000
treeherdermozilla-central@c65991f3fa10 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1480608
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1480608. Skip over items that aren't in DrawTarget/DirtyRect. r=mstange MozReview-Commit-ID: Kc9E1SUVUh3
gfx/2d/RectAbsolute.h
gfx/webrender_bindings/Moz2DImageRenderer.cpp
--- a/gfx/2d/RectAbsolute.h
+++ b/gfx/2d/RectAbsolute.h
@@ -89,16 +89,20 @@ public:
     Sub result;
     result.left = std::max<T>(left, aOther.left);
     result.top = std::max<T>(top, aOther.top);
     result.right = std::min<T>(right, aOther.right);
     result.bottom = std::min<T>(bottom, aOther.bottom);
     return result;
   }
 
+  bool IsEmpty() const {
+    return right <= left || bottom <= top;
+  }
+
   bool IsEqualEdges(const Sub& aOther) const
   {
     return left == aOther.left && top == aOther.top &&
            right == aOther.right && bottom == aOther.bottom;
   }
 };
 
 template <class Units>
--- a/gfx/webrender_bindings/Moz2DImageRenderer.cpp
+++ b/gfx/webrender_bindings/Moz2DImageRenderer.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gfxUtils.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/Range.h"
 #include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/RectAbsolute.h"
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/gfx/RecordedEvent.h"
 #include "mozilla/layers/WebRenderDrawEventRecorder.h"
 #include "WebRenderTypes.h"
 #include "webrender_ffi.h"
 
 #include <unordered_map>
 
@@ -262,19 +263,25 @@ static bool Moz2DRenderCallback(const Ra
     gfx::Tile tile;
     tile.mDrawTarget = dt;
     tile.mTileOrigin = gfx::IntPoint(aTileOffset->x * *aTileSize, aTileOffset->y * *aTileSize);
     tileset.mTiles = &tile;
     tileset.mTileCount = 1;
     dt = gfx::Factory::CreateTiledDrawTarget(tileset);
   }
 
+  auto bounds = gfx::IntRect(origin, aSize);
+
   if (aDirtyRect) {
     Rect dirty(aDirtyRect->origin.x, aDirtyRect->origin.y, aDirtyRect->size.width, aDirtyRect->size.height);
     dt->PushClipRect(dirty);
+    bounds = bounds.Intersect(IntRect(aDirtyRect->origin.x,
+                                      aDirtyRect->origin.y,
+                                      aDirtyRect->size.width,
+                                      aDirtyRect->size.height));
   }
 
   struct Reader {
     const uint8_t *buf;
     size_t len;
     size_t pos;
 
     Reader(const uint8_t *buf, size_t len) : buf(buf), len(len), pos(0) {}
@@ -289,32 +296,43 @@ static bool Moz2DRenderCallback(const Ra
     int ReadInt() {
       int ret;
       MOZ_RELEASE_ASSERT(pos + sizeof(ret) <= len);
       memcpy(&ret, buf + pos, sizeof(ret));
       pos += sizeof(ret);
       return ret;
     }
 
-    void SkipBounds() {
-      MOZ_RELEASE_ASSERT(pos + sizeof(int) * 4 <= len);
-      pos += sizeof(int) * 4;
+    IntRectAbsolute ReadBounds() {
+      MOZ_RELEASE_ASSERT(pos + sizeof(int32_t) * 4 <= len);
+      int32_t x1, y1, x2, y2;
+      memcpy(&x1, buf + pos + 0 * sizeof(int32_t), sizeof(x1));
+      memcpy(&y1, buf + pos + 1 * sizeof(int32_t), sizeof(y1));
+      memcpy(&x2, buf + pos + 2 * sizeof(int32_t), sizeof(x2));
+      memcpy(&y2, buf + pos + 3 * sizeof(int32_t), sizeof(y2));
+      pos += sizeof(int32_t) * 4;
+      return IntRectAbsolute(x1, y1, x2, y2);
     }
 
   };
   //XXX: Make safe
   size_t indexOffset = *(size_t*)(aBlob.end().get()-sizeof(size_t));
   Reader reader(aBlob.begin().get()+indexOffset, aBlob.length()-sizeof(size_t)-indexOffset);
 
   bool ret;
   size_t offset = 0;
+  auto absBounds = IntRectAbsolute::FromRect(bounds);
   while (reader.pos < reader.len) {
     size_t end = reader.ReadSize();
     size_t extra_end = reader.ReadSize();
-    reader.SkipBounds();
+    auto combinedBounds = absBounds.Intersect(reader.ReadBounds());
+    if (combinedBounds.IsEmpty()) {
+      offset = extra_end;
+      continue;
+    }
 
     layers::WebRenderTranslator translator(dt);
 
     size_t count = *(size_t*)(aBlob.begin().get() + end);
     for (size_t i = 0; i < count; i++) {
       wr::FontKey key = *(wr::FontKey*)(aBlob.begin() + end + sizeof(count) + sizeof(wr::FontKey)*i).get();
       RefPtr<UnscaledFont> font = GetUnscaledFont(&translator, key);
       translator.AddUnscaledFont(0, font);