A pipe sends its output to the program that has it open for reading. In a shell pipeline, that's the program on the right-hand side of the pipe symbol, i.e.
evince in your example.
You're sending the file name
tmp.pdf to evince on its standard input. However evince doesn't care about its standard input. Like every program that acts on a file, it expects the file name to be passed as a command line argument; if you don't pass a file name on the command line, it offers to open a file. Command line arguments are not the same thing as standard input. Humans have different input organs that input different things (e.g. you can't eat through your nose), and similarly programs have different ways of receiving information that serve different purposes.
Evince can read a file (not a file name) on standard input:
evince /dev/stdin <"tmp.pdf". (This may not work on all Unix variants.) The file name
/dev/stdin means “whatever file you already have open on your standard input”. Programs intended for command line typically read their standard input when they aren't given a file name, but GUI programs usually don't. Evince can only open a regular file this way, not data from a pipe (e.g.
cat tmp.pdf | evince /dev/stdin doesn't work), because it needs to be able to seek back and forth in the file when navigating between pages.