github.com/racerxdl/gonx@v0.0.0-20210103083128-c5afc43bcbd2/services/display/display.go (about) 1 package display 2 3 import ( 4 "fmt" 5 "github.com/racerxdl/gonx/nx/nxerrors" 6 "github.com/racerxdl/gonx/nx/nxtypes" 7 "github.com/racerxdl/gonx/services/am" 8 "github.com/racerxdl/gonx/services/gpu" 9 "github.com/racerxdl/gonx/services/vi" 10 ) 11 12 const debugDisplay = false 13 14 var display *vi.Display 15 var displayInitializations = 0 16 17 func Init() (err error) { 18 if debugDisplay { 19 println("Display::Init()") 20 } 21 displayInitializations++ 22 if displayInitializations > 1 { 23 return nil 24 } 25 26 gpuInit := false 27 viInit := false 28 29 defer func() { 30 if err != nil { 31 displayInitializations-- 32 if viInit { 33 vi.Finalize() 34 } 35 if gpuInit { 36 gpu.Finalize() 37 } 38 } 39 }() 40 41 if debugDisplay { 42 println("Display::Init() - GPU Init") 43 } 44 err = gpu.Init() 45 if err != nil { 46 return err 47 } 48 gpuInit = true 49 50 if debugDisplay { 51 println("Display::Init() - VI Init") 52 } 53 err = vi.Init() 54 if err != nil { 55 return err 56 } 57 viInit = true 58 59 if debugDisplay { 60 println("Display::Init() - Open Display") 61 } 62 display, err = vi.OpenDisplay("Default") 63 if err != nil { 64 return err 65 } 66 67 if debugDisplay { 68 println("Display::Init() - AM Init") 69 } 70 71 return nil 72 } 73 74 func forceFinalize() { 75 if debugDisplay { 76 println("Display::ForceFinalize()") 77 } 78 79 _ = vi.CloseDisplay(display) 80 vi.Finalize() 81 gpu.Finalize() 82 displayInitializations = 0 83 } 84 85 func Finalize() { 86 if debugDisplay { 87 println("Display::Finalize()") 88 } 89 displayInitializations-- 90 if displayInitializations <= 0 { 91 forceFinalize() 92 } 93 } 94 95 func OpenLayer() (surface *Surface, err error) { 96 if debugDisplay { 97 println("Display::OpenLayer()") 98 } 99 if displayInitializations < 1 { 100 return nil, nxerrors.DisplayNotInitialized 101 } 102 103 var layerId uint64 104 var aruid nxtypes.ARUID 105 var igbp *vi.IGBP 106 107 managedLayerInit := false 108 igbpInit := false 109 surfaceInit := false 110 layerId = 0 111 112 defer func() { 113 if err != nil { 114 if surfaceInit { 115 // Surface takes ownership of IGBP and layer 116 surface.Destroy() 117 surface = nil 118 return 119 } 120 121 if igbpInit { 122 _ = vi.AdjustRefCount(igbp.IgbpBinder.Handle, -1, 1) 123 _ = vi.CloseLayer(layerId) 124 } 125 126 if managedLayerInit { 127 _ = vi.DestroyManagedLayer(layerId) 128 } 129 } 130 }() 131 132 aruid, err = am.IwcGetAppletResourceUserId() 133 if err != nil { 134 return surface, err 135 } 136 137 if debugDisplay { 138 println("Display::OpenLayer() - CreateManagedLayer") 139 } 140 if aruid > 0 { 141 // Applet 142 layerId, err = am.IscCreateManagedDisplayLayer() 143 if err != nil { 144 return surface, err 145 } 146 } else { 147 layerId, err = vi.CreateManagedLayer(display, 0, aruid) 148 if err != nil { 149 return surface, err 150 } 151 } 152 managedLayerInit = true 153 154 if debugDisplay { 155 fmt.Printf("Display::OpenLayer() - OpenLayer(\"Default\", %d, %d)\n", layerId, aruid) 156 } 157 igbp, err = vi.OpenLayer("Default", layerId, aruid) 158 if err != nil { 159 return surface, err 160 } 161 igbpInit = true 162 163 if debugDisplay { 164 println("Display::OpenLayer() - SurfaceCreate") 165 } 166 surface, _, err = SurfaceCreate(layerId, *igbp) 167 if err != nil { 168 return surface, err 169 } 170 surfaceInit = true 171 172 if debugDisplay { 173 println("Display::OpenLayer() - IadsSetLayerScalingMode") 174 } 175 err = vi.IadsSetLayerScalingMode(vi.ScalingMode_FitToLayer, layerId) 176 if err != nil { 177 return surface, err 178 } 179 180 return surface, nil 181 } 182 183 func GetVSyncEvent() (nxtypes.ReventHandle, error) { 184 if displayInitializations <= 0 { 185 return 0, nxerrors.DisplayNotInitialized 186 } 187 188 if display.VSync == 0 { 189 err := vi.GetDisplayVsyncEvent(display) 190 if err != nil { 191 return 0, err 192 } 193 } 194 195 return display.VSync, nil 196 }