[pypy-commit] lang-smalltalk rbitblt: start converting squeakjs bitblt

timfel noreply at buildbot.pypy.org
Thu Dec 19 14:23:13 CET 2013


Author: Tim Felgentreff <timfelgentreff at gmail.com>
Branch: rbitblt
Changeset: r542:582625456d68
Date: 2013-12-19 14:22 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/582625456d68/

Log:	start converting squeakjs bitblt

diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -643,32 +643,16 @@
     space = interp.space
 
     s_bitblt = w_rcvr.as_bitblt_get_shadow(space)
-    # See BlueBook p.356ff
-    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()
-    # print s_bitblt.as_string()
-    s_bitblt.copy_loop()
+    s_bitblt.copyBits()
 
     w_dest_form = w_rcvr.fetch(space, 0)
-    if w_dest_form.is_same_object(space.objtable['w_display']):
+    if (combinationRule == 22 or combinationRule == 32):
+        s_frame.pop() # pops the next value under BitBlt
+        s_frame.push(s_bitblt.bitCount())
+    else 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()
-
-    # try:
-    #     s_frame._sendSelfSelector(interp.image.w_simulateCopyBits, 0, interp)
-    # except Return:
-    #     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()
-
-    # in case we return normally, we have to restore the removed w_rcvr
     return w_rcvr
 
 @expose_primitive(BE_CURSOR)
@@ -893,8 +877,8 @@
         raise PrimitiveFailedError
     signature = (w_modulename.as_string(), w_functionname.as_string())
 
-    # if signature == ('BitBltPlugin', 'primitiveCopyBits'):
-    #     return prim_holder.prim_table[BITBLT_COPY_BITS](interp, s_frame, argcount, s_method)
+    if signature == ('BitBltPlugin', 'primitiveCopyBits'):
+        return prim_holder.prim_table[BITBLT_COPY_BITS](interp, s_frame, argcount, s_method)
     if signature[0] == "SocketPlugin":
         from spyvm.plugins.socket import SocketPlugin
         return SocketPlugin.call(signature[1], interp, s_frame, argcount, s_method)
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -1128,111 +1128,117 @@
 
 
 class BitBltShadow(AbstractCachingShadow):
-    _attrs_ = [# From BitBlt
-               "dest_form", "source_form", "halftone_form",
-               "combination_rule", "dest_x", "dest_y", "width",
-               "height", "source_x", "source_y", "clip_x", "clip_y",
-               "clip_width", "clip_height", "color_map",
-               # From BitBltSimulation
-               "w", "h", "sx", "sy", "dx", "dy",
-               "dest_bits", "dest_raster", "source_bits", "source_raster",
-               "halftone_bits", "skew", "mask1", "mask2", "skew_mask",
-               "n_words", "h_dir", "v_dir", "preload", "source_index",
-               "dest_index", "source_delta", "dest_delta"]
-
     WordSize = 32
-    RightMasks = [rarithmetic.r_uint(0)]
+    MaskTable = [rarithmetic.r_uint(0)]
     for i in xrange(WordSize):
-        RightMasks.append(rarithmetic.r_uint((2 ** (i + 1)) - 1))
+        MaskTable.append(rarithmetic.r_uint((2 ** (i + 1)) - 1))
     AllOnes = rarithmetic.r_uint((2 ** WordSize) - 1)
 
     def sync_cache(self):
+        self.loadBitBlt()
+
+    def intOrIfNil(self, w_int, i):
+        if w_int is self.space.w_nil:
+            return i
+        else:
+            return self.space.unwrap_int(w_int)
+
+    def loadForm(self, w_form):
         try:
-            w_form = self.fetch(0)
-            assert isinstance(w_form, model.W_PointersObject)
+            if not isinstance(w_form, model.W_PointersObject):
+                raise PrimitiveFailedError()
             s_form = w_form.as_form_get_shadow(self.space)
-            assert isinstance(s_form, FormShadow)
-            self.dest_form = s_form
+            if not isinstance(s_form, FormShadow):
+                raise PrimitiveFailedError()
+            return s_form
         except error.PrimitiveFailedError, e:
             w_self = self.w_self()
             assert isinstance(w_self, model.W_PointersObject)
             w_self._shadow = None
             raise e
-        w_source_form = self.fetch(1)
-        if w_source_form is self.space.w_nil:
-            self.source_form = None
+
+    def loadHalftone(self, w_halftone_form):
+        if w_halftone_form is self.space.w_nil:
+            return None
+        elif isinstance(w_halftone_form, model.W_WordsObject):
+            # Already a bitmap
+            return w_halftone_form.words
         else:
