[pypy-commit] lang-smalltalk default: improved rpython bitblt removing some of the errors

lwassermann noreply at buildbot.pypy.org
Tue Jul 16 17:05:10 CEST 2013


Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch: 
Changeset: r499:b992548ddcd8
Date: 2013-07-16 15:50 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/b992548ddcd8/

Log:	improved rpython bitblt removing some of the errors added a printing
	function to rpython bb as well as the minibluebookdebug image to
	allow printf debugging (comparing the results) added hard checks for
	lower bound on WordsObject and DisplayBitmap word access

diff --git a/images/minibluebookdebug.image b/images/minibluebookdebug.image
index fa4c1e60de2e4482f2b3308297fef4b73835ef1e..4bb8ed8fd0cdcee3a381df2e4ad05a6af5337096
GIT binary patch

[cut]

diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -129,7 +129,6 @@
     def __repr__(self):
         return self.as_repr_string()
 
-    @jit.elidable
     def as_repr_string(self):
         return "%r" % self
 
@@ -878,6 +877,9 @@
         self.setword(index0, word)
 
     def getword(self, n):
+        # if n < 0:
+        #     import pdb; pdb.set_trace()
+        assert n >= 0
         if self.words is not None:
             return self.words[n]
         else:
@@ -1004,7 +1006,12 @@
         return w_result
 
     def getword(self, n):
+        assert n >= 0
+        # if self._realsize > n:
         return self._real_depth_buffer[n]
+        # else:
+        #     print "Out-of-bounds access on display: %d/%d" % (n, self._realsize)
+        #     import pdb; pdb.set_trace()
 
     def setword(self, n, word):
         raise NotImplementedError("subclass responsibility")
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -611,32 +611,23 @@
         raise PrimitiveFailedError
     
     space = interp.space
-    import time
 
-    start = time.time()
-    print "blitting"
-
+    s_bitblt = w_rcvr.as_bitblt_get_shadow(space)
     # See BlueBook p.356ff
-    s_bitblt = w_rcvr.as_bitblt_get_shadow(space)
-    s_bitblt.sync_cache()
     s_bitblt.clip_range()
     if s_bitblt.w <= 0 or s_bitblt.h <= 0:
         return w_rcvr # null range
     s_bitblt.compute_masks()
     s_bitblt.check_overlap()
     s_bitblt.calculate_offsets()
-    try:
-        s_bitblt.copy_loop()
-    except IndexError:
-        raise PrimitiveFailedError()
+    # print s_bitblt.as_string()
+    s_bitblt.copy_loop()
 
     w_dest_form = w_rcvr.fetch(space, 0)
     if w_dest_form.is_same_object(space.objtable['w_display']):
         w_bitmap = w_dest_form.fetch(space, 0)
         assert isinstance(w_bitmap, model.W_DisplayBitmap)
         w_bitmap.flush_to_screen()
-
-    print "blitting finshed after %d ms" % int((time.time() - start) * 1000)
     return w_rcvr
 
     # try:
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -1129,9 +1129,9 @@
                "dest_index", "source_delta", "dest_delta"]
 
     WordSize = 32
-    RightMasks = [rarithmetic.r_uint(1)]
+    RightMasks = [rarithmetic.r_uint(0)]
     for i in xrange(WordSize):
-        RightMasks.append(rarithmetic.r_uint((2 ** (i + 2)) - 1))
+        RightMasks.append(rarithmetic.r_uint((2 ** (i + 1)) - 1))
     AllOnes = rarithmetic.r_uint((2 ** WordSize) - 1)
 
     def sync_cache(self):
@@ -1174,14 +1174,14 @@
         else:
             self.halftone_bits = None
         self.combination_rule = self.space.unwrap_int(self.fetch(3))
-        self.dest_x = self.space.unwrap_int(self.fetch(4)) - 1
-        self.dest_y = self.space.unwrap_int(self.fetch(5)) - 1
+        self.dest_x = self.space.unwrap_int(self.fetch(4))
+        self.dest_y = self.space.unwrap_int(self.fetch(5))
         self.width = self.space.unwrap_int(self.fetch(6))
         self.height = self.space.unwrap_int(self.fetch(7))
-        self.source_x = self.space.unwrap_int(self.fetch(8)) - 1
-        self.source_y = self.space.unwrap_int(self.fetch(9)) - 1
-        self.clip_x = self.space.unwrap_int(self.fetch(10)) - 1
-        self.clip_y = self.space.unwrap_int(self.fetch(11)) - 1
+        self.source_x = self.space.unwrap_int(self.fetch(8))
+        self.source_y = self.space.unwrap_int(self.fetch(9))
+        self.clip_x = self.space.unwrap_int(self.fetch(10))
+        self.clip_y = self.space.unwrap_int(self.fetch(11))
         self.clip_width = self.space.unwrap_int(self.fetch(12))
         self.clip_height = self.space.unwrap_int(self.fetch(13))
         self.color_map = self.fetch(14)
@@ -1263,27 +1263,26 @@
                 self.sx = self.sx + self.w - 1
                 self.dx = self.dx + self.w - 1
                 self.skew_mask = ~self.skew_mask
