To improve performance when drawing pixel rectangles, follow these guidelines:

Disable all per-fragment operations.

Disable
texturing and fog.

Define images in the native hardware format so type
conversion is not necessary.

Know where the bottleneck is.

Similar to polygon drawing, there can be a pixel-drawing bottleneck due to
overload in host bandwidth, processing, or rasterizing. When all modes are
off, the path is most likely limited by host bandwidth, and a wise choice of
host pixel format and type pays off tremendously. For this reason, using
type GL_ UNSIGNED_BYTE, for the image components is sometimes faster.

Zooming up pixels may create a raster bottleneck.

A big pixel rectangle has a higher throughput (that is, pixels per
second) than a small rectangle. Because the imaging pipeline is tuned to trade
off a relatively large setup time with a high throughput, a large rectangle
amortizes the setup cost over many pixels.