void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
        {
            var writeableBitmap = image.Source as WriteableBitmap;

            if (writeableBitmap == null || writeableBitmap.PixelWidth != width || writeableBitmap.PixelHeight != height)
            {
                image.Source = writeableBitmap = new WriteableBitmap(width, height, dpiX, dpiY, AbstractRenderHandler.PixelFormat, null);
            }

            if (writeableBitmap != null)
            {
                writeableBitmap.Lock();

                NativeMethodWrapper.MemoryCopy(writeableBitmap.BackBuffer, buffer, writeableBitmap.BackBufferStride * writeableBitmap.PixelHeight);

                if (invalidateDirtyRect)
                {
                    writeableBitmap.AddDirtyRect(new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height));
                }
                else
                {
                    writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight));
                }
                writeableBitmap.Unlock();
            }
        }
        /// <inheritdoc/>
        /// <remarks>
        /// NOTE: DevTools popups DO NOT trigger OnBeforePopup.
        /// </remarks>
        protected override bool OnBeforePopup(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
        {
            newBrowser = null;

            //No action so we'll go with the default behaviour.
            if (onPopupCreated == null)
            {
                return(false);
            }

            var webBrowser = (ChromiumWebBrowser)chromiumWebBrowser;

            //We need to execute sync here so IWindowInfo.SetAsChild is called before we return false;
            webBrowser.InvokeSyncOnUiThreadIfRequired(new Action(() =>
            {
                var control = new ChromiumHostControl
                {
                    Dock = DockStyle.Fill
                };
                control.CreateControl();

                onPopupCreated?.Invoke(control, targetUrl);

                var rect = control.ClientRectangle;

                var windowBounds = new CefSharp.Structs.Rect(rect.X, rect.Y, rect.Width, rect.Height);

                windowInfo.SetAsChild(control.Handle, windowBounds);
            }));

            return(false);
        }
        /// <summary>
        /// Open DevTools using your own Control as the parent. If inspectElementAtX and/or inspectElementAtY are specified then
        /// the element at the specified (x,y) location will be inspected.
        /// For resize/moving to work correctly you will need to use the <see cref="CefSharp.WinForms.Handler.LifeSpanHandler"/> implementation.
        /// (Set <see cref="ChromiumWebBrowser.LifeSpanHandler"/> to an instance of <see cref="CefSharp.WinForms.Handler.LifeSpanHandler"/>)
        /// </summary>
        /// <param name="chromiumWebBrowser"><see cref="ChromiumWebBrowser"/> instance</param>
        /// <param name="addParentControl">
        /// Action that is Invoked when the DevTools Host Control has been created and needs to be added to it's parent.
        /// It's important the control is added to it's intended parent at this point so the <see cref="Control.ClientRectangle"/>
        /// can be calculated to set the initial display size.</param>
        /// <param name="inspectElementAtX">x coordinate (used for inspectElement)</param>
        /// <param name="inspectElementAtY">y coordinate (used for inspectElement)</param>
        /// <returns>Returns the <see cref="Control"/> that hosts the DevTools instance if successful, otherwise returns null on error.</returns>
        public static Control ShowDevToolsDocked(this IChromiumWebBrowserBase chromiumWebBrowser, Action <ChromiumHostControl> addParentControl, string controlName = nameof(ChromiumHostControl) + "DevTools", DockStyle dockStyle = DockStyle.Fill, int inspectElementAtX = 0, int inspectElementAtY = 0)
        {
            if (chromiumWebBrowser.IsDisposed || addParentControl == null)
            {
                return(null);
            }

            var host = chromiumWebBrowser.GetBrowserHost();

            if (host == null)
            {
                return(null);
            }

            var control = new ChromiumHostControl()
            {
                Name = controlName,
                Dock = dockStyle
            };

            control.CreateControl();

            //It's now time for the user to add the control to it's parent
            addParentControl(control);

            //Devtools will be a child of the ChromiumHostControl
            var rect         = control.ClientRectangle;
            var windowInfo   = new WindowInfo();
            var windowBounds = new CefSharp.Structs.Rect(rect.X, rect.Y, rect.Width, rect.Height);

            windowInfo.SetAsChild(control.Handle, windowBounds);
            host.ShowDevTools(windowInfo, inspectElementAtX, inspectElementAtY);

            return(control);
        }
Exemple #4
0
        private void CopyMemoryGentle(IntPtr source, IntPtr destination, Rect dirtyRect, RenderInfo info)
        {
            IntPtr newDestination = new IntPtr(destination.ToInt64() + dirtyRect.Y * info.Width * info.BytesPerPixel + dirtyRect.X * info.BytesPerPixel);
            IntPtr newSource      = new IntPtr(source.ToInt64() + dirtyRect.Y * info.Width * info.BytesPerPixel + dirtyRect.X * info.BytesPerPixel);
            int    length         = (dirtyRect.Height - 1) * info.Width * info.BytesPerPixel + dirtyRect.Width * info.BytesPerPixel;

            CopyMemory(newDestination, newSource, (uint)length);
        }
Exemple #5
0
 public RenderInfo(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
 {
     IsPopup   = isPopup;
     DirtyRect = dirtyRect;
     Buffer    = buffer;
     Width     = width;
     Height    = height;
     Image     = image;
 }
Exemple #6
0
        void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
        {
            if (image.Dispatcher.HasShutdownStarted)
            {
                return;
            }

            int pixels        = width * height;
            int numberOfBytes = pixels * BytesPerPixel;
            var stride        = width * BytesPerPixel;
            var tempBuffer    = new byte[numberOfBytes];

            //Copy unmanaged memory to our buffer
            Marshal.Copy(buffer, tempBuffer, 0, numberOfBytes);

            image.Dispatcher.BeginInvoke((Action)(() =>
            {
                var bitmap = image.Source as WriteableBitmap;

                if (bitmap == null || bitmap.PixelHeight != height || bitmap.PixelWidth != width)
                {
                    if (image.Source != null)
                    {
                        image.Source = null;
                        GC.Collect(1);
                    }

                    image.Source = bitmap = new WriteableBitmap(width, height, dpiX, dpiY, PixelFormat, null);
                }

                //Get a ptr to our temp buffer
                var tempBufferPtr = Marshal.UnsafeAddrOfPinnedArrayElement(tempBuffer, 0);

                //By default we'll only update the dirty rect, for those that run into a MILERR_WIN32ERROR Exception (#2035)
                //it's desirably to either upgrade to a newer .Net version (only client runtime needs to be installed, not compiled
                //against a newer version. Or invalidate the whole bitmap
                if (invalidateDirtyRect)
                {
                    // Update the dirty region
                    var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);

                    bitmap.Lock();
                    bitmap.WritePixels(sourceRect, tempBufferPtr, numberOfBytes, stride, dirtyRect.X, dirtyRect.Y);
                    bitmap.Unlock();
                }
                else
                {
                    // Update whole bitmap
                    var sourceRect = new Int32Rect(0, 0, width, height);

                    bitmap.Lock();
                    bitmap.WritePixels(sourceRect, tempBufferPtr, numberOfBytes, stride);
                    bitmap.Unlock();
                }
            }), dispatcherPriority);
        }
Exemple #7
0
        internal void OnBrowserRequestsPainting(CefSharp.Structs.Rect dirtyRect, IntPtr buffer, int width, int height)
        {
            if (_colorBuffer == null || _colorBuffer.Width != width || _colorBuffer.Height != height)
            {
                _colorBuffer?.Dispose();
                _colorBuffer = new DeviceIndependentBitmap(width, height);
            }

            _colorBuffer.CopyFromBuffer(buffer, (uint)(width * height * 4 /*RGBA*/));

            var blend = new NativeMethods.BlendFunction
            {
                BlendOp             = NativeMethods.AC_SRC_OVER,
                BlendFlags          = 0,
                SourceConstantAlpha = 255,
                AlphaFormat         = NativeMethods.AC_SRC_ALPHA
            };
            var windowPosition = new NativeMethods.Point
            {
                X = this.Left,
                Y = this.Top
            };
            var surfaceSize = new NativeMethods.Size
            {
                Width  = _colorBuffer.Width,
                Height = _colorBuffer.Height
            };
            var surfacePosition = new NativeMethods.Point
            {
                X = 0,
                Y = 0
            };

            try
            {
                IntPtr handle = this.InvokeSyncOnUI((f) => f.Handle); //IntPtr.Zero;
                                                                      // this.InvokeSyncOnUIThread(() => handle = this.Handle);

                NativeMethods.UpdateLayeredWindow(
                    handle,
                    IntPtr.Zero,
                    ref windowPosition,
                    ref surfaceSize,
                    _colorBuffer.DeviceContext,
                    ref surfacePosition,
                    0,
                    ref blend,
                    NativeMethods.ULW_ALPHA);
            }
            catch (ObjectDisposedException ex)
            {
                //can happen, when the form gets killed by the ui thread while we try to render CEF stuff on it
                _colorBuffer?.Dispose();
            }
        }
 void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
 {
     if (isPopup)
     {
         CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref popupSize, ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
     }
     else
     {
         CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref viewSize, ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
     }
 }
        void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
        {
            if (image.Dispatcher.HasShutdownStarted)
            {
                return;
            }

            lock (lockObj)
            {
                var layer = isPopup ? popup : view;
                layer.OnPaint(dirtyRect, buffer, width, height, image);
            }
        }
        void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
        {
            lock (lockObject)
            {
                if (IsDisposed || image.Dispatcher.HasShutdownStarted)
                {
                    return;
                }

                var paintElement = isPopup ? popup : view;
                paintElement?.UpdateBuffer(dirtyRect, buffer, width, height, image);
                paintElement?.UpdateImage(lockObject);
            }
        }
Exemple #11
0
        /// <summary>
        /// Called when an element should be painted. (Invoked from CefRenderHandler.OnPaint)
        /// This method is only called when <see cref="IWindowInfo.SharedTextureEnabled"/> is set to false.
        /// </summary>
        /// <param name="isPopup">indicates whether the element is the view or the popup widget.</param>
        /// <param name="dirtyRect">contains the set of rectangles in pixel coordinates that need to be repainted</param>
        /// <param name="buffer">The bitmap will be will be  width * height *4 bytes in size and represents a BGRA image with an upper-left origin</param>
        /// <param name="width">width</param>
        /// <param name="height">height</param>
        /// <param name="image">image used as parent for rendered bitmap</param>
        public virtual void OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
        {
            if (image.Dispatcher.HasShutdownStarted)
            {
                return;
            }

            if (isPopup)
            {
                CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref popupSize, ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
            }
            else
            {
                CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref viewSize, ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
            }
        }
            internal void OnPaint(Rect dirtyRect, IntPtr sourceBuffer, int width, int height, Image image)
            {
                ImageSize = (width * height) * AbstractRenderHandler.BytesPerPixel;

                if (BufferSize < ImageSize)
                {
                    Marshal.FreeHGlobal(Buffer);
                    Buffer     = Marshal.AllocHGlobal(ImageSize);
                    BufferSize = ImageSize;
                }

                Width     = width;
                Height    = height;
                DirtyRect = dirtyRect;

                NativeMethodWrapper.MemoryCopy(Buffer, sourceBuffer, ImageSize);

                Image   = image;
                IsDirty = true;
            }
            internal void UpdateBuffer(Rect dirtyRect, IntPtr sourceBuffer, int width, int height, Image image)
            {
                imageSize = (width * height) * AbstractRenderHandler.BytesPerPixel;

                if (bufferSize < imageSize)
                {
                    Marshal.FreeHGlobal(buffer);
                    buffer     = Marshal.AllocHGlobal(imageSize);
                    bufferSize = imageSize;
                }

                this.width     = width;
                this.height    = height;
                this.dirtyRect = dirtyRect;

                NativeMethodWrapper.MemoryCopy(buffer, sourceBuffer, imageSize);

                this.image = image;
                IsDirty    = true;
            }
            public void OnPaint(CefSharp.Structs.Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
            {
                lock (_lock)
                {
                    int numberOfBytes = (width * height) * (System.Windows.Media.PixelFormats.Pbgra32.BitsPerPixel / 8);

                    if (_bufferSize < numberOfBytes)
                    {
                        System.Runtime.InteropServices.Marshal.FreeHGlobal(_buffer);
                        _buffer     = System.Runtime.InteropServices.Marshal.AllocHGlobal(numberOfBytes);
                        _bufferSize = numberOfBytes;
                    }

                    _width  = width;
                    _height = height;

                    CopyMemory(_buffer, buffer, numberOfBytes);

                    _image = image; //Invalidate
                }
            }
Exemple #15
0
        void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
        {
            //File.AppendAllText("DEBUG.txt", DateTime.Now.ToLongTimeString() + this.GetHashCode() + " ONPAINT " + isPopup + " " + buffer + " - " + width + "x" + height + " " + image.GetHashCode() + Environment.NewLine);
            if (image.Dispatcher.HasShutdownStarted ||
                (dirtyRect.X == 0 && dirtyRect.Y == 0 && dirtyRect.Width == 0 && dirtyRect.Height == 0))
            {
                return;
            }

            if (isPopup)
            {
                CurrentPopupRenderInfo = new RenderInfo(isPopup, dirtyRect, buffer, width, height, image);

                ReleaseMemoryMappedView(ref memoryMappedFile, ref memoryMappedViewAccessor);
                memoryMappedFile         = MemoryMappedFile.CreateNew(null, CurrentRenderInfo.NumberOfBytes, MemoryMappedFileAccess.ReadWrite);
                memoryMappedViewAccessor = memoryMappedFile.CreateViewAccessor();

                var data = texA.LockRectangle(0, LockFlags.ReadOnly);
                CopyMemoryGentle(data.DataPointer, memoryMappedViewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), CurrentRenderInfo.NumberOfBytes);
                texA.UnlockRectangle(0);

                ReleaseMemoryMappedView(ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
                popupMemoryMappedFile         = MemoryMappedFile.CreateNew(null, CurrentPopupRenderInfo.NumberOfBytes, MemoryMappedFileAccess.ReadWrite);
                popupMemoryMappedViewAccessor = popupMemoryMappedFile.CreateViewAccessor();
                CopyMemoryGentle(CurrentPopupRenderInfo.Buffer, popupMemoryMappedViewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), CurrentPopupRenderInfo.NumberOfBytes);

                DirectXRender(CurrentPopupRenderInfo);
            }
            else
            {
                CurrentRenderInfo.IsPopup   = isPopup;
                CurrentRenderInfo.DirtyRect = dirtyRect;
                CurrentRenderInfo.Buffer    = buffer;
                CurrentRenderInfo.Width     = width;
                CurrentRenderInfo.Height    = height;
                CurrentRenderInfo.Image     = image;
                DirectXRender(CurrentRenderInfo);
            }
        }
Exemple #16
0
 /// <summary>
 /// Called when an element has been rendered to the shared texture handle.
 /// This method is only called when <see cref="IWindowInfo.SharedTextureEnabled"/> is set to true
 /// </summary>
 /// <param name="isPopup">indicates whether the element is the view or the popup widget.</param>
 /// <param name="dirtyRect">contains the set of rectangles in pixel coordinates that need to be repainted</param>
 /// <param name="sharedHandle">is the handle for a D3D11 Texture2D that can be accessed via ID3D11Device using the OpenSharedResource method.</param>
 void IRenderHandler.OnAcceleratedPaint(bool isPopup, Rect dirtyRect, IntPtr sharedHandle)
 {
     //NOT USED
 }
Exemple #17
0
        protected override void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
        {
            bool createNewBitmap = false;

            lock (lockObject)
            {
                int pixels        = width * height;
                int numberOfBytes = pixels * BytesPerPixel;

                createNewBitmap = mappedFile == null || currentSize.Height != height || currentSize.Width != width;

                if (createNewBitmap)
                {
                    //If the MemoryMappedFile is smaller than we need then create a larger one
                    //If it's larger then we need then rather than going through the costly expense of
                    //allocating a new one we'll just use the old one and only access the number of bytes we require.
                    if (viewAccessor == null || viewAccessor.Capacity < numberOfBytes)
                    {
                        ReleaseMemoryMappedView(ref mappedFile, ref viewAccessor);

                        mappedFile = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite);

                        viewAccessor = mappedFile.CreateViewAccessor();
                    }

                    currentSize.Height = height;
                    currentSize.Width  = width;
                }

                NativeMethodWrapper.MemoryCopy(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, numberOfBytes);

                //Take a reference to the sourceBuffer that's used to update our WritableBitmap,
                //once we're on the UI thread we need to check if it's still valid
                var sourceBuffer = viewAccessor.SafeMemoryMappedViewHandle;

                image.Dispatcher.BeginInvoke((Action)(() =>
                {
                    lock (lockObject)
                    {
                        if (sourceBuffer.IsClosed || sourceBuffer.IsInvalid)
                        {
                            return;
                        }

                        if (createNewBitmap)
                        {
                            if (image.Source != null)
                            {
                                image.Source = null;
                                GC.Collect(1);
                            }

                            image.Source = new WriteableBitmap(width, height, dpiX, dpiY, PixelFormat, null);
                        }

                        var stride = width * BytesPerPixel;
                        var noOfBytes = stride * height;

                        var bitmap = (WriteableBitmap)image.Source;

                        //By default we'll only update the dirty rect, for those that run into a MILERR_WIN32ERROR Exception (#2035)
                        //it's desirably to either upgrade to a newer .Net version (only client runtime needs to be installed, not compiled
                        //against a newer version. Or invalidate the whole bitmap
                        if (invalidateDirtyRect)
                        {
                            // Update the dirty region
                            var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);

                            bitmap.Lock();
                            bitmap.WritePixels(sourceRect, sourceBuffer.DangerousGetHandle(), noOfBytes, stride, dirtyRect.X, dirtyRect.Y);
                            bitmap.Unlock();
                        }
                        else
                        {
                            // Update whole bitmap
                            var sourceRect = new Int32Rect(0, 0, width, height);

                            bitmap.Lock();
                            bitmap.WritePixels(sourceRect, sourceBuffer.DangerousGetHandle(), noOfBytes, stride);
                            bitmap.Unlock();
                        }
                    }
                }), dispatcherPriority);
            }
        }
        private void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
        {
            bool createNewBitmap = false;

            if (image.Dispatcher.HasShutdownStarted)
            {
                return;
            }

            lock (lockObject)
            {
                int pixels        = width * height;
                int numberOfBytes = pixels * BytesPerPixel;

                createNewBitmap = mappedFile == null || currentSize.Height != height || currentSize.Width != width;

                if (createNewBitmap)
                {
                    ReleaseMemoryMappedView(ref mappedFile, ref viewAccessor);

                    mappedFile = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite);

                    viewAccessor = mappedFile.CreateViewAccessor();

                    currentSize.Height = height;
                    currentSize.Width  = width;
                }

                //TODO: Performance analysis to determine which is the fastest memory copy function
                //NativeMethodWrapper.CopyMemoryUsingHandle(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, numberOfBytes);
                CopyMemory(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, (uint)numberOfBytes);

                //Take a reference to the sourceBuffer that's used to update our WritableBitmap,
                //once we're on the UI thread we need to check if it's still valid
                var sourceBuffer = viewAccessor.SafeMemoryMappedViewHandle;

                image.Dispatcher.BeginInvoke((Action)(() =>
                {
                    lock (lockObject)
                    {
                        if (sourceBuffer.IsClosed || sourceBuffer.IsInvalid)
                        {
                            return;
                        }

                        if (createNewBitmap)
                        {
                            if (image.Source != null)
                            {
                                image.Source = null;
                                GC.Collect(1);
                            }

                            image.Source = new WriteableBitmap(width, height, dpiX, dpiY, PixelFormat, null);
                        }

                        var stride = width * BytesPerPixel;
                        var noOfBytes = stride * height;

                        var bitmap = (WriteableBitmap)image.Source;

                        //By default we'll only update the dirty rect, for those that run into a MILERR_WIN32ERROR Exception (#2035)
                        //it's desirably to either upgrade to a newer .Net version (only client runtime needs to be installed, not compiled
                        //against a newer version. Or invalidate the whole bitmap
                        if (invalidateDirtyRect)
                        {
                            // Update the dirty region
                            var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);

                            bitmap.Lock();
                            bitmap.WritePixels(sourceRect, sourceBuffer.DangerousGetHandle(), noOfBytes, stride, dirtyRect.X, dirtyRect.Y);
                            bitmap.Unlock();
                        }
                        else
                        {
                            // Update whole bitmap
                            var sourceRect = new Int32Rect(0, 0, width, height);

                            bitmap.Lock();
                            bitmap.WritePixels(sourceRect, sourceBuffer.DangerousGetHandle(), noOfBytes, stride);
                            bitmap.Unlock();
                        }
                    }
                }), dispatcherPriority);
            }
        }
 public virtual void SetAsChild(System.IntPtr parentHandle, CefSharp.Structs.Rect windowBounds)
 {
 }
        public void OnPaint(bool isPopup, CefSharp.Structs.Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
        {
            var layer = isPopup ? this._popup : this._background;

            layer.OnPaint(dirtyRect, buffer, width, height, image);
        }
 public void OnAcceleratedPaint(bool isPopup, CefSharp.Structs.Rect dirtyRect, IntPtr sharedHandle)
 {
     //throw new NotImplementedException();
 }
Exemple #22
0
        protected override void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
        {
            var createNewBitmap = false;

            lock (lockObject)
            {
                int pixels        = width * height;
                int numberOfBytes = pixels * BytesPerPixel;

                createNewBitmap = mappedFile == null || currentSize.Height != height || currentSize.Width != width;

                if (createNewBitmap)
                {
                    ReleaseMemoryMappedView(ref mappedFile, ref viewAccessor);

                    mappedFile = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite);

                    viewAccessor = mappedFile.CreateViewAccessor();

                    currentSize.Height = height;
                    currentSize.Width  = width;
                }

                //TODO: Performance analysis to determine which is the fastest memory copy function
                //NativeMethodWrapper.CopyMemoryUsingHandle(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, numberOfBytes);
                CopyMemory(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, (uint)numberOfBytes);

                //Take a reference to the backBufferHandle, once we're on the UI thread we need to check if it's still valid
                var backBufferHandle = mappedFile.SafeMemoryMappedFileHandle;

                //Invoke on the WPF UI Thread
                image.Dispatcher.BeginInvoke((Action)(() =>
                {
                    lock (lockObject)
                    {
                        if (backBufferHandle.IsClosed || backBufferHandle.IsInvalid)
                        {
                            return;
                        }

                        if (createNewBitmap)
                        {
                            if (image.Source != null)
                            {
                                image.Source = null;
                                //TODO: Is this still required in newer versions of .Net?
                                GC.Collect(1);
                            }

                            var stride = width * BytesPerPixel;
                            var bitmap = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(backBufferHandle.DangerousGetHandle(), width, height, PixelFormat, stride, 0);
                            image.Source = bitmap;
                        }
                        else if (image.Source != null)
                        {
                            var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);
                            var bitmap = (InteropBitmap)image.Source;
                            bitmap.Invalidate(sourceRect);
                        }
                    }
                }), dispatcherPriority);
            }
        }
        protected override void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
        {
            var createNewBitmap = false;

            lock (lockObject)
            {
                int pixels        = width * height;
                int numberOfBytes = pixels * BytesPerPixel;

                createNewBitmap = mappedFile == null || currentSize.Height != height || currentSize.Width != width;

                if (createNewBitmap)
                {
                    ReleaseMemoryMappedView(ref mappedFile, ref viewAccessor);

                    mappedFile = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite);

                    viewAccessor = mappedFile.CreateViewAccessor();

                    currentSize.Height = height;
                    currentSize.Width  = width;
                }

                NativeMethodWrapper.MemoryCopy(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, numberOfBytes);

                //Take a reference to the backBufferHandle, once we're on the UI thread we need to check if it's still valid
                var backBufferHandle = mappedFile.SafeMemoryMappedFileHandle;

                //Invoke on the WPF UI Thread
                image.Dispatcher.BeginInvoke((Action)(() =>
                {
                    lock (lockObject)
                    {
                        if (backBufferHandle.IsClosed || backBufferHandle.IsInvalid)
                        {
                            return;
                        }

                        var size = isPopup ? popupSize : viewSize;

                        //If OnPaint is called multiple times before
                        //our BeginInvoke call we check the size matches our most recent
                        //update, the buffer has already been overriden (frame is dropped effectively)
                        //so we ignore this call
                        //https://github.com/cefsharp/CefSharp/issues/3114
                        if (size.Width != width || size.Height != height)
                        {
                            return;
                        }

                        if (createNewBitmap)
                        {
                            if (image.Source != null)
                            {
                                image.Source = null;
                                //TODO: Is this still required in newer versions of .Net?
                                GC.Collect(1);
                            }

                            var stride = width * BytesPerPixel;
                            var bitmap = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(backBufferHandle.DangerousGetHandle(), width, height, PixelFormat, stride, 0);
                            image.Source = bitmap;
                        }
                        else if (image.Source != null)
                        {
                            var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);
                            var bitmap = (InteropBitmap)image.Source;
                            bitmap.Invalidate(sourceRect);
                        }
                    }
                }), dispatcherPriority);
            }
        }
