예제 #1
0
        private IntPtr GetConfigHandle(EglContext eglContext, IntPtr displayHandle)
        {
            var eglQueryContextHandle = eglContext.Display.GlInterface.GetProcAddress("eglQueryContext");

            // create function by pointer
            var getConfig =
                (GetConfigDelegate)Marshal.GetDelegateForFunctionPointer(eglQueryContextHandle,
                                                                         typeof(GetConfigDelegate));

            // store config ID
            var values = new int[1];

            // getting config ID
            getConfig(displayHandle, eglContext.Context, EglConsts.EGL_CONFIG_ID, values);


            var config  = IntPtr.Zero;
            var attribs = new[]
            {
                EglConsts.EGL_CONFIG_ID, values[0],
                EglConsts.EGL_NONE
            };

            // getting config by ID
            ((EglDisplay)eglContext.Display).EglInterface.ChooseConfig(displayHandle, attribs, out config, 1,
                                                                       out var numConfigs);

            return(config);
        }
예제 #2
0
        public EGLInterop()
        {
            var glFeature = AvaloniaLocator.Current.GetService <IWindowingPlatformGlFeature>();

            _eglContext = glFeature.ImmediateContext as EglContext;

            var pointer = GetEglD3Device(_eglContext);

            _device = new Device(pointer);
        }
예제 #3
0
 internal WinUICompositedWindow(EglContext syncContext,
                                ICompositor compositor,
                                object pumpLock,
                                ICompositionTarget compositionTarget,
                                ICompositionDrawingSurfaceInterop surfaceInterop,
                                IVisual contentVisual, IVisual blurVisual)
 {
     _compositor        = compositor.CloneReference();
     _syncContext       = syncContext;
     _pumpLock          = pumpLock;
     _blurVisual        = blurVisual.CloneReference();
     _compositionTarget = compositionTarget.CloneReference();
     _contentVisual     = contentVisual.CloneReference();
     _surfaceInterop    = surfaceInterop.CloneReference();
 }
        public WinUICompositorConnection(EglPlatformOpenGlInterface gl, object pumpLock)
        {
            _gl                       = gl;
            _pumpLock                 = pumpLock;
            _syncContext              = _gl.PrimaryEglContext;
            _angle                    = (AngleWin32EglDisplay)_gl.Display;
            _compositor               = NativeWinRTMethods.CreateInstance <ICompositor>("Windows.UI.Composition.Compositor");
            _compositor2              = _compositor.QueryInterface <ICompositor2>();
            _compositor5              = _compositor.QueryInterface <ICompositor5>();
            _compositorInterop        = _compositor.QueryInterface <ICompositorInterop>();
            _compositorDesktopInterop = _compositor.QueryInterface <ICompositorDesktopInterop>();
            using var device          = MicroComRuntime.CreateProxyFor <IUnknown>(_angle.GetDirect3DDevice(), true);

            _device    = _compositorInterop.CreateGraphicsDevice(device);
            _blurBrush = CreateBlurBrush();
        }
 internal WinUICompositedWindow(EglContext syncContext,
                                ICompositor compositor,
                                object pumpLock,
                                ICompositionTarget compositionTarget,
                                ICompositionDrawingSurfaceInterop surfaceInterop,
                                IVisual contentVisual, IVisual blurVisual, IVisual micaVisual,
                                ICompositionRoundedRectangleGeometry roundedRectangleGeometry)
 {
     _compositor  = compositor.CloneReference();
     _syncContext = syncContext;
     _pumpLock    = pumpLock;
     _micaVisual  = micaVisual;
     _roundedRectangleGeometry = roundedRectangleGeometry;
     _blurVisual        = blurVisual.CloneReference();
     _compositionTarget = compositionTarget.CloneReference();
     _contentVisual     = contentVisual.CloneReference();
     _surfaceInterop    = surfaceInterop.CloneReference();
 }
