def _draw_as_bitmap(self, context, opacity):
        """
            instead of caching paths, this function caches the whole drawn thing
            use cache_as_bitmap on sprite to enable this mode
        """
        matrix = context.get_matrix()
        matrix_changed = matrix != self._last_matrix
        new_instructions = self.__new_instructions is not None and len(self.__new_instructions) > 0

        if not new_instructions and not matrix_changed:
            context.save()
            context.identity_matrix()
            context.translate(self.extents.x, self.extents.y)
            context.set_source_surface(self.cache_surface)
            if opacity < 1:
                context.paint_with_alpha(opacity)
            else:
                context.paint()
            context.restore()
            return


        if new_instructions:
            self.__instruction_cache = list(self.__new_instructions)
            self.__new_instructions = deque()

        self.paths = []
        self.extents = None

        if not self.__instruction_cache:
            # no instructions - nothing to do
            return

        # instructions that end path
        path_end_instructions = ("new_path", "clip", "stroke", "fill", "stroke_preserve", "fill_preserve")

        # measure the path extents so we know the size of cache surface
        # also to save some time use the context to paint for the first time
        extents = gdk.Rectangle()
        for instruction, args in self.__instruction_cache:
            if instruction in path_end_instructions:
                self.paths.append((instruction, "path", context.copy_path()))
                exts = context.path_extents()
                exts = get_gdk_rectangle(int(exts[0]), int(exts[1]),
                                         int(exts[2]-exts[0]), int(exts[3]-exts[1]))
                if extents.width and extents.height:
                    extents = gdk.rectangle_union(extents, exts)
                else:
                    extents = exts
            elif instruction in ("save", "restore", "translate", "scale", "rotate"):
                self.paths.append((instruction, "transform", args))


            if instruction in ("set_source_pixbuf", "set_source_surface"):
                # draw a rectangle around the pathless instructions so that the extents are correct
                pixbuf = args[0]
                x = args[1] if len(args) > 1 else 0
                y = args[2] if len(args) > 2 else 0
                context.rectangle(x, y, pixbuf.get_width(), pixbuf.get_height())
                context.clip()

            if instruction == "paint" and opacity < 1:
                context.paint_with_alpha(opacity)
            elif instruction == "set_color":
                self._set_color(context, args[0], args[1], args[2], args[3] * opacity)
            elif instruction == "show_layout":
                self._show_layout(context, *args)
            else:
                getattr(context, instruction)(*args)


        # avoid re-caching if we have just moved
        just_transforms = new_instructions == False and \
                          matrix and self._last_matrix \
                          and all([matrix[i] == self._last_matrix[i] for i in range(4)])

        # TODO - this does not look awfully safe
        extents.x += matrix[4] - 5
        extents.y += matrix[5] - 5
        self.extents = extents

        if not just_transforms:
            # now draw the instructions on the caching surface
            w = int(extents.width) + 10
            h = int(extents.height) + 10
            self.cache_surface = context.get_target().create_similar(cairo.CONTENT_COLOR_ALPHA, w, h)
            ctx = cairo.Context(self.cache_surface)
            ctx.translate(-extents.x, -extents.y)

            ctx.transform(matrix)
            for instruction, args in self.__instruction_cache:
                if instruction == "set_color":
                    self._set_color(ctx, args[0], args[1], args[2], args[3])
                elif instruction == "show_layout":
                    self._show_layout(ctx, *args)
                else:
                    getattr(ctx, instruction)(*args)

        self._last_matrix = matrix