Author: Tim Felgentreff <[email protected]>
Branch: rbitblt
Changeset: r549:8070c7ef400e
Date: 2014-01-03 16:28 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/8070c7ef400e/

Log:    use SDL surface depths where possible, map depths <8. has what looks
        like endianess issues for depth < 32

diff --git a/spyvm/display.py b/spyvm/display.py
--- a/spyvm/display.py
+++ b/spyvm/display.py
@@ -34,8 +34,15 @@
         self.width = w
         self.height = h
         self.depth = d
-        self.screen = RSDL.SetVideoMode(w, h, 32, 0)
-        assert self.screen
+        flags = RSDL.HWPALETTE | RSDL.RESIZABLE | RSDL.ASYNCBLIT | 
RSDL.DOUBLEBUF
+        if d < 8:
+            d = 8
+        self.screen = RSDL.SetVideoMode(w, h, d, flags)
+        if not self.screen:
+            print "Could not open display at depth %d" % d
+            raise RuntimeError
+        elif d == 8:
+            self.set_squeak_colormap(self.screen)
 
     def get_pixelbuffer(self):
         return rffi.cast(rffi.ULONGP, self.screen.c_pixels)
@@ -43,6 +50,24 @@
     def flip(self):
         RSDL.Flip(self.screen)
 
+    def set_squeak_colormap(self, screen):
+        # TODO: fix this up from the image
+        colors = lltype.malloc(rffi.CArray(RSDL.ColorPtr.TO), 4, flavor='raw')
+        colors[0].c_r = rffi.r_uchar(255)
+        colors[0].c_g = rffi.r_uchar(255)
+        colors[0].c_b = rffi.r_uchar(255)
+        colors[1].c_r = rffi.r_uchar(0)
+        colors[1].c_g = rffi.r_uchar(0)
+        colors[1].c_b = rffi.r_uchar(0)
+        colors[2].c_r = rffi.r_uchar(128)
+        colors[2].c_g = rffi.r_uchar(128)
+        colors[2].c_b = rffi.r_uchar(128)
+        colors[3].c_r = rffi.r_uchar(255)
+        colors[3].c_g = rffi.r_uchar(255)
+        colors[3].c_b = rffi.r_uchar(255)
+        RSDL.SetColors(self.screen, rffi.cast(RSDL.ColorPtr, colors), 0, 4)
+        lltype.free(colors, flavor='raw')
+
     def handle_mouse_button(self, c_type, event):
         b = rffi.cast(RSDL.MouseButtonEventPtr, event)
         btn = rffi.getintfield(b, 'c_button')
@@ -102,6 +127,8 @@
                 elif c_type == RSDL.KEYDOWN:
                     self.handle_keypress(c_type, event)
                     return
+                elif c_type == RSDL.VIDEORESIZE:
+                    pass # TODO
                 elif c_type == RSDL.QUIT:
                     from spyvm.error import Exit
                     raise Exit("Window closed..")
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -968,22 +968,16 @@
             lltype.free(self.c_words, flavor='raw')
 
 
-NATIVE_DEPTH = 32
-
 class W_DisplayBitmap(W_AbstractObjectWithClassReference):
-    _attrs_ = ['pixelbuffer', '_realsize', '_real_depth_buffer', 'display']
-    _immutable_fields_ = ['_realsize', 'display']
+    _attrs_ = ['pixelbuffer', '_realsize', '_real_depth_buffer', 'display', 
'_depth']
+    _immutable_fields_ = ['_realsize', 'display', '_depth']
 
     @staticmethod
     def create(space, w_class, size, depth, display):
-        if depth == 1:
-            return W_DisplayBitmap1Bit(space, w_class, size, depth, display)
-        elif depth == 16:
-            return W_DisplayBitmap16Bit(space, w_class, size, depth, display)
-        elif depth == 32:
-            return W_DisplayBitmap32Bit(space, w_class, size, depth, display)
+        if depth < 8:
+            return W_MappingDisplayBitmap(space, w_class, size * (8 / depth), 
depth, display)
         else:
-            raise NotImplementedError("non B/W squeak")
+            return W_DisplayBitmap(space, w_class, size, depth, display)
 
     def __init__(self, space, w_class, size, depth, display):
         W_AbstractObjectWithClassReference.__init__(self, space, w_class)
@@ -991,6 +985,7 @@
         self.pixelbuffer = display.get_pixelbuffer()
         self._realsize = size
         self.display = display
+        self._depth = depth
 
     def at0(self, space, index0):
         val = self.getword(index0)
@@ -1019,14 +1014,11 @@
 
     def getword(self, n):
         assert self.size() > 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")