예제 #6
0
        void Init(DrmCard card, DrmResources resources, DrmConnector connector, DrmModeInfo modeInfo)
        {
            FbDestroyDelegate = FbDestroyCallback;
            _card             = card;
            uint GetCrtc()
            {
                if (resources.Encoders.TryGetValue(connector.EncoderId, out var encoder))
                {
                    // Not sure why that should work
                    return(encoder.Encoder.crtc_id);
                }
                else
                {
                    foreach (var encId in connector.EncoderIds)
                    {
                        if (resources.Encoders.TryGetValue(encId, out encoder) &&
                            encoder.PossibleCrtcs.Count > 0)
                        {
                            return(encoder.PossibleCrtcs.First().crtc_id);
                        }
                    }

                    throw new InvalidOperationException("Unable to find CRTC matching the desired mode");
                }
            }

            _crtcId = GetCrtc();
            var device = gbm_create_device(card.Fd);

            _gbmTargetSurface = gbm_surface_create(device, modeInfo.Resolution.Width, modeInfo.Resolution.Height,
                                                   GbmColorFormats.GBM_FORMAT_XRGB8888, GbmBoFlags.GBM_BO_USE_SCANOUT | GbmBoFlags.GBM_BO_USE_RENDERING);
            if (_gbmTargetSurface == null)
            {
                throw new InvalidOperationException("Unable to create GBM surface");
            }



            _eglDisplay = new EglDisplay(new EglInterface(eglGetProcAddress), 0x31D7, device, null);
            _eglSurface = _eglDisplay.CreateWindowSurface(_gbmTargetSurface);


            EglContext CreateContext(EglContext share)
            {
                var offSurf = gbm_surface_create(device, 1, 1, GbmColorFormats.GBM_FORMAT_XRGB8888,
                                                 GbmBoFlags.GBM_BO_USE_RENDERING);

                if (offSurf == null)
                {
                    throw new InvalidOperationException("Unable to create 1x1 sized GBM surface");
                }
                return(_eglDisplay.CreateContext(share, _eglDisplay.CreateWindowSurface(offSurf)));
            }

            _immediateContext = CreateContext(null);
            _deferredContext  = CreateContext(_immediateContext);

            _immediateContext.MakeCurrent(_eglSurface);
            _eglDisplay.GlInterface.ClearColor(0, 0, 0, 0);
            _eglDisplay.GlInterface.Clear(GlConsts.GL_COLOR_BUFFER_BIT | GlConsts.GL_STENCIL_BUFFER_BIT);
            _eglSurface.SwapBuffers();
            var bo          = gbm_surface_lock_front_buffer(_gbmTargetSurface);
            var fbId        = GetFbIdForBo(bo);
            var connectorId = connector.Id;
            var mode        = modeInfo.Mode;


            var res = drmModeSetCrtc(_card.Fd, _crtcId, fbId, 0, 0, &connectorId, 1, &mode);

            if (res != 0)
            {
                throw new Win32Exception(res, "drmModeSetCrtc failed");
            }

            _mode      = mode;
            _currentBo = bo;

            // Go trough two cycles of buffer swapping (there are render artifacts otherwise)
            for (var c = 0; c < 2; c++)
            {
                using (CreateGlRenderTarget().BeginDraw())
                {
                    _eglDisplay.GlInterface.ClearColor(0, 0, 0, 0);
                    _eglDisplay.GlInterface.Clear(GlConsts.GL_COLOR_BUFFER_BIT | GlConsts.GL_STENCIL_BUFFER_BIT);
                }
            }
        }
