Commits

Brendan Howell  committed 26ca2e9

Fixed #5
this is now well optimized using one cairo context for all operations and
blitting once per frame with a direct surfarray operation. I get 60-90 FPS
on ol' Ada, my Pentium4. Should be good enough for now. Anything better
will have to come from hardware optimization.

  • Participants
  • Parent commits a20f351

Comments (0)

Files changed (1)

File drawing_cairo.py

         self.fill = True
         self.fill_color = (0.5, 0, 0.5, 1)
         
-    #TODO: see if this can be optimized and just grab the context every time
+    #grab the context at the beginning of the frame
     def setSurface(self, sdl_surface):
         self.sdl_surface = sdl_surface
         width = sdl_surface.get_width()
         height = sdl_surface.get_height()
         
-        stride = width * 4
-        self.data = array.array("c",chr(0) * width * height * 4)
-        self.surface = cairo.ImageSurface.create_for_data(self.data, cairo.FORMAT_ARGB32, width, height, stride)
+        self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
         self.ctx = cairo.Context(self.surface)
         self.pangoctx = pangocairo.CairoContext(self.ctx)
         self.font_map = pangocairo.cairo_font_map_get_default()
         self.families = self.font_map.list_families()
         
     def setBackground(self, red, green, blue):
-        #self.setSurface(self.sdl_surface)
         self.ctx.set_source_rgba(blue/255.0, green/255.0, red/255.0, 1)
         self.ctx.paint()
-        #self._blitToScreen()
-
         
     def setStroke(self, red, green, blue, alpha=255, width=1):
         self.setStrokeWidth(width)
         self.fill = fill
         
     def rect(self, x, y, width, height): 
-        #self.setSurface(self.sdl_surface)
         self.ctx.rectangle(x, y, width, height)
         self._fillAndStroke()
     
     def circle(self, cx, cy, radius):
-        #self.setSurface(self.sdl_surface)
         self.ctx.arc(cx, cy, radius, 0, 2.0 * math.pi)
         self._fillAndStroke()
     
     def ellipse(self, cx, cy, width, height):
-        #self.setSurface(self.sdl_surface)
         self.ctx.save()
         self.ctx.translate(cx, cy)
         self.ctx.scale(width / 2.0, height / 2.0)
         self._fillAndStroke()
     
     def arc(self, cx, cy, radius, startAngle, endAngle):
-        #self.setSurface(self.sdl_surface)
         self.ctx.arc(cx, cy, radius, math.radians(startAngle), math.radians(endAngle))
         self._fillAndStroke()
         
     def line(self, x1, y1, x2, y2):
-        #self.setSurface(self.sdl_surface)
         self.ctx.move_to(x1, y1)
         self.ctx.line_to(x2, y2)
         self._fillAndStroke()
     
     def polygon(self, pointlist):
-        #self.setSurface(self.sdl_surface)
         x, y = pointlist[0]
         self.ctx.move_to(x, y)
         for point in pointlist[1:]:
         self._fillAndStroke()
                 
     def curve(self, x1, y1, cx1, cy1, cx2, cy2, x2, y2):
-        #self.setSurface(self.sdl_surface)
         self.ctx.move_to(x1, y1)
         self.ctx.curve_to(cx1, cy1, cx2, cy2, x2, y2)
         self._fillAndStroke()
         self.pangoctx.show_layout(layout)
         print('F => %s %s'%layout.get_pixel_size())
         self.ctx.restore()
-        #self._blitToScreen()
         
     def _fillAndStroke(self):
         if(self.fill):
             self.ctx.stroke()
         else:
             self.ctx.new_path()
-        #self.surface.finish()
-        #self._blitToScreen()
-        
+
+    #TODO: finish this
     def renderToPDF(self, fileName):
     	self.surface = cairo.PDFSurface(fileName, self.sdl_surface.get_width(), self.sdl_surface.get_height())
     	
-    	#
-    	
-    	
-        
-    def _blitToScreen(self):
-        #data_string = bgra_surf_to_rgba_string(self.surface)
-        blue = self.data[0::4]
-        red = self.data[2::4]
-        self.data[0::4] = red 
-        self.data[2::4] = blue
-        pygame_surface = pygame.image.frombuffer(self.data.tostring(), 
-                (self.sdl_surface.get_width(), 
-                 self.sdl_surface.get_height()
-                ), 
-                'RGBA')
-        self.sdl_surface.unlock()
-        self.sdl_surface.blit(pygame_surface, (0,0))        
+
+    def _blitToScreen(self):  
+        dest = pygame.surfarray.pixels2d(self.sdl_surface)
+        dest.data[:] = self.surface.get_data()