Bug 1480608. Skip over items that aren't in DrawTarget/DirtyRect. r=mstange draft
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Thu, 02 Aug 2018 18:09:17 -0400
changeset 827410 b39f355867dac3e6e2b7df9fc6487921aa9cfe44
parent 827379 d9e6ce390607ad8c227adc2ad2ff3cac89a814bc
push id118531
push userbmo:jmuizelaar@mozilla.com
push dateWed, 08 Aug 2018 03:03:52 +0000
reviewersmstange
bugs1480608
milestone63.0a1
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);