Exemple #24
0
        /// <inheritdoc/>
        /// <remarks>
        /// NOTE: DevTools popups DO NOT trigger OnBeforePopup.
        /// </remarks>
        protected override bool OnBeforePopup(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
        {
            newBrowser = null;

            PopupCreation userAction = onBeforePopupCreated?.Invoke(chromiumWebBrowser, browser, frame, targetUrl, targetFrameName, targetDisposition, userGesture, browserSettings) ?? PopupCreation.Continue;

            //Cancel popup creation
            if (userAction == PopupCreation.Cancel)
            {
                return(true);
            }

            if (userAction == PopupCreation.ContinueWithJavascriptDisabled)
            {
                noJavascriptAccess = true;
            }

            //No action so we'll go with the default behaviour.
            if (onPopupCreated == null)
            {
                return(false);
            }

            var webBrowser = (ChromiumWebBrowser)chromiumWebBrowser;

            //Load and Display Handlers are used to trigger the relevant events.
            //If they are already assigned we'll leave the user preference in place
            if (webBrowser.LoadHandler == null)
            {
                webBrowser.LoadHandler = new LoadHandler();
            }
            if (webBrowser.DisplayHandler == null)
            {
                webBrowser.DisplayHandler = new DisplayHandler();
            }

            //We need to execute sync here so IWindowInfo.SetAsChild is called before we return false;
            webBrowser.InvokeSyncOnUiThreadIfRequired(new Action(() =>
            {
                ChromiumHostControl control = chromiumHostControlCreatedDelegate?.Invoke();

                if (control == null)
                {
                    control = new ChromiumHostControl
                    {
                        Dock = DockStyle.Fill
                    };
                }
                control.CreateControl();

                onPopupCreated?.Invoke(control, targetUrl);

                var rect = control.ClientRectangle;

                var windowBounds = new CefSharp.Structs.Rect(rect.X, rect.Y, rect.Width, rect.Height);

                windowInfo.SetAsChild(control.Handle, windowBounds);
            }));

            return(false);
        }
Exemple #25
0
 /// <summary>
 /// Called when an element has been rendered to the shared texture handle.
 /// This method is only called when <see cref="IWindowInfo.SharedTextureEnabled"/> is set to true
 /// </summary>
 /// <param name="isPopup">indicates whether the element is the view or the popup widget.</param>
 /// <param name="dirtyRect">contains the set of rectangles in pixel coordinates that need to be repainted</param>
 /// <param name="sharedHandle">is the handle for a D3D11 Texture2D that can be accessed via ID3D11Device using the OpenSharedResource method.</param>
 public virtual void OnAcceleratedPaint(bool isPopup, Rect dirtyRect, IntPtr sharedHandle)
 {
     // NOT USED
 }
        protected override void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
        {
            bool createNewBitmap = false;

            lock (lockObject)
            {
                int pixels        = width * height;
                int numberOfBytes = pixels * BytesPerPixel;

                createNewBitmap = mappedFile == null || currentSize.Height != height || currentSize.Width != width;

                if (createNewBitmap)
                {
                    //If the MemoryMappedFile is smaller than we need then create a larger one
                    //If it's larger then we need then rather than going through the costly expense of
                    //allocating a new one we'll just use the old one and only access the number of bytes we require.
                    if (viewAccessor == null || viewAccessor.Capacity < numberOfBytes)
                    {
                        ReleaseMemoryMappedView(ref mappedFile, ref viewAccessor);

                        mappedFile = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite);

                        viewAccessor = mappedFile.CreateViewAccessor();
                    }

                    currentSize.Height = height;
                    currentSize.Width  = width;
                }

                NativeMethodWrapper.MemoryCopy(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, numberOfBytes);

                //Take a reference to the sourceBuffer that's used to update our WritableBitmap,
                //once we're on the UI thread we need to check if it's still valid
                var sourceBuffer = viewAccessor.SafeMemoryMappedViewHandle;

                image.Dispatcher.BeginInvoke((Action)(() =>
                {
                    lock (lockObject)
                    {
                        if (sourceBuffer.IsClosed || sourceBuffer.IsInvalid)
                        {
                            return;
                        }

                        var size = isPopup ? popupSize : viewSize;

                        //If OnPaint is called multiple times before
                        //our BeginInvoke call we check the size matches our most recent
                        //update, the buffer has already been overriden (frame is dropped effectively)
                        //so we ignore this call
                        //https://github.com/cefsharp/CefSharp/issues/3114
                        if (size.Width != width || size.Height != height)
                        {
                            return;
                        }

                        if (createNewBitmap)
                        {
                            if (image.Source != null)
                            {
                                image.Source = null;
                                GC.Collect(1);
                            }

                            image.Source = new WriteableBitmap(width, height, dpiX, dpiY, PixelFormat, null);
                        }

                        var stride = width * BytesPerPixel;
                        var noOfBytes = stride * height;

                        var bitmap = (WriteableBitmap)image.Source;

                        //When agressively resizing the ChromiumWebBrowser sometimes
                        //we can end up with our buffer size not matching our bitmap size
                        //Just ignore these frames as the rendering should eventually catch up
                        //(CEF can generate multiple frames before WPF has performed a render cycle)
                        //https://github.com/cefsharp/CefSharp/issues/3474
                        if (width > bitmap.PixelWidth || height > bitmap.PixelHeight)
                        {
                            return;
                        }

                        //By default we'll only update the dirty rect, for those that run into a MILERR_WIN32ERROR Exception (#2035)
                        //it's desirably to either upgrade to a newer .Net version (only client runtime needs to be installed, not compiled
                        //against a newer version. Or invalidate the whole bitmap
                        if (invalidateDirtyRect)
                        {
                            // Update the dirty region
                            var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);

                            bitmap.Lock();
                            bitmap.WritePixels(sourceRect, sourceBuffer.DangerousGetHandle(), noOfBytes, stride, dirtyRect.X, dirtyRect.Y);
                            bitmap.Unlock();
                        }
                        else
                        {
                            // Update whole bitmap
                            var sourceRect = new Int32Rect(0, 0, width, height);

                            bitmap.Lock();
                            bitmap.WritePixels(sourceRect, sourceBuffer.DangerousGetHandle(), noOfBytes, stride);
                            bitmap.Unlock();
                        }
                    }
                }), dispatcherPriority);
            }
        }