+        self._real_depth_buffer[n] = word
+        self.pixelbuffer[n] = word
 
     def is_array_object(self):
         return True
@@ -1041,58 +1033,45 @@
     def __del__(self):
         lltype.free(self._real_depth_buffer, flavor='raw')
 
-    @jit.elidable
-    def compute_pos_and_line_end(self, n, depth):
-        width = self.display.width
-        words_per_line = width / (NATIVE_DEPTH / depth)
-        if width % (NATIVE_DEPTH / depth) != 0:
-            words_per_line += 1
-        line = n / words_per_line
-        assert line < self.display.height # line is 0 based
-        line_start = width * line
-        line_end = line_start + width # actually the start of the next line
-        pos = ((n % words_per_line) * (NATIVE_DEPTH / depth)) + line_start
-        return pos, line_end
 
-
-class W_DisplayBitmap1Bit(W_DisplayBitmap):
+NATIVE_DEPTH = 8
+class W_MappingDisplayBitmap(W_DisplayBitmap):
     @jit.unroll_safe
     def setword(self, n, word):
         self._real_depth_buffer[n] = word
-        pos, line_end = self.compute_pos_and_line_end(n, 1)
-        mask = r_uint(1)
-        mask <<= 31
-        for i in xrange(32):
-            if pos == line_end:
+        word = r_uint(word)
+        pos = self.compute_pos(n)
+        # pos, line_end = self.compute_pos_and_line_end(n, self._depth)
+        maskR = r_uint(2 ** self._depth - 1)
+        mask = maskR << (32 - self._depth)
+        rshift = 32 - self._depth
+        for i in xrange(8 / self._depth):
+            if pos >= self.size():
                 return
-            bit = mask & word
-            pixel = r_uint((0x00ffffff * (bit == 0)) | r_uint(0xff000000))
-            self.pixelbuffer[pos] = pixel
-            mask >>= 1
+            mapword = r_uint(0)
+            for i in xrange(4):
+                pixel = r_uint(word) >> rshift
+                mapword <<= 8
+                mapword |= r_uint(pixel)
+                word <<= self._depth
+            self.pixelbuffer[pos] = mapword
             pos += 1
 
-class W_DisplayBitmap16Bit(W_DisplayBitmap):
-    @jit.unroll_safe
-    def setword(self, n, word):
-        self._real_depth_buffer[n] = word
-        pos, line_end = self.compute_pos_and_line_end(n, 16)
-        for i in xrange(2):
-            if pos >= line_end:
-                return
-            pixel = r_uint(0x0 |
-                           ((word & 0b111110000000000) << 9) |
-                           ((word & 0b000001111100000) << 6) |
-                           ((word & 0b000000000011111) << 3)
-            )
-            self.pixelbuffer[pos] = pixel
-            word = (word >> 16) & 0xffff
-            pos += 1
+    def compute_pos(self, n):
+        return n * (NATIVE_DEPTH / self._depth)
 
-class W_DisplayBitmap32Bit(W_DisplayBitmap):
-    @jit.unroll_safe
-    def setword(self, n, word):
-        self._real_depth_buffer[n] = word
-        self.pixelbuffer[n] = word
+    # @jit.elidable
+    # def compute_pos_and_line_end(self, n, depth):
+    #     width = self.display.width
+    #     words_per_line = width / (NATIVE_DEPTH / depth)
+    #     if width % (NATIVE_DEPTH / depth) != 0:
+    #         words_per_line += 1
+    #     line = n / words_per_line
+    #     assert line < self.display.height # line is 0 based
+    #     line_start = width * line
+    #     line_end = line_start + width # actually the start of the next line
+    #     pos = ((n % words_per_line) * (NATIVE_DEPTH / depth)) + line_start
+    #     return pos, line_end
 
 # XXX Shouldn't compiledmethod have class reference for subclassed compiled
 # methods?
diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py
--- a/spyvm/squeakimage.py
+++ b/spyvm/squeakimage.py
@@ -376,6 +376,14 @@
         self.lastWindowSize = reader.lastWindowSize
         self.version = reader.version
         self.is_modern = reader.version.magic > 6502
+        # self.run_spy_hacks(space)
+
+    def run_spy_hacks(self, space):
+        w_display = space.objtable["w_display"]
+        if w_display is not None and w_display is not space.w_nil:
+            if space.unwrap_int(w_display.fetch(space, 3)) < 8:
+                # non-native indexed color depth not well supported
+                w_display.store(space, 3, space.wrap_int(32))
 
     def find_symbol(self, space, reader, symbol):
         w_dnu = self.special(constants.SO_DOES_NOT_UNDERSTAND)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to