Isn't the original graphics.library written in C?
All versions (1.x through 3.x) are written in a mix of 'C' and 68k assembly language, strongly leaning towards 68k assembly code. Looking at the API, you'll find that a large part of the operations are about filling in data structures, hooking them up and then eventually telling the hardware what to do with them. Typically, the "clerical operations" are written in 'C', and the part which talks to the hardware is written in assembly language.
graphics.library, like intuition.library, is one of the more complex operating system components, both in how it uses data structures and how many distinct operations it can carry out. Hence, you'll find that 'C' plays a major part in its implementation.
That said, when you need to talk to the hardware in a very specific manner, you couldn't do that quite so elegantly back in 1986 if you didn't use 68k assembly language. There is complex assembly language code in graphics.library, it even uses its own preprocessor (!) in order to simplify writing loops (while .. do) and control structures (if .. then .. else).
You can't expect a C compiler to match the optimizations made manually by an assembler programmer. I've heard so many stories about how well C compilers optimize these days and how assembler is made redundant, and then when you actually disassemble the code the compiler produced, it's bloated, filled with jump tables, and inefficient code.
If you have specific requirements for carrying out operations, you may get better control through the use of assembly language than any modern 'C' compiler could provide you with. C11 has just gained new control keywords in order to make interfacing to hardware more straightforward, but it will take a while for the language to evolve to give you the kind of control only assembly language can give you.
As for assembly language becoming largely redundant, it's probably unavoidable. 'C' in particular is a more expressive language which encodes in fewer lines what assembly language, by its very nature, requires much more effort to express. The thing is, if you can say the same thing with fewer words, the chances of mucking it up are somewhat reduced. If you have the right language, you can even verify the correctness of the instructions and data structures you used, which is something that eludes assembly language by its very design.
As for inefficient code, performance nowadays does not necessarily come out of implementing an algorithm through the optimum low level language encoding you could choose (that being assembly language). You can't necessarily predict how your code will be executed, and if you can, you might have to run the gauntlet of observing a handful of operating conditions under which it executes, such as regarding optimum pipeline use, prefetch, etc. This can get so ugly that it has to be automated (look up how one programmed the Motorola 56000 DSP in its day, just to get an idea how weird this can get) just to let the programmer worry about implementing his design correctly.
This is how progress looks like: the gains made through building faster processors are used in such a way that writing more complex software, more secure software and more reliable software becomes an easier goal to achieve through the use of tools and code generation which does not necessarily attempt to squeeze the last cycle out of the machine. This is, in the end a trade-off, if not a sacrifice.