-            try:
-                w_form = w_source_form
-                assert isinstance(w_form, model.W_PointersObject)
-                s_form = w_form.as_form_get_shadow(self.space)
-                assert isinstance(s_form, FormShadow)
-                self.source_form = s_form
-            except error.PrimitiveFailedError, e:
-                w_self = self.w_self()
-                assert isinstance(w_self, model.W_PointersObject)
-                w_self._shadow = None
-                raise e
-        w_halftone_form = self.fetch(2)
-        if w_halftone_form is not self.space.w_nil:
-            if isinstance(w_halftone_form, model.W_WordsObject):
-                # Already a bitmap
-                self.halftone_bits = w_halftone_form.words
+            assert isinstance(w_halftone_form, model.W_PointersObject)
+            w_bits = w_halftone_form.as_form_get_shadow(self.space).w_bits
+            assert isinstance(w_bits, model.W_WordsObject)
+            return w_bits.words
+
+    def loadColorMap(self, w_color_map):
+        if isinstance(w_color_map, model.W_WordsObject):
+            self.cmLookupTable = w_color_map.words
+            self.cmMask = len(self.cmLookupTable) - 1
+        else:
+            self.cmLookupTable = None
+
+    def loadBitBlt(self):
+        self.success = True
+        self.destForm = self.fetch(0)
+        self.dest = self.loadForm(self.destForm)
+        self.sourceForm = self.fetch(1)
+        if self.sourceForm is not self.space.w_nil:
+            self.source = self.loadForm(self.sourceForm)
+        else:
+            self.source = None
+        self.halftone = self.loadHalftone(self.fetch(2))
+        self.combinationRule = self.space.unwrap_int(self.fetch(3))
+        self.destX = self.intOrIfNil(self.fetch(4), 0)
+        self.destY = self.intOrIfNil(self.fetch(5), 0)
+        self.width = self.intOrIfNil(self.fetch(6), self.dest_form.width)
+        self.height = self.intOrIfNil(self.fetch(7), self.dest_form.height)
+        self.clipX = self.intOrIfNil(self.fetch(10), 0)
+        self.clipY = self.intOrIfNil(self.fetch(11), 0)
+        self.clipW = self.intOrIfNil(self.fetch(12), self.width)
+        self.clipH = self.intOrIfNil(self.fetch(13), self.height)
+        if not self.source:
+            self.sourceX = 0
+            self.sourceY = 0
+        else:
+            self.loadColorMap(self.fetch(14))
+            self.sourceX = self.intOrIfNil(self.fetch(8), 0)
+            self.sourceY = self.intOrIfNil(self.fetch(9), 0)
+
+    def copyBits(self):
+        self.bitCount = 0
+        self.clipRange()
+        if (self.bbW <= 0 ir self.bbH <= 0):
+            return
+        self.destMaskAndPointerInit()
+        if not self.source:
+            self.copyLoopNoSource()
+        else:
+            self.checkSourceOverlap()
+            if self.source.depth !== self.dest.depth:
+                self.copyLoopPixMap()
             else:
-                assert isinstance(w_halftone_form, model.W_PointersObject)
-                w_bits = w_halftone_form.as_form_get_shadow(self.space).w_bits
-                assert isinstance(w_bits, model.W_WordsObject)
-                self.halftone_bits = w_bits.words
-        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))
-        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))
-        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)
+                self.sourceSkewAndPointerInit()
+                self.copyLoop()
 
-    def clip_range(self):
-        if self.dest_x >= self.clip_x:
-            self.sx = self.source_x
-            self.dx = self.dest_x
-            self.w = self.width
-        else:
-            self.sx = self.source_x + (self.clip_x - self.dest_x)
-            self.w = self.width - (self.clip_x - self.dest_x)
-            self.dx = self.clip_x
-        if self.dx + self.w > self.clip_x + self.clip_width:
-            self.w = self.w - (self.dx + self.w - (self.clip_x + self.clip_width))
-        if self.dest_y >= self.clip_y:
-            self.sy = self.source_y
-            self.dy = self.dest_y
-            self.h = self.height
-        else:
-            self.sy = self.source_y + self.clip_y - self.dest_y
-            self.h = self.height - self.clip_y - self.dest_y
-            self.dy = self.clip_y
-        if self.dy + self.h > self.clip_y + self.clip_height:
-            self.h = self.h - (self.dy + self.h - (self.clip_y + self.clip_height))
-        if self.source_form is None:
-            return
-        if self.sx < 0:
-            self.dx = self.dx - self.sx
-            self.w = self.w + self.sx
-            self.sx = 0
-        if self.sx + self.w > self.source_form.width:
-            self.w = self.w - (self.sx + self.w - self.source_form.width)
-        if self.sy < 0:
-            self.dy = self.dy - self.sy
-            self.h = self.h + self.sy
-            self.sy = 0
-        if self.sy + self.h > self.source_form.height:
-            self.h = self.h - (self.sy + self.h - self.source_form.height)
+    def clipRange(self):
+        # intersect with destForm bounds
+        if self.clipX < 0:
+            self.clipW += self.clipX
+            self.clipX = 0
+        if self.clipY < 0:
+            self.clipH += self.clipY
+            self.clipY = 0
+        if self.clipX + self.clipW > self.dest.width:
+            self.clipW = self.dest.width - self.clipX
+        if self.clipY + self.clipH > self.dest.height:
+            self.clipH = self.dest.height - self.clipY
+
+        # intersect with clipRect
+        leftOffset = max(self.clipY - self.destY, 0)
+        self.sx = self.sourceX + leftOffset
+        self.dx = self.destX + leftOffset
+        self.bbW = self.width - leftOffset
+        rightOffset =
+
 
     def compute_masks(self):
         self.dest_bits = self.dest_form.w_bits


More information about the pypy-commit mailing list