예제 #1
0
        /// <summary>
        /// Read pixel data from <paramref name="intPtr"/> into our local buffer
        /// and return the total number of bytes read.
        /// </summary>
        /// <param name="header"></param>
        /// <param name="intPtr"></param>
        /// <returns></returns>
        internal int ReadPixelData(InteropRenderHeader header, IntPtr intPtr)
        {
            var pixelArraySize = header.width * header.height * 3;

            lock (renderTextureLock)
            {
                if (Pixels == IntPtr.Zero)
                {
                    InteropLogger.Debug($"Allocating {header.width} x {header.height}");
                    Pixels = Marshal.AllocHGlobal(pixelArraySize);
                }
                else if (header.width != Header.width || header.height != Header.height)
                {
                    // If the inbound data resized - resize our buffer
                    InteropLogger.Debug($"Reallocating {header.width} x {header.height}");
                    Pixels = Marshal.ReAllocHGlobal(Pixels, new IntPtr(pixelArraySize));
                }

                // Could do a Buffer.MemoryCopy here - but I'm locked to
                // .NET 4.5 due to the DllExport library we're using.
                UnsafeNativeMethods.CopyMemory(Pixels, intPtr, (uint)pixelArraySize);

                Header = header;
                Frame++;
            }

            return(pixelArraySize);
        }
예제 #2
0
        /// <summary>
        /// Copy the RenderTexture data from the ViewportController into shared memory with Blender.
        ///
        /// <para>
        ///     The <paramref name="pixelsRGB24Func"/> callback is executed IFF we have room in the
        ///     buffer to write - letting us skip the heavy pixel copy operations if the consumer
        ///     is backed up in processing data.
        /// </para>
        /// </summary>
        internal void PublishRenderTexture(ViewportController viewport, Func <byte[]> pixelsRGB24Func)
        {
            if (!IsConnected)
            {
                Debug.LogWarning("Cannot send RT - No connection");
            }

            Profiler.BeginSample("Write wait on pixelsProducer");

            int bytesWritten = pixelsProducer.Write((ptr) => {
                // If we have a node we can write on, actually do the heavy lifting
                // of pulling the pixel data from the RenderTexture (in the callback)
                // and write into the buffer.
                var pixelsRGB24 = pixelsRGB24Func();

                Profiler.BeginSample("Write Pixels into Shared Memory");

                // Pack a header into shared memory
                var header = new InteropRenderHeader
                {
                    viewportId = viewport.ID,
                    width      = viewport.Width,
                    height     = viewport.Height
                };

                var headerSize = FastStructure.SizeOf <InteropRenderHeader>();
                FastStructure.WriteBytes(ptr, FastStructure.ToBytes(ref header), 0, headerSize);

                // Copy render image data into shared memory
                FastStructure.WriteBytes(ptr + headerSize, pixelsRGB24, 0, pixelsRGB24.Length);

                /*InteropLogger.Debug($"Writing {pixelsRGB24.Length} bytes with meta {header.width} x {header.height} and pix 0 is " +
                 *  $"{pixelsRGB24[0]}, {pixelsRGB24[1]}, {pixelsRGB24[2]}"
                 * );*/

                Profiler.EndSample();
                return(headerSize + pixelsRGB24.Length);
            }, WRITE_WAIT);

            /*
             * if (bytesWritten < 1)
             * {
             *  Debug.LogWarning("pixelsProducer buffer is backed up. Skipped write.");
             * }*/

            Profiler.EndSample();
        }