It is actually a very interesting question. Initially I thought that a definitive answer does not even exist; after all, it is only certain that speed difference between these methods deviates based on hardware and driver version, just like it does for every other thing.
But what exactly makes that speed deviation? Lets look at the difference between old-fashioned fixed-function blending and custom fragment program blending. Maybe some kind of conclusion will arise.
Fixed-function blending uses one of the predefined equations to mix fragment color outputs with the framebuffer color values:
- render first texture to the framebuffer;
- set blending function and parameters for a simple alpha blending;
- render second texture to the framebuffer. Note that fixed-function blending is performed directly on the framebuffer, sampling it and modifying it at the same time.
Shader-based blending uses custom fragment program to turn a fragment into colors and a depth value:
- render first texture to a previously allocated texture buffer;
- change shader program to one with custom blending of any complexity;
- render second texture to the framebuffer while reading texture buffer from step 1.
It may seem that fixed-function blending should be faster, due to GPU's special hardware for simple blending, direct framebuffer reads and lack of an additional memory buffer.
However, nowadays video memory is usually abundant, and hardware is really optimized for customizable pipeline, so there is no gain on read speed. GPU's speed for simple blending is highly hardware dependent, but so is the shaders performance.
There is one important detail still missing: framebuffer blending has its own stage in rendering pipeline — it is independent from fragment shaders. Which means fixed-function blending can be generally considered being "always faster" simply because it can perform blending operations while custom fragment shader program is processing later fragments.
This also means that fixed-function blending contributes to your ROP count and, consequently, framebuffer bandwidth. And fragment shaders contribute to your fragment shading costs. Frame-buffer bandwidth is a function of GPU memory clock, and fragment-shading speed is a function of the GPU core clock.
So in case of performance problems with two concerned techniques it is possible to be ROP-bound or fragment-shading-bound. (Actually, there are other possible resource bounds, like limit on vertex transformations, but these does not matter in context of the question.)
Just for the sake of completeness and possible effects on the texture sampling performance, it is also worth noting that texture bandwidth is consumed any time a texture fetch request goes out to memory. Texture bandwidth is also a function of GPU memory clock.
In conclusion, use blending for simple blending operations or when you need to blend something with entire framebuffer, and you are not ROP-bound. Use texture sampling when needed or when it suits your code better, and you are not fragment-shading-bound.
Obviously, if you are texture-bandwidth-bound, it is better to avoid unnecessary texture samples, so framebuffer-based blending is preferrable.
Your specific case
As long as you are not bound on those three things mentioned earlier, relative speed of your two methods should be identical. #1 would be easier to tweak and fix, in my opinion.
Also, I have not seen your code, but generally SSAO should be applied only to ambient part of lighting, so blending it over the final scene sounds wrong. All the more reason to sample SSAO texture in your lighting shader.