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  }