Author: Lars Wassermann <lars.wasserm...@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
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to