SF: Define DisplayId as struct type

This prevents accidental mix-up with HWC display IDs, which have the
same backing type, as well as other implicitly convertible integers,
e.g. EDID manufacturer IDs. This CL also fixes misuses detected by
type checking:

1) Recycling of virtual display IDs.
2) Skipping composition for non-HWC virtual displays.
3) Unit tests for fallback/virtual display IDs.

Bug: 74619554
Bug: 119412688
Test: libsurfaceflinger_unittest
Test: vrflinger_test on walleye_xr
Change-Id: I0be41cc93c82860e859f1adf427430436c926595
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 7c5c1bc..071f07d 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -647,7 +647,7 @@
 }
 
 std::string DisplayDevice::getDebugName() const {
-    const auto id = mId ? base::StringPrintf("%" PRIu64 ", ", *mId) : std::string();
+    const auto id = mId ? to_string(*mId) + ", " : std::string();
     return base::StringPrintf("DisplayDevice{%s%s%s\"%s\"}", id.c_str(),
                               isPrimary() ? "primary, " : "", isVirtual() ? "virtual, " : "",
                               mDisplayName.c_str());