What are you trying to accomplish exactly?
The best way to modify a texture (or the screen) pixel-by-pixel is through fragment shaders.
If it needs to be done on the CPU, you'll have a harder time. The standard approach is to modify your pixel array (or ByteBuffer) and upload the new data to your full-screen FBO texture with glTexSubImage2D. This can be costly and obviously isn't something you should do many times per frame. You can optimize by uploading a smaller amount of data where possible, or not uploading any data when nothing changes.
You can also use PBO to make the data transfer asynchronous, which may increase performance.
Another optimization may be to tweak the format and internal format of your texture and pixel buffer, depending on your needs. This could result in sending less data to the GPU (i.e. RGBA = 2,160,000 bytes, LUMINANCE = 540,000 bytes).
If you don't mind losing colour information, you can specify different internalFormat sizes to reduce memory such as GL_RGB5 (5 bits per channel). You can also specify different formats to reduce bandwidth such as GL_RGB_5_6_5 (Green gets an extra bit). More info on the color space
here. Some more OpenGL details on formats
here and
here.
Another solution would be to use a low resolution texture (i.e. half size, 450x300), then render it scaled to the screen using GL_NEAREST filtering. You can see this effect in
GLSL sandbox, where selecting a different number (0.5, 1, 2) will change the resolution and thus drastically alter performance.
TL;DR - use shaders.