-                assert isinstance(self.mask2, rarithmetic.r_uint)
                 self.mask1, self.mask2 = self.mask2, self.mask1
 
     def calculate_offsets(self):
         self.preload = (self.source_form is not None and (
-                        self.skew_mask != 0 and
+                        self.skew != 0 and
                         self.skew <= (self.sx & (BitBltShadow.WordSize - 1))))
         if self.h_dir < 0:
             self.preload = not self.preload
-        self.source_index = self.sy * self.source_raster + self.sx // BitBltShadow.WordSize
-        self.dest_index = self.dy * self.dest_raster + self.dx // BitBltShadow.WordSize
-        self.source_delta = ((self.source_raster *
+        self.source_index = self.sy * self.source_raster + (self.sx // BitBltShadow.WordSize)
+        self.dest_index = self.dy * self.dest_raster + (self.dx // BitBltShadow.WordSize)
+        self.source_delta = (self.source_raster *
                              self.v_dir -
-                             (self.n_words + (1 if self.preload else 0))) *
-                             self.h_dir)
+                             ((self.n_words + (1 if self.preload else 0)) *
+                             self.h_dir))
         self.dest_delta = self.dest_raster * self.v_dir - self.n_words * self.h_dir
 
     def copy_loop(self):
         space = self.space
         no_skew_mask = ~self.skew_mask
-        for i in xrange(self.h):
+        for i in xrange(1, self.h+1):
             if self.halftone_bits:
                 halftone_word = self.halftone_bits[self.dy % len(self.halftone_bits)]
                 self.dy = self.dy + self.v_dir
@@ -1296,17 +1295,18 @@
             else:
                 prev_word = 0
             merge_mask = self.mask1
-            for word in xrange(self.n_words):
+            for word in xrange(1, self.n_words + 1):
                 if self.source_form is not None:
                     prev_word = prev_word & self.skew_mask
-                    try:
+                    if (self.source_index < 0 
+                        or self.source_index >= self.source_bits.size()):
+                        this_word = self.source_bits.getword(0)
+                    else:
                         this_word = self.source_bits.getword(self.source_index)
-                    except IndexError:
-                        this_word = self.source_bits.getword(0)
                     skew_word = prev_word | (this_word & no_skew_mask)
                     prev_word = this_word
                     skew_word = (self.bit_shift(skew_word, self.skew) |
-                                 self.bit_shift(skew_word, self.skew - 16))
+                                 self.bit_shift(skew_word, self.skew - BitBltShadow.WordSize))
                 merge_word = rarithmetic.r_uint(self.merge(
                     skew_word & halftone_word,
                     self.dest_bits.getword(self.dest_index)
@@ -1326,12 +1326,17 @@
             self.dest_index = self.dest_index + self.dest_delta
 
     def bit_shift(self, target, amount):
-        if amount > 0:
+        if amount > 31 or amount < -31:
+            return 0
+        elif amount > 0:
             return (rarithmetic.r_uint(target) << amount) & BitBltShadow.AllOnes
+        elif amount == 0:
+            return target
         else:
-            return (rarithmetic.r_uint(target) >> -amount) & BitBltShadow.AllOnes
+            return (rarithmetic.r_uint(target) >> -amount)
 
     def merge(self, source_word, dest_word):
+        assert isinstance(source_word, rarithmetic.r_uint) and isinstance(dest_word, rarithmetic.r_uint)
         if self.combination_rule == 0:
             return 0
         elif self.combination_rule == 1:
@@ -1364,9 +1369,24 @@
             return ~source_word | ~dest_word
         elif self.combination_rule == 15:
             return dest_word & BitBltShadow.AllOnes
+        elif self.combination_rule >= 16 and self.combination_rule <= 24:
+            return dest_word
+        elif self.combination_rule == 25:
+            if source_word == 0:
+                return dest_word
+            else:
+                return source_word | (dest_word & ~source_word)
+        elif 26 <= self.combination_rule <= 41:
+            return dest_word
         else:
             raise error.PrimitiveFailedError()
 
+    def as_string(bb):
+        return 'aBitBlt (destX: %d, destY: %d, sx: %d, sy: %d, dx: %d, dy: %d, w: %d, h: %d, hDir: %d, vDir: %d, sDelta: %d, dDelta: %d, skew: %d, sI: %d, dI: %d)' % (
+            bb.dest_x, bb.dest_y, bb.sx, bb.sy, bb.dx, bb.dy, bb.w, bb.h, bb.h_dir, bb.v_dir, bb.source_delta, bb.dest_delta, bb.skew, bb.source_index, bb.dest_index)
+            # "dest_raster", "source_raster",
+            # "halftone_bits", "mask1", "mask2", "skew_mask",
+            # "n_words", "preload"
 
 class FormShadow(AbstractCachingShadow):
     _attrs_ = ["w_bits", "width", "height", "depth", "offset_x", "offset_y"]
@@ -1384,8 +1404,8 @@
         w_offset = self.fetch(4)
         assert isinstance(w_offset, model.W_PointersObject)
         if not w_offset is self.space.w_nil:
-            self.offset_x = self.space.unwrap_int(w_offset._fetch(0)) - 1
-            self.offset_y = self.space.unwrap_int(w_offset._fetch(1)) - 1
+            self.offset_x = self.space.unwrap_int(w_offset._fetch(0))
+            self.offset_y = self.space.unwrap_int(w_offset._fetch(1))
 
     # def replace_bits(self):
     #     w_bits = self.w_bits


More information about the pypy-commit mailing list