Talking about graphics api, one can do it in the geometry stage, or in a vertex shader, and give it the look of diversity and randomness, even a systematic influence and movement like wind would have, by offsetting a mesh via texture lookups.
Basis would be just a few meshes, a deciduous tree, coniferous tree, one or two fruit trees, one can introduce variation through colour, size, rotation, bending. That's very fast, it wouldn't much affect the performance even if thousands of objects where rendered that way, as long as they aren't too complicated and one can do it in a single draw call through instancing, which GLES3 supports, I think.
See the basic example of a grass field, but this can be taken much farther of course.
Hope this isn't too much over engineering :-)
GPU tessellation has disadvantages, it is relatively limited in its functionality, and it doesn't really generate geometry. The above is much more flexible.