protected virtual bool UpdateVertexBufferFromGeometrySource(IEnumerable <TDxPoint> newPoints) { bool vertexBufferSizeChanged = false; // Vertices will be resized to the next power of 2, saves on resizing too much _pointList = newPoints.ToArray(); var pointCount = _pointList.Length; // There's an issue with nVidia cards that the rendering pipeline locks up if we try to reuse // Vertex buffers allocated on the default pool. AMD cards seem to be ok. Work around is to use // the system pool, which is slow, or lock the back buffer via the target image. if (DxHost.LockImage()) { if (_vertexBuffer == null || pointCount > _vertexBufferAllocated || pointCount < (_vertexBufferAllocated >> 1)) { _vertexBuffer?.Dispose(); var newSize = MathHelper.CeilingPow2(pointCount); _vertexBuffer = new VertexBuffer(Device, Utilities.SizeOf <TDxPoint>() * newSize, Usage.WriteOnly, VertexFormat.None, Pool.Default); _vertexBufferAllocated = newSize; vertexBufferSizeChanged = true; } // Lock the entire buffer by specifying 0 for the offset and size, throw away it's current contents var vertexStream = _vertexBuffer.Lock(0, 0, LockFlags.Discard); vertexStream.WriteRange(_pointList); _vertexBuffer.Unlock(); DxHost.UnlockImage(); } _vertexCount = pointCount; // Calculate the bounds of the list on a background thread var localPointList = _pointList; var dataTransform = Plotter.Viewport.Transform.DataTransform; if (localPointList.Any()) { Action resizeAction = () => { var minX = localPointList[0].X; var maxX = localPointList[0].X; var minY = localPointList[0].Y; var maxY = localPointList[0].Y; foreach (var point in localPointList) { minX = Math.Min(minX, point.X); maxX = Math.Max(maxX, point.X); minY = Math.Min(minY, point.Y); maxY = Math.Max(maxY, point.Y); } var bounds = BoundsHelper.GetViewportBounds(new[] { new System.Windows.Point(minX, minY), new System.Windows.Point(maxX, maxY) }, dataTransform); _syncContext.Send(s => { Viewport2D.SetContentBounds(this, bounds); }, null); }; // Spawn action on throttled update thread _throttledAction.InvokeAction(resizeAction); } return(vertexBufferSizeChanged); }
protected override bool UpdateVertexBufferFromGeometrySource(IEnumerable <TDxPoint> newPoints) { var vertexBufferSizeChanged = base.UpdateVertexBufferFromGeometrySource(newPoints); if (DxHost.LockImage()) { if (vertexBufferSizeChanged) { _indexBuffer?.Dispose(); // Create a 16 bit index buffer _indexBuffer = new IndexBuffer(Device, Utilities.SizeOf <int>() * _vertexBufferAllocated, Usage.WriteOnly, Pool.Default, false); } // Now set the index buffer to match // Lock the buffer, so that we can access the data. DataStream indexStream = _indexBuffer.Lock(0, 0, LockFlags.Discard); indexStream.WriteRange(Enumerable.Range(0, _vertexBufferAllocated).ToArray()); // Unlock the stream again, committing all changes. _indexBuffer.Unlock(); DxHost.UnlockImage(); } return(vertexBufferSizeChanged); }