예제 #7
0
        private static int RunApp()
        {
            app.Out.WriteLine("Hello World!");

            int brightnessValue = 100;

            if (brightness.HasValue())
            {
                if (int.TryParse(brightness.Value(), out brightnessValue))
                {
                    if (brightnessValue < 1 || brightnessValue > 100)
                    {
                        app.Error.WriteLine("Brightness value outside allowed values");
                        return(-1);
                    }
                }
                else
                {
                    app.Error.WriteLine("Invalid brightness value");
                    return(-1);
                }
            }

            //long uid = UnixUserInfo.GetRealUserId();
            //if (uid != 0)
            //{
            //    app.Out.WriteLine("You must run this app as root.");
            //    return -1;
            //}

            //ServiceCollection serviceConfig = new ServiceCollection();
            //serviceConfig.AddLogging();
            //serviceConfig.AddOptions();

            //serviceConfig.AddBcm();
            //serviceConfig.AddOpenGl();
            //serviceConfig.AddLedMatrix();

            //using (ServiceProvider services = serviceConfig.BuildServiceProvider())
            //{
            //    services.GetRequiredService<ILoggerFactory>().AddConsole(LogLevel.Information);

            //    return RunApp(services);
            //}

            using (LedMatrixOptions options = new LedMatrixOptions()
            {
                chain_length = 2,
                parallel = 1,
                rows = 64,
                led_rgb_sequence = "RBG",
                pwm_bits = 8,
                show_refresh_rate = 1,
                brightness = brightnessValue,
            })
                using (LedMatrix matrix = new LedMatrix(options.rows, options.chain_length, options.parallel))
                    using (BcmHost host = new BcmHost())
                        using (Resource target = host.Dispman.CreateResource(VC_IMAGE_TYPE_T.VC_IMAGE_RGB888, matrix.CanvasWidth, matrix.CanvasHeight))
                            using (Display display = host.Dispman.DisplayOpenOffscreen(target, DISPMANX_TRANSFORM_T.DISPMANX_NO_ROTATE))
                                //using (Display display = host.Dispman.DisplayOpen(Screen.MAIN_LCD))
                                using (ScopedElement element = ScopedElement.Create(host, display, null, destRect: display.Rectangle, srcRect: Rescale(display.Rectangle)))
                                    using (DispmanWindow window = new DispmanWindow(element, display.Width, display.Height))
                                        using (EglDisplay eglDisp = new EglDisplay())
                                            using (EglContext ctx = new EglContext(eglDisp))
                                                using (EglSurface surface = new EglSurface(eglDisp, window))
                                                    using (Data data = new Data())
                                                    {
                                                        Rectangle rect = display.Rectangle;
                                                        app.Out.WriteLine("Ready to go, screen is {0}x{1}", display.Width, display.Height);
                                                        Stopwatch swatch = Stopwatch.StartNew();

                                                        app.Out.WriteLine("Initializing 3D context");
                                                        ctx.MakeCurrent(surface);

                                                        app.Out.WriteLine("init_ogl");
                                                        init_ogl();
                                                        app.Out.WriteLine("init_model_proj");
                                                        init_model_proj(rect, data);
                                                        app.Out.WriteLine("init_textures");
                                                        init_textures(data);

                                                        app.Out.WriteLine("Initializing buffer");
                                                        //int bufferLength = rect.Width * rect.Height * 3;
                                                        //byte[] buffer = new byte[bufferLength];

                                                        app.Out.WriteLine("Init complete, starting loop");
                                                        //Render loop
                                                        bool run = true;
                                                        Console.CancelKeyPress += (s, e) =>
                                                        {
                                                            if (run)
                                                            {
                                                                run      = false;
                                                                e.Cancel = true;
                                                            }
                                                        };
                                                        Console.TreatControlCAsInput = true;

                                                        int    pitch = Utils.ALIGN_UP(3 * display.Width, 32);
                                                        byte[] image = new byte[pitch * display.Height];
                                                        app.Out.WriteLine("Buffer size: {0}", image.Length);
                                                        while (run)
                                                        {
                                                            if (Console.KeyAvailable)
                                                            {
                                                                var key = Console.ReadKey(true);
                                                                if (key.Key == ConsoleKey.C && key.Modifiers == ConsoleModifiers.Control)
                                                                {
                                                                    run = false;
                                                                    Console.TreatControlCAsInput = false;
                                                                    continue;
                                                                }
                                                                if (key.Key == ConsoleKey.Add || key.Key == ConsoleKey.Subtract)
                                                                {
                                                                    int newB;
                                                                    if (key.Key == ConsoleKey.Add)
                                                                    {
                                                                        newB = Math.Min(options.brightness + 1, 100);
                                                                    }
                                                                    else
                                                                    {
                                                                        newB = Math.Max(options.brightness - 1, 0);
                                                                    }
                                                                    if (options.brightness != newB)
                                                                    {
                                                                        options.brightness = newB;
                                                                        app.Out.WriteLine("New brightness: {0}%", newB);
                                                                        if (!matrix.UpdateOptions(options))
                                                                        {
                                                                            app.Out.WriteLine("Update option failed");
                                                                        }
                                                                    }
                                                                }
                                                            }

                                                            update_model();
                                                            redraw_scene(surface);

                                                            //extract data to buffer
                                                            //target.WriteData(1, buffer, rect);
                                                            target.ReadData(rect, image, pitch);

                                                            //Display image to matrix
                                                            matrix.UpdateCanvas(canvas =>
                                                            {
                                                                for (int x = 0; x < canvas.Width; x++)
                                                                {
                                                                    for (int y = 0; y < canvas.Height; y++)
                                                                    {
                                                                        int baseAddr = (x * canvas.Width + y) * 3;
                                                                        try
                                                                        {
                                                                            byte r = image[baseAddr + 0];
                                                                            byte g = image[baseAddr + 1];
                                                                            byte b = image[baseAddr + 2];
                                                                            canvas.SetPixel(x, y, r, g, b);
                                                                        }
                                                                        catch (IndexOutOfRangeException ex)
                                                                        {
                                                                            app.Out.WriteLine("X={0} Y={1} baseAddre={2} pitch={3}", x, y, baseAddr, pitch);
                                                                            System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(ex).Throw();
                                                                        }
                                                                    }
                                                                }
                                                            });
                                                            app.Out.Write(".");
                                                        }

                                                        return(0);
                                                    }
        }