Exemple #27
0
 protected abstract void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor);
 void IRenderHandler.OnAcceleratedPaint(bool isPopup, Rect dirtyRect, IntPtr sharedHandle)
 {
     throw new NotImplementedException();
 }
        private void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
        {
            if (image.Dispatcher.HasShutdownStarted)
            {
                return;
            }

            var createNewBitmap = false;

            lock (lockObject)
            {
                int pixels        = width * height;
                int numberOfBytes = pixels * BytesPerPixel;

                createNewBitmap = mappedFile == null || currentSize.Height != height || currentSize.Width != width;

                if (createNewBitmap)
                {
                    //If the MemoryMappedFile is smaller than we need then create a larger one
                    //If it's larger then we need then rather than going through the costly expense of
                    //allocating a new one we'll just use the old one and only access the number of bytes we require.
                    if (viewAccessor == null || viewAccessor.Capacity < numberOfBytes)
                    {
                        ReleaseMemoryMappedView(ref mappedFile, ref viewAccessor);

                        mappedFile = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite);

                        viewAccessor = mappedFile.CreateViewAccessor();
                    }

                    currentSize.Height = height;
                    currentSize.Width  = width;
                }

                //TODO: Performance analysis to determine which is the fastest memory copy function
                //NativeMethodWrapper.CopyMemoryUsingHandle(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, numberOfBytes);
                CopyMemory(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, (uint)numberOfBytes);

                //Take a reference to the backBufferHandle, once we're on the UI thread we need to check if it's still valid
                var backBufferHandle = mappedFile.SafeMemoryMappedFileHandle;

                image.Dispatcher.BeginInvoke((Action)(() =>
                {
                    lock (lockObject)
                    {
                        if (backBufferHandle.IsClosed || backBufferHandle.IsInvalid)
                        {
                            return;
                        }

                        if (createNewBitmap)
                        {
                            if (image.Source != null)
                            {
                                image.Source = null;
                                GC.Collect(1);
                            }

                            var stride = width * BytesPerPixel;
                            var bitmap = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(backBufferHandle.DangerousGetHandle(), width, height, PixelFormat, stride, 0);
                            image.Source = bitmap;
                        }
                        else
                        {
                            if (image.Source != null)
                            {
                                var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);
                                var bitmap = (InteropBitmap)image.Source;
                                bitmap.Invalidate(sourceRect);
                            }
                        }
                    }
                }), dispatcherPriority);
            }
        }
 void CefSharp.Internals.IRenderWebBrowser.OnPaint(CefSharp.PaintElementType type, CefSharp.Structs.Rect dirtyRect, IntPtr buffer, int width, int height)
 {
     OnPaintDelegate.Invoke(type, dirtyRect, buffer, width, height);
 }