Though the display drivers are allowed to export almost any acceleration function they like, there is one restriction: a display driver may not provide an "unsafe" operation that could crash or damage the system. Recall that any user can open the graph devices and start performing ioctls. We do not want to allow such users to crash the system.
Suppose you're writing a driver for a poorly designed video card which can be "locked up" by writing illegal values to its registers. In that case, it would not be legal for the driver to export the video registers directly. Similarly, if exporting the registers would give the user the power to fry the monitor, then it is also not allowed.
There is a second consideration: kernel complexity should be kept minimal. The writer of a display driver shouldn't provide a hundred acceleration functions for drawing patterned ellipses, dotted lines, filled polygons, shaded 3D polygons... that's just too much to put in the kernel. A driver providing no more than ten acceleration functions would make us happy. One providing twenty would makes us nervous. One providing a hundred would probably be rejected. We like to keep the acceleration functions to about 4 kbytes.
We like it when drivers provide "bulk" operations like "draw array of shapes". Bulk operations are more efficient, because they can do a lot of drawing in just one ioctl. We also like it when drivers provide operations like "mmap the frame buffer". That's a nice one, because libggi only needs one mmap to set things up, and the rest can be done in libggi. This is efficient, and it keeps the kernel simple. And when "mmap the video registers" can be done safely, that neatly transfers all the smarts out of the kernel, and into libggi.